#include "stm32f0xx_hal.h" #include "adc.h" #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) { __ADC1_CLK_ENABLE(); GPIO_InitTypeDef GPIO_InitStruct; GPIO_InitStruct.Pin = VBATT_SENSE_Pin; GPIO_InitStruct.Mode = GPIO_MODE_ANALOG; GPIO_InitStruct.Pull = GPIO_NOPULL; HAL_GPIO_Init(VBATT_SENSE_GPIO_Port, &GPIO_InitStruct); ADC_ChannelConfTypeDef sConfig; hadc.Instance = ADC1; 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; hadc.Init.EOCSelection = EOC_SINGLE_CONV; hadc.Init.LowPowerAutoWait = DISABLE; hadc.Init.LowPowerAutoPowerOff = DISABLE; hadc.Init.ContinuousConvMode = DISABLE; hadc.Init.DiscontinuousConvMode = DISABLE; hadc.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE; hadc.Init.DMAContinuousRequests = DISABLE; hadc.Init.Overrun = OVR_DATA_PRESERVED; HAL_ADC_Init(&hadc); sConfig.Channel = ADC_CHANNEL_6; sConfig.Rank = ADC_RANK_CHANNEL_NUMBER; 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) { // TODO: Is stopping the clocks enough? Might need to disable periph? __ADC1_CLK_ENABLE(); __DMA1_CLK_ENABLE(); HAL_ADC_Start_DMA(&hadc, adc_buffer, ADC_BUF_LEN); } void adc_stop(void) { HAL_ADC_Stop_DMA(&hadc); __DMA1_CLK_DISABLE(); __ADC1_CLK_DISABLE(); } 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; }