Restructured ADC1_MDx code and extended its support also to MD-9600
This commit is contained in:
parent
6b541a8ba1
commit
e157fc361d
|
|
@ -24,7 +24,7 @@
|
|||
/*
|
||||
* The sample buffer is structured as follows:
|
||||
*
|
||||
* | vbat | vol | rssi | vox |
|
||||
* | vol | vbat | vox | rssi | sw1 | sw2 | rssi2 | htemp |
|
||||
*
|
||||
* NOTE: we are forced to allocate it through a malloc in order to make it be
|
||||
* in the "large" 128kB RAM. This because the linker script maps the .data and
|
||||
|
|
@ -32,6 +32,14 @@
|
|||
*/
|
||||
uint16_t *sampleBuf = NULL;
|
||||
|
||||
#if defined(PLATFORM_MD9600)
|
||||
static const size_t nChannels = 8;
|
||||
#elif defined(PLATFORM_MD3x0)
|
||||
static const size_t nChannels = 4;
|
||||
#else
|
||||
static const size_t nChannels = 2;
|
||||
#endif
|
||||
|
||||
void adc1_init()
|
||||
{
|
||||
RCC->APB2ENR |= RCC_APB2ENR_ADC1EN;
|
||||
|
|
@ -42,16 +50,18 @@ void adc1_init()
|
|||
|
||||
/*
|
||||
* Configure GPIOs to analog input mode:
|
||||
* - PA0: volume potentiometer level
|
||||
* - PA1: battery voltage
|
||||
* - PA3: vox level
|
||||
* - PB0: RSSI level
|
||||
*/
|
||||
gpio_setMode(AIN_VBAT, INPUT_ANALOG);
|
||||
gpio_setMode(AIN_VOLUME, INPUT_ANALOG);
|
||||
#if defined(PLATFORM_MD3x0)
|
||||
gpio_setMode(AIN_MIC, INPUT_ANALOG);
|
||||
gpio_setMode(AIN_RSSI, INPUT_ANALOG);
|
||||
#if defined(PLATFORM_MD3x0) || defined(PLATFORM_MD9600)
|
||||
gpio_setMode(AIN_MIC, INPUT_ANALOG);
|
||||
gpio_setMode(AIN_RSSI, INPUT_ANALOG);
|
||||
#if defined(PLATFORM_MD9600)
|
||||
gpio_setMode(AIN_SW2, INPUT_ANALOG);
|
||||
gpio_setMode(AIN_SW1, INPUT_ANALOG);
|
||||
gpio_setMode(AIN_RSSI2, INPUT_ANALOG);
|
||||
gpio_setMode(AIN_HTEMP, INPUT_ANALOG);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/*
|
||||
|
|
@ -64,7 +74,11 @@ void adc1_init()
|
|||
ADC1->SMPR2 = ADC_SMPR2_SMP0
|
||||
| ADC_SMPR2_SMP1
|
||||
| ADC_SMPR2_SMP3
|
||||
| ADC_SMPR2_SMP8;
|
||||
| ADC_SMPR2_SMP6
|
||||
| ADC_SMPR2_SMP7
|
||||
| ADC_SMPR2_SMP8
|
||||
| ADC_SMPR2_SMP9;
|
||||
ADC1->SMPR1 = ADC_SMPR1_SMP15;
|
||||
|
||||
/*
|
||||
* No overrun interrupt, 12-bit resolution, no analog watchdog, no
|
||||
|
|
@ -78,7 +92,17 @@ void adc1_init()
|
|||
| ADC_CR2_ADON;
|
||||
|
||||
/* Scan sequence config. */
|
||||
#if defined(PLATFORM_MD3x0)
|
||||
#if defined(PLATFORM_MD9600)
|
||||
ADC1->SQR1 = 7 << 20; /* Eight channels to be converted */
|
||||
ADC1->SQR3 |= (0 << 0) /* CH0, volume potentiometer level on PA0 */
|
||||
| (1 << 5) /* CH1, battery voltage on PA1 */
|
||||
| (3 << 10) /* CH3, vox level on PA3 */
|
||||
| (8 << 15) /* CH8, RSSI value on PB0 */
|
||||
| (7 << 20) /* CH7, SW1 value on PA7 */
|
||||
| (6 << 25); /* CH6, SW2 value on PA6 */
|
||||
ADC1->SQR2 |= (9 << 0) /* CH9, RSSI2 value on PB1 */
|
||||
| (15 << 5); /* CH15, HTEMP value on PC5 */
|
||||
#elif defined(PLATFORM_MD3x0)
|
||||
ADC1->SQR1 = 3 << 20; /* Four channels to be converted */
|
||||
ADC1->SQR3 |= (1 << 0) /* CH1, battery voltage on PA1 */
|
||||
| (0 << 5) /* CH0, volume potentiometer level on PA0 */
|
||||
|
|
@ -86,8 +110,8 @@ void adc1_init()
|
|||
| (3 << 15); /* CH3, vox level on PA3 */
|
||||
#else
|
||||
ADC1->SQR1 = 1 << 20; /* Convert two channel */
|
||||
ADC1->SQR3 |= (1 << 0) /* CH1, battery voltage on PA1 */
|
||||
| (0 << 15); /* CH0, volume potentiometer level on PA0 */
|
||||
ADC1->SQR3 |= (0 << 0) /* CH0, volume potentiometer level on PA0 */
|
||||
| (1 << 5); /* CH1, battery voltage on PA1 */
|
||||
#endif
|
||||
|
||||
/* DMA2 Stream 0 configuration:
|
||||
|
|
@ -101,7 +125,7 @@ void adc1_init()
|
|||
*/
|
||||
DMA2_Stream0->PAR = ((uint32_t) &(ADC1->DR));
|
||||
DMA2_Stream0->M0AR = ((uint32_t) sampleBuf);
|
||||
DMA2_Stream0->NDTR = 4;
|
||||
DMA2_Stream0->NDTR = nChannels;
|
||||
DMA2_Stream0->CR = DMA_SxCR_MSIZE_0 /* Memory size: 16 bit */
|
||||
| DMA_SxCR_PSIZE_0 /* Peripheral size: 16 bit */
|
||||
| DMA_SxCR_PL_0 /* Medium priority */
|
||||
|
|
@ -125,7 +149,7 @@ void adc1_terminate()
|
|||
|
||||
float adc1_getMeasurement(uint8_t ch)
|
||||
{
|
||||
if((ch > 3) || (sampleBuf == NULL)) return 0.0f;
|
||||
if((ch > (nChannels-1)) || (sampleBuf == NULL)) return 0.0f;
|
||||
|
||||
float value = ((float) sampleBuf[ch]);
|
||||
return (value * 3300.0f)/4096.0f;
|
||||
|
|
|
|||
|
|
@ -21,13 +21,37 @@
|
|||
#include <stdint.h>
|
||||
|
||||
/**
|
||||
* Driver for ADC1, used to continuously sample the following channels:
|
||||
* - ADC1_CH0 (PA0): output value of the volume potentiometer;
|
||||
* - ADC1_CH1 (PA1): battery voltage through 1:3 resistor divider;
|
||||
* - ADC1_CH3 (PA3): vox level;
|
||||
* - ADC1_CH8 (PB0): RSSI level;
|
||||
* Driver for ADC1, used on all the MDx devices to continuously sample battery
|
||||
* voltage and other values.
|
||||
*
|
||||
* Channel mapping for MDx platforms:
|
||||
*
|
||||
* +--------+----------+---------+
|
||||
* | MD-3x0 | MD-UV3x0 | MD-9600 |
|
||||
* +-----+------+-----------------+--------+----------+---------+
|
||||
* | PA0 | IN0 | volume level | x | x | |
|
||||
* | PA1 | IN1 | supply voltage | x | x | x |
|
||||
* | PA3 | IN3 | mic level (VOX) | x | x | x |
|
||||
* | PA6 | IN6 | mic SW2 line | | | x |
|
||||
* | PA7 | IN7 | mic SW1 line | | | x |
|
||||
* | PB0 | IN8 | RSSI | x | | x |
|
||||
* | PB1 | IN9 | | | | x |
|
||||
* | PC5 | IN15 | heatsink temp. | | | x |
|
||||
* +-----+------+-----------------+--------+----------+---------+
|
||||
*/
|
||||
|
||||
enum adcCh
|
||||
{
|
||||
ADC_VOL_CH = 0,
|
||||
ADC_VBAT_CH = 1,
|
||||
ADC_VOX_CH = 2,
|
||||
ADC_RSSI_CH = 3,
|
||||
ADC_SW1_CH = 4,
|
||||
ADC_SW2_CH = 5,
|
||||
ADC_RSSI2_CH = 6,
|
||||
ADC_HTEMP_CH = 7
|
||||
};
|
||||
|
||||
/**
|
||||
* Initialise and start ADC1 and DMA2 Stream 0.
|
||||
*
|
||||
|
|
@ -47,16 +71,12 @@ void adc1_init();
|
|||
void adc1_terminate();
|
||||
|
||||
/**
|
||||
* Get current measurement of a given channel, mapped as below:
|
||||
* - channel 0: battery voltage
|
||||
* - channel 1: volume level
|
||||
* - channel 2: RSSI level
|
||||
* - channel 3: vox level
|
||||
* Get current measurement of a given channel.
|
||||
*
|
||||
* NOTE: the mapping above DOES NOT correspond to the physical ADC channel
|
||||
* mapping!
|
||||
* NOTE: the mapping provided in enum adcCh DOES NOT correspond to the physical
|
||||
* ADC channel mapping!
|
||||
*
|
||||
* @param ch: channel number, between 0 and 3.
|
||||
* @param ch: channel number.
|
||||
* @return current value of the specified channel in mV.
|
||||
*/
|
||||
float adc1_getMeasurement(uint8_t ch);
|
||||
|
|
|
|||
|
|
@ -290,7 +290,7 @@ float radio_getRssi(const freq_t rxFreq)
|
|||
if(rxFreq < 401035000) offset_index = 0;
|
||||
if(rxFreq > 479995000) offset_index = 8;
|
||||
|
||||
float rssi_mv = adc1_getMeasurement(2);
|
||||
float rssi_mv = adc1_getMeasurement(ADC_RSSI_CH);
|
||||
float rssi_dbm = (rssi_mv - rssi_offset[offset_index]) / rssi_gain;
|
||||
return rssi_dbm;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -118,17 +118,17 @@ float platform_getVbat()
|
|||
* adc1_getMeasurement returns a value in mV. Thus, to have effective
|
||||
* battery voltage multiply by three and divide by 1000
|
||||
*/
|
||||
return adc1_getMeasurement(0)*3.0f/1000.0f;
|
||||
return adc1_getMeasurement(ADC_VBAT_CH)*3.0f/1000.0f;
|
||||
}
|
||||
|
||||
float platform_getMicLevel()
|
||||
{
|
||||
return adc1_getMeasurement(2);
|
||||
return adc1_getMeasurement(ADC_VOX_CH);
|
||||
}
|
||||
|
||||
float platform_getVolumeLevel()
|
||||
{
|
||||
return adc1_getMeasurement(3);
|
||||
return adc1_getMeasurement(ADC_VOL_CH);
|
||||
}
|
||||
|
||||
int8_t platform_getChSelector()
|
||||
|
|
|
|||
|
|
@ -62,7 +62,14 @@
|
|||
#define LCD_CS GPIOD,14
|
||||
|
||||
/* Analog inputs */
|
||||
#define AIN_VOLUME GPIOA,0
|
||||
#define AIN_VBAT GPIOA,1
|
||||
#define AIN_MIC GPIOA,3
|
||||
#define AIN_SW2 GPIOA,6
|
||||
#define AIN_SW1 GPIOA,7
|
||||
#define AIN_RSSI GPIOB,0
|
||||
#define AIN_RSSI2 GPIOB,1
|
||||
#define AIN_HTEMP GPIOC,5
|
||||
|
||||
/* Channel selection rotary encoder */
|
||||
#define CH_SELECTOR_0 GPIOB,10
|
||||
|
|
|
|||
|
|
@ -186,7 +186,7 @@ float platform_getVbat()
|
|||
* adc1_getMeasurement returns a value in mV. Thus, to have effective
|
||||
* battery voltage multiply by three and divide by 1000
|
||||
*/
|
||||
return adc1_getMeasurement(0)*3.0f/1000.0f;
|
||||
return adc1_getMeasurement(ADC_VBAT_CH)*3.0f/1000.0f;
|
||||
}
|
||||
|
||||
float platform_getMicLevel()
|
||||
|
|
@ -196,7 +196,7 @@ float platform_getMicLevel()
|
|||
|
||||
float platform_getVolumeLevel()
|
||||
{
|
||||
return adc1_getMeasurement(1);
|
||||
return adc1_getMeasurement(ADC_VOL_CH);
|
||||
}
|
||||
|
||||
int8_t platform_getChSelector()
|
||||
|
|
|
|||
Loading…
Reference in New Issue