diff --git a/src/adc.c b/src/adc.c --- a/src/adc.c +++ b/src/adc.c @@ -3,6 +3,10 @@ #include "gpio.h" ADC_HandleTypeDef hadc; +DMA_HandleTypeDef hdma_adc; + +#define ADC_BUF_LEN 3 +uint16_t adc_buffer[ADC_BUF_LEN]; // Initialize ADC void adc_init(void) @@ -17,7 +21,7 @@ void adc_init(void) ADC_ChannelConfTypeDef sConfig; hadc.Instance = ADC1; - hadc.Init.ClockPrescaler = ADC_CLOCK_ASYNC; + hadc.Init.ClockPrescaler = ADC_CLOCK_ASYNC; // hopefully stops in sleep hadc.Init.Resolution = ADC_RESOLUTION12b; hadc.Init.DataAlign = ADC_DATAALIGN_RIGHT; hadc.Init.ScanConvMode = ADC_SCAN_DIRECTION_FORWARD; @@ -36,5 +40,79 @@ void adc_init(void) sConfig.SamplingTime = ADC_SAMPLETIME_1CYCLE_5; HAL_ADC_ConfigChannel(&hadc, &sConfig); + sConfig.Channel = ADC_CHANNEL_TEMPSENSOR; + sConfig.Rank = ADC_RANK_CHANNEL_NUMBER; + sConfig.SamplingTime = ADC_SAMPLETIME_1CYCLE_5; + HAL_ADC_ConfigChannel(&hadc, &sConfig); + + + // TODO: AAH might not want to be running this DMA all the time! Meh. + + __DMA1_CLK_ENABLE(); + HAL_NVIC_SetPriority(DMA1_Channel1_IRQn, 0, 0); + HAL_NVIC_EnableIRQ(DMA1_Channel1_IRQn); + + hdma_adc.Instance = DMA1_Channel1; + hdma_adc.Init.Direction = DMA_PERIPH_TO_MEMORY; + hdma_adc.Init.PeriphInc = DMA_PINC_DISABLE; + hdma_adc.Init.MemInc = DMA_MINC_ENABLE; + hdma_adc.Init.PeriphDataAlignment = DMA_PDATAALIGN_HALFWORD; + hdma_adc.Init.MemDataAlignment = DMA_MDATAALIGN_HALFWORD; + hdma_adc.Init.Mode = DMA_CIRCULAR; + hdma_adc.Init.Priority = DMA_PRIORITY_LOW; + HAL_DMA_Init(&hdma_adc); + + __HAL_LINKDMA(&hadc,DMA_Handle,hdma_adc); + + + HAL_ADC_Start_DMA(&hadc, adc_buffer, ADC_BUF_LEN); + + +} + +void adc_start(void) +{ + HAL_ADC_Start_DMA(&hadc, adc_buffer, ADC_BUF_LEN); } + +void adc_stop(void) +{ + HAL_ADC_Stop_DMA(&hadc); +} + + +uint8_t adc_get_vbatt(void) +{ + return 33; //adc_buffer[0] / 62.5; // tenths of volts ish +} + + + +//See RM0091 section 13.9 and appendix A.7.16 +//Temperature sensor raw value at 30 degrees C, VDDA=3.3V +#define TEMP30_CAL_ADDR ((uint16_t*) ((uint32_t) 0x1FFFF7B8)) +//Temperature sensor raw value at 110 degrees C, VDDA=3.3V +#define TEMP110_CAL_ADDR ((uint16_t*) ((uint32_t) 0x1FFFF7C2)) +#define ADC_TEMPERATURE_OFFSET 0 + +int16_t adc_get_dietemp(void) +{ + int32_t tempraw = adc_buffer[1]; + int32_t temperature; + temperature = tempraw - ((int32_t)*TEMP30_CAL_ADDR); + temperature = temperature * (110L - 30L); + temperature = temperature / (*TEMP110_CAL_ADDR - *TEMP30_CAL_ADDR); + temperature = temperature + 30L; + + temperature = temperature + ADC_TEMPERATURE_OFFSET; + + return 14; //temperature; + // TODO: Verify +} + + +ADC_HandleTypeDef* adc_gethandle(void) +{ + return &hadc; +}