From 1e678c3ce873f24003f4d2cf2c11cdaeab0585e4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mario=20H=C3=BCttel?= Date: Mon, 3 Feb 2020 19:40:59 +0100 Subject: [PATCH] Fix bug in clock manager and remove DMA sampling from ADC code. Will be rewritten in a different way --- stm-firmware/adc-meas.c | 79 ++++++--------------- stm-firmware/clock-enable-manager.c | 9 ++- stm-firmware/include/clock-enable-manager.h | 6 +- stm-firmware/include/stm32-gpio-macros.h | 2 +- stm-firmware/main.c | 4 +- 5 files changed, 32 insertions(+), 68 deletions(-) diff --git a/stm-firmware/adc-meas.c b/stm-firmware/adc-meas.c index f52e173..9b50903 100644 --- a/stm-firmware/adc-meas.c +++ b/stm-firmware/adc-meas.c @@ -3,16 +3,16 @@ #include #include #include +#include static float pt1000_offset; static float pt1000_sens_dev; static bool calibration_active; static float filter_alpha; static volatile float pt1000_res_raw_lf; -static volatile bool streaming_active; static volatile bool filter_ready; static volatile enum adc_pt1000_error pt1000_error; -static volatile uint8_t *dma_flag_ptr = NULL; +static volatile uint8_t * volatile dma_flag_ptr = NULL; static uint32_t filter_startup_cnt; #define ADC_TO_RES(adc) ((float)(adc) / 4096.0f * 2500.0f) @@ -20,12 +20,12 @@ static uint32_t filter_startup_cnt; static inline void adc_pt1000_stop_sample_frequency_timer() { TIM2->CR1 &= ~TIM_CR1_CEN; - RCC->APB1ENR &= ~RCC_APB1ENR_TIM2EN; + rcc_manager_disable_clock(&RCC->APB1ENR, BITMASK_TO_BITNO(RCC_APB1ENR_TIM2EN)); } static inline void adc_pt1000_setup_sample_frequency_timer() { - RCC->APB1ENR |= RCC_APB1ENR_TIM2EN; + rcc_manager_enable_clock(&RCC->APB1ENR, BITMASK_TO_BITNO(RCC_APB1ENR_TIM2EN)); /* Divide 42 MHz peripheral clock by 42 */ TIM2->PSC = (42UL-1UL); @@ -45,13 +45,16 @@ static inline void adc_pt1000_disable_adc() { ADC1->CR2 &= ~ADC_CR2_ADON; DMA2_Stream0->CR = 0; - RCC->APB2ENR &= ~RCC_APB2ENR_ADC1EN; + + rcc_manager_disable_clock(&RCC->APB2ENR, BITMASK_TO_BITNO(RCC_APB2ENR_ADC1EN)); + rcc_manager_disable_clock(&RCC->AHB1ENR, BITMASK_TO_BITNO(ADC_PT1000_PORT_RCC_MASK)); } void adc_pt1000_setup_meas() { - RCC->APB2ENR |= RCC_APB2ENR_ADC1EN; - RCC->AHB1ENR |= ADC_PT1000_PORT_RCC_MASK; + rcc_manager_enable_clock(&RCC->APB2ENR, BITMASK_TO_BITNO(RCC_APB2ENR_ADC1EN)); + rcc_manager_enable_clock(&RCC->AHB1ENR, BITMASK_TO_BITNO(ADC_PT1000_PORT_RCC_MASK)); + ADC_PT1000_PORT->MODER |= ANALOG(ADC_PT1000_PIN); /* Set S&H time for PT1000 ADC channel */ @@ -78,7 +81,6 @@ void adc_pt1000_setup_meas() adc_pt1000_set_moving_average_filter_param(ADC_PT1000_FILTER_WEIGHT); adc_pt1000_set_resistance_calibration(0, 0, false); - streaming_active = false; pt1000_res_raw_lf = 0.0f; NVIC_EnableIRQ(ADC_IRQn); @@ -140,55 +142,13 @@ int adc_pt1000_get_current_resistance(float *resistance) goto return_value; } - if (streaming_active) { - ret_val = 1; - goto return_value; - } - return_value: return ret_val; } int adc_pt1000_stream_raw_value_to_memory(uint16_t *adc_array, uint32_t length, volatile uint8_t *flag_to_set) { - static volatile uint8_t alt_flag; - int ret_val = 0; - if (!(ADC1->CR2 & ADC_CR2_ADON)) - return -1; - - if (!adc_array || !length) - return -1000; - - if (flag_to_set) - dma_flag_ptr = flag_to_set; - else - dma_flag_ptr = &alt_flag; - - *dma_flag_ptr = 0; - streaming_active = true; - - ADC1->CR2 &= ~ADC_CR2_ADON; - DMA2_Stream0->CR &= ~DMA_SxCR_EN; - - DMA2_Stream0->M0AR = (uint32_t)adc_array; - DMA2_Stream0->PAR = (uint32_t)&ADC1->DR; - - DMA2_Stream0->CR = DMA_SxCR_PL_1 | DMA_SxCR_MSIZE_0 | DMA_SxCR_PSIZE_0 | DMA_SxCR_MINC | DMA_SxCR_TCIE; - DMA2_Stream0->NDTR = length; - NVIC_EnableIRQ(DMA2_Stream0_IRQn); - - DMA2_Stream0->CR |= DMA_SxCR_EN; - ADC1->CR2 |= ADC_CR2_ADON | ADC_CR2_DMA; - - if (!flag_to_set) { - while(!alt_flag); - - if (alt_flag < 0) - ret_val = -alt_flag; - } - - return ret_val; } void adc_pt1000_convert_raw_value_array_to_resistance(float *resistance_dest, uint16_t *raw_source, uint32_t count) @@ -212,6 +172,11 @@ void adc_pt1000_disable() adc_pt1000_stop_sample_frequency_timer(); filter_ready = false; pt1000_res_raw_lf = 0.0f; + + if (dma_flag_ptr) { + *dma_flag_ptr = -3; + dma_flag_ptr = NULL; + } } static inline __attribute__((optimize("O3"))) void adc_pt1000_filter(uint16_t adc_value) @@ -237,9 +202,9 @@ void ADC_IRQHandler(void) pt1000_error |= ADC_PT1000_OVERFLOW; /* Disable ADC in case of overrrun*/ adc_pt1000_disable(); - if (streaming_active) { - streaming_active = false; + if (dma_flag_ptr) { *dma_flag_ptr = -1; + dma_flag_ptr = NULL; } } @@ -256,16 +221,14 @@ void DMA2_Stream0_IRQHandler() lisr = DMA2->LISR; DMA2->LIFCR = lisr; - if (lisr & DMA_LISR_TCIF0) { + if (lisr & DMA_LISR_TCIF0 && dma_flag_ptr) { *dma_flag_ptr = 1; - ADC1->CR2 &= ~ADC_CR2_DMA; - streaming_active = false; + dma_flag_ptr = NULL; } - if (lisr & DMA_LISR_TEIF0) { + if (lisr & DMA_LISR_TEIF0 && dma_flag_ptr) { *dma_flag_ptr = -2; - ADC1->CR2 &= ~ADC_CR2_DMA; - streaming_active = false; + dma_flag_ptr = NULL; } } diff --git a/stm-firmware/clock-enable-manager.c b/stm-firmware/clock-enable-manager.c index 41dab16..a06e9fb 100644 --- a/stm-firmware/clock-enable-manager.c +++ b/stm-firmware/clock-enable-manager.c @@ -4,7 +4,7 @@ #define COUNT_OF(x) ((sizeof(x)/sizeof(0[x])) / ((size_t)(!(sizeof(x) % sizeof(0[x]))))) struct rcc_enable_count { - uint32_t *rcc_reg_addr; + volatile uint32_t *rcc_reg_addr; uint32_t *enable_bit_cnt; uint8_t rcc_enable_bit_pos; }; @@ -18,7 +18,7 @@ static struct rcc_enable_count enable_count_list[RCC_ENABLE_MANAGER_COUNT] = {0} #endif #if RCC_ENABLE_MANAGER_STATIC -static struct rcc_enable_count *search_enable_entry_in_list(uint32_t *reg_addr, uint8_t bit_pos) +static struct rcc_enable_count *search_enable_entry_in_list(volatile uint32_t *reg_addr, uint8_t bit_pos) { int i; struct rcc_enable_count *ret_element = NULL; @@ -52,7 +52,6 @@ static struct rcc_enable_count *enable_entry_list_get_free_entry() /* Clear the count value to be safe */ ret_ptr->enable_bit_cnt = 0; - break; } } @@ -71,7 +70,7 @@ static void enable_entry_list_remove_entry(struct rcc_enable_count *entry) } #endif -int rcc_manager_enable_clock(uint32_t *rcc_enable_register, uint8_t bit_no) +int rcc_manager_enable_clock(volatile uint32_t *rcc_enable_register, uint8_t bit_no) { int ret_val = 0; struct rcc_enable_count *entry; @@ -108,7 +107,7 @@ ret_error_code: return ret_val; } -int rcc_manager_disable_clock(uint32_t *rcc_enable_register, uint8_t bit_no) +int rcc_manager_disable_clock(volatile uint32_t *rcc_enable_register, uint8_t bit_no) { int ret_val = -1; struct rcc_enable_count *entry; diff --git a/stm-firmware/include/clock-enable-manager.h b/stm-firmware/include/clock-enable-manager.h index 20f88fa..3b24d60 100644 --- a/stm-firmware/include/clock-enable-manager.h +++ b/stm-firmware/include/clock-enable-manager.h @@ -10,7 +10,7 @@ #define RCC_ENABLE_MANAGER_STATIC 1U #if RCC_ENABLE_MANAGER_STATIC -#define RCC_ENABLE_MANAGER_COUNT 20U +#define RCC_ENABLE_MANAGER_COUNT 30U #else #error "RCC Enable Manager not yet implemented with dynamic memory" #endif @@ -28,7 +28,7 @@ * * @return 0 if successful */ -int rcc_manager_enable_clock(uint32_t *rcc_enable_register, uint8_t bit_no); +int rcc_manager_enable_clock(volatile uint32_t *rcc_enable_register, uint8_t bit_no); /** * @brief Disable clock for peripheral and decrement the enaböe-counter of that bit. @@ -42,7 +42,7 @@ int rcc_manager_enable_clock(uint32_t *rcc_enable_register, uint8_t bit_no); * @param bit_no Bit number (0 to 31) of the bit to disable * @return 0 if successful */ -int rcc_manager_disable_clock(uint32_t *rcc_enable_register, uint8_t bit_no); +int rcc_manager_disable_clock(volatile uint32_t *rcc_enable_register, uint8_t bit_no); #endif /* __CLOCK_ENABLE_MANAGER_H__ */ diff --git a/stm-firmware/include/stm32-gpio-macros.h b/stm-firmware/include/stm32-gpio-macros.h index 5829507..ee35600 100644 --- a/stm-firmware/include/stm32-gpio-macros.h +++ b/stm-firmware/include/stm32-gpio-macros.h @@ -8,7 +8,7 @@ #define SETAF(PORT,PIN,AF) PORT->AFR[(PIN < 8 ? 0 : 1)] |= AF << ((PIN < 8 ? PIN : (PIN - 8)) * 4) #define ANALOG(pin) (0x03 << (pin * 2)) -#define BIOTMASK_TO_BITNO(x) (x&0x1?0:x&0x2?1:x&0x4?2:x&0x8?3: \ +#define BITMASK_TO_BITNO(x) (x&0x1?0:x&0x2?1:x&0x4?2:x&0x8?3: \ x&0x10?4:x&0x20?5:x&0x40?6:x&0x80?7: \ x&0x100?8:x&0x200?9:x&0x400?10:x&0x800?11: \ x&0x1000?12:x&0x2000?13:x&0x4000?14:x&0x8000?15: \ diff --git a/stm-firmware/main.c b/stm-firmware/main.c index dfe9fa6..42751a2 100644 --- a/stm-firmware/main.c +++ b/stm-firmware/main.c @@ -12,6 +12,7 @@ #include #include #include +#include static void setup_nvic_priorities() { @@ -27,7 +28,8 @@ static float pt1000_value; static volatile int pt1000_value_status; int main() { - RCC->AHB1ENR |= RCC_AHB1ENR_GPIOBEN; + rcc_manager_enable_clock(&RCC->AHB1ENR, BITMASK_TO_BITNO(RCC_AHB1ENR_GPIOBEN)); + __DSB(); GPIOB->MODER = OUTPUT(2) | OUTPUT(3); GPIOB->ODR |= (1<<2);