diff --git a/platform/drivers/ADC/ADC1_MDx.c b/platform/drivers/ADC/ADC1_MDx.c index edf062f3..1a62b9fa 100644 --- a/platform/drivers/ADC/ADC1_MDx.c +++ b/platform/drivers/ADC/ADC1_MDx.c @@ -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; diff --git a/platform/drivers/ADC/ADC1_MDx.h b/platform/drivers/ADC/ADC1_MDx.h index a4a49629..728354b6 100644 --- a/platform/drivers/ADC/ADC1_MDx.h +++ b/platform/drivers/ADC/ADC1_MDx.h @@ -21,13 +21,37 @@ #include /** - * 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); diff --git a/platform/drivers/baseband/radio_MD3x0.c b/platform/drivers/baseband/radio_MD3x0.c index 0b02d92b..37d6fee4 100644 --- a/platform/drivers/baseband/radio_MD3x0.c +++ b/platform/drivers/baseband/radio_MD3x0.c @@ -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; } diff --git a/platform/targets/MD-3x0/platform.c b/platform/targets/MD-3x0/platform.c index bb52ef7b..ac21bdb2 100644 --- a/platform/targets/MD-3x0/platform.c +++ b/platform/targets/MD-3x0/platform.c @@ -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() diff --git a/platform/targets/MD-9600/hwconfig.h b/platform/targets/MD-9600/hwconfig.h index b0565abe..e5b76d5b 100644 --- a/platform/targets/MD-9600/hwconfig.h +++ b/platform/targets/MD-9600/hwconfig.h @@ -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 diff --git a/platform/targets/MD-UV3x0/platform.c b/platform/targets/MD-UV3x0/platform.c index 7d7eb1b4..eff37d41 100644 --- a/platform/targets/MD-UV3x0/platform.c +++ b/platform/targets/MD-UV3x0/platform.c @@ -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()