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 <stm32-gpio-macros.h>
#include <stdlib.h>
#include <clock-enable-manager.h>
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;
}
}

View File

@ -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;

View File

@ -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__ */

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 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: \

View File

@ -12,6 +12,7 @@
#include <stdlib.h>
#include <string.h>
#include <adc-meas.h>
#include <clock-enable-manager.h>
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);