diff --git a/Project/applications/smartcities/adc.c b/Project/applications/smartcities/adc.c new file mode 100644 index 0000000..fb42fbc --- /dev/null +++ b/Project/applications/smartcities/adc.c @@ -0,0 +1,112 @@ +#include "adc.h" + +#define DBG(fmt,...) if(1){printf("[ADC] "fmt"\r\n", ##__VA_ARGS__);}else{({});} + + +#define ADC_MIN_VALUE (0) +#define ADC_MAX_VALUE (0xfff) /* 12-bit adc */ +#define ADC_VREF_PLUS (3300) /* Vref+ is connected with Vdda (3.3v) */ +#define ADC_VREF_MINUS (0) /* Vref- is connected with Vssa (0v) */ + +#define ADCbatt ADC1 +#define ADCbatt_RCC RCC_APB2Periph_ADC1 /* */ +#define ADCbatt_DIVIDER RCC_PCLK2_Div4 /* Can be 2/4/6/8. PCLK2 runs at 32Mhz, and max ADC clock is 14Mhz */ +#define ADCbatt_CHANNEL ADC_Channel_12 /* 0/17 */ +#define ADCbatt_SAMPLETIME ADC_SampleTime_239Cycles5 +#define ADCbatt_GPIO_PIN GPIO_Pin_2 +#define ADCbatt_GPIO_PORT GPIOC +#define ADCbatt_GPIO_RCC RCC_APB2Periph_GPIOC +#define ADCbatt_GPIO_STR "PC2" + +#define ADCsound ADC1 +#define ADCsound_RCC RCC_APB2Periph_ADC1 /* */ +#define ADCsound_DIVIDER RCC_PCLK2_Div4 /* Can be 2/4/6/8. PCLK2 runs at 32Mhz, and max ADC clock is 14Mhz */ +#define ADCsound_CHANNEL ADC_Channel_12 /* 0/17 */ +#define ADCsound_SAMPLETIME ADC_SampleTime_239Cycles5 +#define ADCsound_GPIO_PIN GPIO_Pin_2 +#define ADCsound_GPIO_PORT GPIOC +#define ADCsound_GPIO_RCC RCC_APB2Periph_GPIOC +#define ADCsound_GPIO_STR "PC2" + +void adc_init() +{ + adc_peripheralInit(); +} + +uint32_t adc_process() +{ + uint16_t adcRegisterValue; + uint32_t analogValue; + + adcRegisterValue = adc_read(); + + /* + * Calculate the register value to volts + * 1. adcRegisterValue Range is [ADC_MIN_VALUE, ADC_MAX_VALUE] + * 2. analogValue Range is [ADC_VREF_MINUS, ADC_VREF_PLUS] + */ + analogValue = ADC_VREF_MINUS + (((adcRegisterValue - ADC_MIN_VALUE)*(ADC_VREF_PLUS - ADC_VREF_MINUS))/(ADC_MAX_VALUE - ADC_MIN_VALUE)); + DBG("Register value is %4u [%4u milliVolts are currently given to gpio %s]",adcRegisterValue, analogValue, ADCbatt_GPIO_STR); + return analogValue; +} + +void adc_peripheralInit() +{ + GPIO_InitTypeDef GPIO_InitStructure; + ADC_InitTypeDef ADC_InitStructure; + RCC_APB2PeriphClockCmd(ADCbatt_GPIO_RCC, ENABLE); + GPIO_InitStructure.GPIO_Pin = ADCbatt_GPIO_PIN; + GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; + GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; + GPIO_Init(ADCbatt_GPIO_PORT, &GPIO_InitStructure); + + + /* Max ADC clk is 14mhz and because PCLK2 runs @32Mhz */ + RCC_ADCCLKConfig(ADCbatt_DIVIDER); + /* Enable ADCbatt clock so that we can talk to it */ + RCC_APB2PeriphClockCmd(ADCbatt_RCC, ENABLE); + /* Put everything back to power-on defaults */ + ADC_DeInit(ADCbatt); + + + /* ADC1 and ADC2 operate independently */ + ADC_InitStructure.ADC_Mode = ADC_Mode_Independent; + /* Disable the scan conversion so we do one at a time */ + ADC_InitStructure.ADC_ScanConvMode = DISABLE; + /* Don't do contimuous conversions - do them on demand */ + ADC_InitStructure.ADC_ContinuousConvMode = DISABLE; + /* Start conversin by software, not an external trigger */ + ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None; + /* Conversions are 12 bit - put them in the lower 12 bits of the result */ + ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right; + /* Say how many channels would be used by the sequencer */ + ADC_InitStructure.ADC_NbrOfChannel = 1; + + /* Now do the setup */ + ADC_Init(ADCbatt, &ADC_InitStructure); + /* Enable ADCbatt */ + ADC_Cmd(ADCbatt, ENABLE); + + /* Enable ADCbatt reset calibaration register */ + ADC_ResetCalibration(ADCbatt); + /* Check the end of ADCbatt reset calibration register */ + while(ADC_GetResetCalibrationStatus(ADCbatt)); + /* Start ADCbatt calibaration */ + ADC_StartCalibration(ADCbatt); + /* Check the end of ADC1 calibration */ + while(ADC_GetCalibrationStatus(ADCbatt)); +} + +uint16_t adc_read() +{ + ADC_RegularChannelConfig(ADCbatt, ADCbatt_CHANNEL, 1, ADCbatt_SAMPLETIME); + /* Start the conversion */ + ADC_SoftwareStartConvCmd(ADCbatt, ENABLE); + /* Wait until conversion completion */ + while(ADC_GetFlagStatus(ADCbatt, ADC_FLAG_EOC) == RESET); + /* Get the conversion value */ + return ADC_GetConversionValue(ADCbatt); +} + + + diff --git a/Project/applications/smartcities/adc.h b/Project/applications/smartcities/adc.h new file mode 100644 index 0000000..aa31d46 --- /dev/null +++ b/Project/applications/smartcities/adc.h @@ -0,0 +1,15 @@ +#ifndef ADC_H +#define ADC_H + +#include "libwismart.h" +#include "ch.h" + +#include "stm32f10x_gpio.h" +#include "stm32f10x_adc.h" + +void adc_init(void); +uint32_t adc_process(void); +uint16_t adc_read(void); +void adc_peripheralInit(void); + +#endif \ No newline at end of file