Fix bug in clock manager and remove DMA sampling from ADC code. Will be rewritten in a different way

This commit is contained in:
Mario Hüttel 2020-02-03 19:40:59 +01:00
parent 5f9bc29701
commit 1e678c3ce8
5 changed files with 32 additions and 68 deletions

View File

@ -3,16 +3,16 @@
#include <core_cm4.h> #include <core_cm4.h>
#include <stm32-gpio-macros.h> #include <stm32-gpio-macros.h>
#include <stdlib.h> #include <stdlib.h>
#include <clock-enable-manager.h>
static float pt1000_offset; static float pt1000_offset;
static float pt1000_sens_dev; static float pt1000_sens_dev;
static bool calibration_active; static bool calibration_active;
static float filter_alpha; static float filter_alpha;
static volatile float pt1000_res_raw_lf; static volatile float pt1000_res_raw_lf;
static volatile bool streaming_active;
static volatile bool filter_ready; static volatile bool filter_ready;
static volatile enum adc_pt1000_error pt1000_error; 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; static uint32_t filter_startup_cnt;
#define ADC_TO_RES(adc) ((float)(adc) / 4096.0f * 2500.0f) #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() static inline void adc_pt1000_stop_sample_frequency_timer()
{ {
TIM2->CR1 &= ~TIM_CR1_CEN; 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() 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 */ /* Divide 42 MHz peripheral clock by 42 */
TIM2->PSC = (42UL-1UL); TIM2->PSC = (42UL-1UL);
@ -45,13 +45,16 @@ static inline void adc_pt1000_disable_adc()
{ {
ADC1->CR2 &= ~ADC_CR2_ADON; ADC1->CR2 &= ~ADC_CR2_ADON;
DMA2_Stream0->CR = 0; 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() void adc_pt1000_setup_meas()
{ {
RCC->APB2ENR |= RCC_APB2ENR_ADC1EN; rcc_manager_enable_clock(&RCC->APB2ENR, BITMASK_TO_BITNO(RCC_APB2ENR_ADC1EN));
RCC->AHB1ENR |= ADC_PT1000_PORT_RCC_MASK; rcc_manager_enable_clock(&RCC->AHB1ENR, BITMASK_TO_BITNO(ADC_PT1000_PORT_RCC_MASK));
ADC_PT1000_PORT->MODER |= ANALOG(ADC_PT1000_PIN); ADC_PT1000_PORT->MODER |= ANALOG(ADC_PT1000_PIN);
/* Set S&H time for PT1000 ADC channel */ /* 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_moving_average_filter_param(ADC_PT1000_FILTER_WEIGHT);
adc_pt1000_set_resistance_calibration(0, 0, false); adc_pt1000_set_resistance_calibration(0, 0, false);
streaming_active = false;
pt1000_res_raw_lf = 0.0f; pt1000_res_raw_lf = 0.0f;
NVIC_EnableIRQ(ADC_IRQn); NVIC_EnableIRQ(ADC_IRQn);
@ -140,55 +142,13 @@ int adc_pt1000_get_current_resistance(float *resistance)
goto return_value; goto return_value;
} }
if (streaming_active) {
ret_val = 1;
goto return_value;
}
return_value: return_value:
return ret_val; return ret_val;
} }
int adc_pt1000_stream_raw_value_to_memory(uint16_t *adc_array, uint32_t length, volatile uint8_t *flag_to_set) 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) 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(); adc_pt1000_stop_sample_frequency_timer();
filter_ready = false; filter_ready = false;
pt1000_res_raw_lf = 0.0f; 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) 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; pt1000_error |= ADC_PT1000_OVERFLOW;
/* Disable ADC in case of overrrun*/ /* Disable ADC in case of overrrun*/
adc_pt1000_disable(); adc_pt1000_disable();
if (streaming_active) { if (dma_flag_ptr) {
streaming_active = false;
*dma_flag_ptr = -1; *dma_flag_ptr = -1;
dma_flag_ptr = NULL;
} }
} }
@ -256,16 +221,14 @@ void DMA2_Stream0_IRQHandler()
lisr = DMA2->LISR; lisr = DMA2->LISR;
DMA2->LIFCR = lisr; DMA2->LIFCR = lisr;
if (lisr & DMA_LISR_TCIF0) { if (lisr & DMA_LISR_TCIF0 && dma_flag_ptr) {
*dma_flag_ptr = 1; *dma_flag_ptr = 1;
ADC1->CR2 &= ~ADC_CR2_DMA; dma_flag_ptr = NULL;
streaming_active = false;
} }
if (lisr & DMA_LISR_TEIF0) { if (lisr & DMA_LISR_TEIF0 && dma_flag_ptr) {
*dma_flag_ptr = -2; *dma_flag_ptr = -2;
ADC1->CR2 &= ~ADC_CR2_DMA; dma_flag_ptr = NULL;
streaming_active = false;
} }
} }

View File

@ -4,7 +4,7 @@
#define COUNT_OF(x) ((sizeof(x)/sizeof(0[x])) / ((size_t)(!(sizeof(x) % sizeof(0[x]))))) #define COUNT_OF(x) ((sizeof(x)/sizeof(0[x])) / ((size_t)(!(sizeof(x) % sizeof(0[x])))))
struct rcc_enable_count { struct rcc_enable_count {
uint32_t *rcc_reg_addr; volatile uint32_t *rcc_reg_addr;
uint32_t *enable_bit_cnt; uint32_t *enable_bit_cnt;
uint8_t rcc_enable_bit_pos; uint8_t rcc_enable_bit_pos;
}; };
@ -18,7 +18,7 @@ static struct rcc_enable_count enable_count_list[RCC_ENABLE_MANAGER_COUNT] = {0}
#endif #endif
#if RCC_ENABLE_MANAGER_STATIC #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; int i;
struct rcc_enable_count *ret_element = NULL; 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 */ /* Clear the count value to be safe */
ret_ptr->enable_bit_cnt = 0; ret_ptr->enable_bit_cnt = 0;
break; break;
} }
} }
@ -71,7 +70,7 @@ static void enable_entry_list_remove_entry(struct rcc_enable_count *entry)
} }
#endif #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; int ret_val = 0;
struct rcc_enable_count *entry; struct rcc_enable_count *entry;
@ -108,7 +107,7 @@ ret_error_code:
return ret_val; 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; int ret_val = -1;
struct rcc_enable_count *entry; struct rcc_enable_count *entry;

View File

@ -10,7 +10,7 @@
#define RCC_ENABLE_MANAGER_STATIC 1U #define RCC_ENABLE_MANAGER_STATIC 1U
#if RCC_ENABLE_MANAGER_STATIC #if RCC_ENABLE_MANAGER_STATIC
#define RCC_ENABLE_MANAGER_COUNT 20U #define RCC_ENABLE_MANAGER_COUNT 30U
#else #else
#error "RCC Enable Manager not yet implemented with dynamic memory" #error "RCC Enable Manager not yet implemented with dynamic memory"
#endif #endif
@ -28,7 +28,7 @@
* *
* @return 0 if successful * @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. * @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 * @param bit_no Bit number (0 to 31) of the bit to disable
* @return 0 if successful * @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__ */ #endif /* __CLOCK_ENABLE_MANAGER_H__ */

View File

@ -8,7 +8,7 @@
#define SETAF(PORT,PIN,AF) PORT->AFR[(PIN < 8 ? 0 : 1)] |= AF << ((PIN < 8 ? PIN : (PIN - 8)) * 4) #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 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&0x10?4:x&0x20?5:x&0x40?6:x&0x80?7: \
x&0x100?8:x&0x200?9:x&0x400?10:x&0x800?11: \ x&0x100?8:x&0x200?9:x&0x400?10:x&0x800?11: \
x&0x1000?12:x&0x2000?13:x&0x4000?14:x&0x8000?15: \ x&0x1000?12:x&0x2000?13:x&0x4000?14:x&0x8000?15: \

View File

@ -12,6 +12,7 @@
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <adc-meas.h> #include <adc-meas.h>
#include <clock-enable-manager.h>
static void setup_nvic_priorities() static void setup_nvic_priorities()
{ {
@ -27,7 +28,8 @@ static float pt1000_value;
static volatile int pt1000_value_status; static volatile int pt1000_value_status;
int main() { int main() {
RCC->AHB1ENR |= RCC_AHB1ENR_GPIOBEN; rcc_manager_enable_clock(&RCC->AHB1ENR, BITMASK_TO_BITNO(RCC_AHB1ENR_GPIOBEN));
__DSB(); __DSB();
GPIOB->MODER = OUTPUT(2) | OUTPUT(3); GPIOB->MODER = OUTPUT(2) | OUTPUT(3);
GPIOB->ODR |= (1<<2); GPIOB->ODR |= (1<<2);