/* ########################################################################################################################################################## */ /* # Includes #################################################################################################################################### Includes # */ /* ########################################################################################################################################################## */ #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wpadded" #include #pragma GCC diagnostic pop #include #include "adc.h" #include "dma.h" #include "gpio.h" /* ########################################################################################################################################################## */ /* # Global variables #################################################################################################################### Global variables # */ /* ########################################################################################################################################################## */ /* ########################################################################################################################################################## */ /* # Private define ######################################################################################################################## Private define # */ /* ########################################################################################################################################################## */ #define REGULAR_GROUP_COUNT 3 /* ########################################################################################################################################################## */ /* # Private macro ########################################################################################################################## Private macro # */ /* ########################################################################################################################################################## */ #define SQ( value, reg, num) (( value << ADC_SQR ## reg ## _SQ ## num ## _Pos) & ADC_SQR ## reg ## _SQ ## num ## _Msk) #define SMP(value, reg, num) (((uint32) value << ADC_SMPR ## reg ## _SMP ## num ## _Pos) & ADC_SMPR ## reg ## _SMP ## num ## _Msk) #define L(value) ((value << ADC_SQR1_L_Pos) & ADC_SQR1_L_Msk) /* ########################################################################################################################################################## */ /* # Private typedef ###################################################################################################################### Private typedef # */ /* ########################################################################################################################################################## */ enum { ADC_CR2_EXTSEL_T1_CC1 = 0, ADC_CR2_EXTSEL_T1_CC2 = 1, ADC_CR2_EXTSEL_T1_CC3 = 2, ADC_CR2_EXTSEL_T2_CC2 = 3, ADC_CR2_EXTSEL_T3_TRGO = 4, ADC_CR2_EXTSEL_T4_CC4 = 5, ADC_CR2_EXTSEL_EXTI_L11 = 6, ADC_CR2_EXTSEL_SWSTART = 7 }; enum ADC_SMPR_SMP_ENUM { ADC_SMPR_SMP_1_5 = 0, ADC_SMPR_SMP_7_5 = 1, ADC_SMPR_SMP_13_5 = 2, ADC_SMPR_SMP_28_5 = 3, ADC_SMPR_SMP_41_5 = 4, ADC_SMPR_SMP_55_5 = 5, ADC_SMPR_SMP_71_5 = 6, ADC_SMPR_SMP_239_5 = 7 }; typedef enum ADC_SMPR_SMP_ENUM ADC_SMPR_SMP; enum { RCC_CFGR_ADCPRE_2 = 0, RCC_CFGR_ADCPRE_4 = 1, RCC_CFGR_ADCPRE_6 = 2, RCC_CFGR_ADCPRE_8 = 3 }; /* ########################################################################################################################################################## */ /* # Private functions prototypes ############################################################################################ Private functions prototypes # */ /* ########################################################################################################################################################## */ static inline void setSQR(ADC_TypeDef *adc, uint8_fast l, uint8_fast sq1, uint8_fast sq2, uint8_fast sq3, uint8_fast sq4, uint8_fast sq5, uint8_fast sq6, uint8_fast sq7, uint8_fast sq8, uint8_fast sq9, uint8_fast sq10, uint8_fast sq11, uint8_fast sq12, uint8_fast sq13, uint8_fast sq14, uint8_fast sq15, uint8_fast sq16); static inline void setSMPR(ADC_TypeDef *adc, ADC_SMPR_SMP smp0, ADC_SMPR_SMP smp1, ADC_SMPR_SMP smp2, ADC_SMPR_SMP smp3, ADC_SMPR_SMP smp4, ADC_SMPR_SMP smp5, ADC_SMPR_SMP smp6, ADC_SMPR_SMP smp7, ADC_SMPR_SMP smp8, ADC_SMPR_SMP smp9, ADC_SMPR_SMP smp10, ADC_SMPR_SMP smp11, ADC_SMPR_SMP smp12, ADC_SMPR_SMP smp13, ADC_SMPR_SMP smp14, ADC_SMPR_SMP smp15); /* ########################################################################################################################################################## */ /* # ISR, Hook and Callback functions prototypes ############################################################## ISR, Hook and Callback functions prototypes # */ /* ########################################################################################################################################################## */ void ADC1_2_IRQHandler(void); /* ########################################################################################################################################################## */ /* # Private variables ################################################################################################################## Private variables # */ /* ########################################################################################################################################################## */ static volatile uint16 regularGroup1[REGULAR_GROUP_COUNT] = { 0 }; //static volatile uint8_fast regularGroup1Index = 0; /* ########################################################################################################################################################## */ /* # Private functions ################################################################################################################## Private functions # */ /* ########################################################################################################################################################## */ static inline void setSQR(ADC_TypeDef *adc, uint8_fast l, uint8_fast sq1, uint8_fast sq2, uint8_fast sq3, uint8_fast sq4, uint8_fast sq5, uint8_fast sq6, uint8_fast sq7, uint8_fast sq8, uint8_fast sq9, uint8_fast sq10, uint8_fast sq11, uint8_fast sq12, uint8_fast sq13, uint8_fast sq14, uint8_fast sq15, uint8_fast sq16) { adc->SQR3 = SQ(sq6, 3, 6) | SQ(sq5, 3, 5) | SQ(sq4, 3, 4) | SQ(sq3, 3, 3) | SQ(sq2, 3, 2) | SQ(sq1, 3, 1); adc->SQR2 = SQ(sq12, 2, 12) | SQ(sq11, 2, 11) | SQ(sq10, 2, 10) | SQ(sq9, 2, 9) | SQ(sq8, 2, 8) | SQ(sq7, 2, 7); adc->SQR1 = L(l) | SQ(sq16, 1, 16) | SQ(sq15, 1, 15) | SQ(sq14, 1, 14) | SQ(sq13, 1, 13); } static inline void setSMPR(ADC_TypeDef *adc, ADC_SMPR_SMP smp0, ADC_SMPR_SMP smp1, ADC_SMPR_SMP smp2, ADC_SMPR_SMP smp3, ADC_SMPR_SMP smp4, ADC_SMPR_SMP smp5, ADC_SMPR_SMP smp6, ADC_SMPR_SMP smp7, ADC_SMPR_SMP smp8, ADC_SMPR_SMP smp9, ADC_SMPR_SMP smp10, ADC_SMPR_SMP smp11, ADC_SMPR_SMP smp12, ADC_SMPR_SMP smp13, ADC_SMPR_SMP smp14, ADC_SMPR_SMP smp15) { adc->SMPR2 = SMP(smp9, 2, 9) | SMP(smp8, 2, 8) | SMP(smp7, 2, 7) | SMP(smp6, 2, 6) | SMP(smp5, 2, 5) | SMP(smp4, 2, 4) | SMP(smp3, 2, 3) | SMP(smp2, 2, 2) | SMP(smp1, 2, 1) | SMP(smp0, 2, 0); adc->SMPR1 = SMP(smp15, 1, 15) | SMP(smp14, 1, 14) | SMP(smp13, 1, 13) | SMP(smp12, 1, 12) | SMP(smp11, 1, 11) | SMP(smp10, 1, 10); } /* ########################################################################################################################################################## */ /* # Main, ISR, Hook and Callback functions ######################################################################## Main, ISR, Hook and Callback functions # */ /* ########################################################################################################################################################## */ void ADC1_2_IRQHandler(void) { /* if (READ_BIT(ADC1->SR, ADC_SR_EOC)) { CLEAR_BIT(ADC1->SR, ADC_SR_EOC); } if (READ_BIT(ADC1->SR, ADC_SR_JEOC)) { CLEAR_BIT(ADC1->SR, ADC_SR_JEOC); } if (READ_BIT(ADC1->SR, ADC_SR_AWD)) { CLEAR_BIT(ADC1->SR, ADC_SR_AWD); } if (READ_BIT(ADC2->SR, ADC_SR_EOC)) { CLEAR_BIT(ADC2->SR, ADC_SR_EOC); } if (READ_BIT(ADC2->SR, ADC_SR_JEOC)) { CLEAR_BIT(ADC2->SR, ADC_SR_JEOC); } if (READ_BIT(ADC2->SR, ADC_SR_AWD)) { CLEAR_BIT(ADC2->SR, ADC_SR_AWD); } */ } /* ########################################################################################################################################################## */ /* # Public functions #################################################################################################################### Public functions # */ /* ########################################################################################################################################################## */ void STM32F1_ADC_init(void) { STM32F1_GPIO_configInput(GPIOA, 0, STM32F1_ANALOG); STM32F1_GPIO_configInput(GPIOA, 1, STM32F1_ANALOG); STM32F1_GPIO_configInput(GPIOA, 2, STM32F1_ANALOG); // Divide APB2 clock frequency by 6: 72 MHz / 6 = 12 MHz MODIFY_REG(RCC->CFGR, RCC_CFGR_ADCPRE_Msk, RCC_CFGR_ADCPRE_6 << RCC_CFGR_ADCPRE_Pos); // Enable clock for ADC SET_BIT(RCC->APB2ENR, RCC_APB2ENR_ADC1EN); // Enable clock for GPIO A SET_BIT(RCC->APB2ENR, RCC_APB2ENR_IOPAEN); // Switch the ADC on SET_BIT(ADC1->CR2, ADC_CR2_ADON); // Wait 2 ADC-Clock cycles before starting calibration: (72MHz / 12MHz) * 2 = 12 => 12 Nops __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); // Start calibration SET_BIT(ADC1->CR2, ADC_CR2_CAL); // Wait until the calibration is finished while (READ_BIT(ADC1->CR2, ADC_CR2_CAL)) ; setSQR(ADC1, REGULAR_GROUP_COUNT - 1, 0, 1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); setSMPR(ADC1, ADC_SMPR_SMP_239_5, ADC_SMPR_SMP_239_5, ADC_SMPR_SMP_239_5, ADC_SMPR_SMP_239_5, ADC_SMPR_SMP_239_5, ADC_SMPR_SMP_239_5, ADC_SMPR_SMP_239_5, ADC_SMPR_SMP_239_5, ADC_SMPR_SMP_239_5, ADC_SMPR_SMP_239_5, ADC_SMPR_SMP_239_5, ADC_SMPR_SMP_239_5, ADC_SMPR_SMP_239_5, ADC_SMPR_SMP_239_5, ADC_SMPR_SMP_239_5, ADC_SMPR_SMP_239_5); SET_BIT(ADC1->CR1, ADC_CR1_SCAN); SET_BIT(ADC1->CR2, ADC_CR2_CONT); SET_BIT(ADC1->CR2,ADC_CR2_DMA); // Select software start trigger //MODIFY_REG(ADC1->CR2, ADC_CR2_EXTSEL, ADC_CR2_EXTSEL_SWSTART << ADC_CR2_EXTSEL_Pos); // Enable trigger //SET_BIT(ADC1->CR2, ADC_CR2_EXTTRIG); // Enable Interrupt //SET_BIT(ADC1->CR1, ADC_CR1_EOCIE); //NVIC_SetPriority(ADC1_2_IRQn, NVIC_EncodePriority(NVIC_GetPriorityGrouping(), 5, 0)); //NVIC_EnableIRQ(ADC1_2_IRQn); STM32F1_DMA1_configChannel1ForADC1(REGULAR_GROUP_COUNT, (uint16*) regularGroup1); STM32F1_DMA1_startChannel1(); // Start conversion //SET_BIT(ADC1->CR2, ADC_CR2_SWSTART); SET_BIT(ADC1->CR2, ADC_CR2_ADON); } uint16 STM32F1_ADC_getRegularGroupe1(uint8_fast channel) { if (channel >= REGULAR_GROUP_COUNT) { return 0xFFFF; } return regularGroup1[channel]; } /* ########################################################################################################################################################## */ /* EOF */