From daf9408171ad10f2d859f12b57d2dc818566f86c Mon Sep 17 00:00:00 2001 From: Gautier Hattenberger Date: Fri, 24 Jan 2014 12:49:58 +0100 Subject: [PATCH] [stm32] update libopencm3 and hence also adc injected channel order --- sw/airborne/arch/stm32/mcu_periph/adc_arch.c | 123 +++++++++++-------- sw/airborne/arch/stm32/mcu_periph/adc_arch.h | 18 ++- sw/airborne/mcu_periph/adc.h | 5 +- sw/ext/libopencm3 | 2 +- 4 files changed, 92 insertions(+), 56 deletions(-) diff --git a/sw/airborne/arch/stm32/mcu_periph/adc_arch.c b/sw/airborne/arch/stm32/mcu_periph/adc_arch.c index e4050d4f06d..3a7ba9688c8 100644 --- a/sw/airborne/arch/stm32/mcu_periph/adc_arch.c +++ b/sw/airborne/arch/stm32/mcu_periph/adc_arch.c @@ -90,13 +90,7 @@ #include #include -#if defined(STM32F1) -#include -#define ADC_SAMPLE_TIME ADC_SMPR_SMP_41DOT5CYC -#elif defined(STM32F4) -#include -#define ADC_SAMPLE_TIME ADC_SMPR_SMP_56CYC -#endif +#include #include #include #include @@ -110,6 +104,11 @@ #define NVIC_ADC_IRQ_PRIO 0 #endif +#if defined(STM32F1) +#define ADC_SAMPLE_TIME ADC_SMPR_SMP_41DOT5CYC +#elif defined(STM32F4) +#define ADC_SAMPLE_TIME ADC_SMPR_SMP_56CYC +#endif // Macros to automatically enable the correct ADC @@ -152,6 +151,14 @@ PRINT_CONFIG_MSG("Analog to Digital Coverter 3 active") #warning ALL ADC CONVERTERS INACTIVE #endif +#ifndef ADC_TIMER_PRESCALER +#if defined(STM32F1) +#define ADC_TIMER_PRESCALER 0x8 +#elif defined(STM32F4) +#define ADC_TIMER_PRESCALER 0x53 +#endif +#endif + /***************************************/ /*** STATIC FUNCTION PROTOTYPES ***/ /***************************************/ @@ -197,8 +204,10 @@ static struct adc_buf * adc3_buffers[4]; #endif #if USE_ADC_WATCHDOG +#include "mcu_periph/sys_time.h" // watchdog structure with adc bank and callback static struct { + uint32_t timeStamp; uint32_t adc; adc_watchdog_callback cb; } adc_watchdog; @@ -270,23 +279,19 @@ void adc_init( void ) { * That's why "adc_channel_map" has this descending order. */ - nb_adc1_channels = 0; + nb_adc1_channels = NB_ADC1_CHANNELS; #if USE_AD1 -#ifdef AD1_4_CHANNEL - adc_channel_map[3-nb_adc1_channels] = AD1_4_CHANNEL; - nb_adc1_channels++; -#endif -#ifdef AD1_3_CHANNEL - adc_channel_map[3-nb_adc1_channels] = AD1_3_CHANNEL; - nb_adc1_channels++; +#ifdef AD1_1_CHANNEL + adc_channel_map[AD1_1] = AD1_1_CHANNEL; #endif #ifdef AD1_2_CHANNEL - adc_channel_map[3-nb_adc1_channels] = AD1_2_CHANNEL; - nb_adc1_channels++; + adc_channel_map[AD1_2] = AD1_2_CHANNEL; #endif -#ifdef AD1_1_CHANNEL - adc_channel_map[3-nb_adc1_channels] = AD1_1_CHANNEL; - nb_adc1_channels++; +#ifdef AD1_3_CHANNEL + adc_channel_map[AD1_3] = AD1_3_CHANNEL; +#endif +#ifdef AD1_4_CHANNEL + adc_channel_map[AD1_4] = AD1_4_CHANNEL; #endif // initialize buffer pointers with 0 (not set). Buffer null pointers will be ignored in interrupt // handler, which is important as there are no buffers registered at the time the ADC trigger @@ -296,23 +301,19 @@ void adc_init( void ) { #endif // USE_AD1 - nb_adc2_channels = 0; + nb_adc2_channels = NB_ADC2_CHANNELS; #if USE_AD2 -#ifdef AD2_4_CHANNEL - adc_channel_map[3-nb_adc2_channels] = AD2_4_CHANNEL; - nb_adc2_channels++; -#endif -#ifdef AD2_3_CHANNEL - adc_channel_map[3-nb_adc2_channels] = AD2_3_CHANNEL; - nb_adc2_channels++; +#ifdef AD2_1_CHANNEL + adc_channel_map[AD2_1] = AD2_1_CHANNEL; #endif #ifdef AD2_2_CHANNEL - adc_channel_map[3-nb_adc2_channels] = AD2_2_CHANNEL; - nb_adc2_channels++; + adc_channel_map[AD2_2] = AD2_2_CHANNEL; #endif -#ifdef AD2_1_CHANNEL - adc_channel_map[3-nb_adc2_channels] = AD2_1_CHANNEL; - nb_adc2_channels++; +#ifdef AD2_3_CHANNEL + adc_channel_map[AD2_3] = AD2_3_CHANNEL; +#endif +#ifdef AD2_4_CHANNEL + adc_channel_map[AD2_4] = AD2_4_CHANNEL; #endif // initialize buffer pointers with 0 (not set). Buffer null pointers will be ignored in interrupt // handler, which is important as there are no buffers registered at the time the ADC trigger @@ -322,23 +323,19 @@ void adc_init( void ) { #endif // USE_AD2 - nb_adc3_channels = 0; + nb_adc3_channels = NB_ADC3_CHANNELS; #if USE_AD3 -#ifdef AD3_4_CHANNEL - adc_channel_map[3-nb_adc3_channels] = AD3_4_CHANNEL; - nb_adc3_channels++; -#endif -#ifdef AD3_3_CHANNEL - adc_channel_map[3-nb_adc3_channels] = AD3_3_CHANNEL; - nb_adc3_channels++; +#ifdef AD3_1_CHANNEL + adc_channel_map[AD3_1] = AD3_1_CHANNEL; #endif #ifdef AD3_2_CHANNEL - adc_channel_map[3-nb_adc3_channels] = AD3_2_CHANNEL; - nb_adc3_channels++; + adc_channel_map[AD3_2] = AD3_2_CHANNEL; #endif -#ifdef AD3_1_CHANNEL - adc_channel_map[3-nb_adc3_channels] = AD3_1_CHANNEL; - nb_adc3_channels++; +#ifdef AD3_3_CHANNEL + adc_channel_map[AD3_3] = AD3_3_CHANNEL; +#endif +#ifdef AD3_4_CHANNEL + adc_channel_map[AD3_4] = AD3_4_CHANNEL; #endif // initialize buffer pointers with 0 (not set). Buffer null pointers will be ignored in interrupt // handler, which is important as there are no buffers registered at the time the ADC trigger @@ -351,6 +348,7 @@ void adc_init( void ) { #if USE_ADC_WATCHDOG adc_watchdog.cb = NULL; + adc_watchdog.timeStamp=0; #endif } @@ -440,11 +438,10 @@ static inline void adc_init_rcc( void ) TIM_CR1_CMS_EDGE, TIM_CR1_DIR_UP); #if defined(STM32F1) timer_set_period(timer, 0xFF); - timer_set_prescaler(timer, 0x8); #elif defined(STM32F4) timer_set_period(timer, 0xFFFF); - timer_set_prescaler(timer, 0x53); #endif + timer_set_prescaler(timer, ADC_TIMER_PRESCALER); //timer_set_clock_division(timer, 0x0); /* Generate TRGO on every update. */ timer_set_master_mode(timer, TIM_CR2_MMS_UPDATE); @@ -584,6 +581,16 @@ void adc1_2_isr(void) struct adc_buf * buf; #if USE_ADC_WATCHDOG + /* + We need adc sampling fast enough to detect battery plug out, but we did not + need to get actual actual value so fast. So timer fire adc conversion fast, + at least 500 hz, but we inject adc value in sampling buffer only at 10hz + */ + const uint32_t timeStampDiff = get_sys_time_usec() - adc_watchdog.timeStamp; + const bool_t shouldAccumulateValue = timeStampDiff > 100; + if (shouldAccumulateValue) + adc_watchdog.timeStamp = get_sys_time_usec(); + if (adc_watchdog.cb != NULL) { if (adc_awd(adc_watchdog.adc)) { ADC_SR(adc_watchdog.adc) &= ~ADC_SR_AWD; // clear int flag @@ -596,6 +603,9 @@ void adc1_2_isr(void) // Clear Injected End Of Conversion if (ADC_SR(ADC1) & ADC_SR_JEOC){ ADC_SR(ADC1) &= ~ADC_SR_JEOC; +#if USE_ADC_WATCHDOG + if (shouldAccumulateValue) { +#endif for (channel = 0; channel < nb_adc1_channels; channel++) { buf = adc1_buffers[channel]; if (buf) { @@ -603,6 +613,10 @@ void adc1_2_isr(void) adc_push_sample(buf, value); } } +#if USE_ADC_WATCHDOG + } +#endif + #if !USE_AD2 && !USE_AD3 adc_new_data_trigger = TRUE; #endif @@ -611,6 +625,9 @@ void adc1_2_isr(void) #if USE_AD2 if (ADC_SR(ADC2) & ADC_SR_JEOC){ ADC_SR(ADC2) &= ~ADC_SR_JEOC; +#if USE_ADC_WATCHDOG + if (shouldAccumulateValue) { +#endif for (channel = 0; channel < nb_adc2_channels; channel++) { buf = adc2_buffers[channel]; if (buf) { @@ -618,6 +635,9 @@ void adc1_2_isr(void) adc_push_sample(buf, value); } } +#if USE_ADC_WATCHDOG + } +#endif #if !USE_AD3 adc_new_data_trigger = TRUE; #endif @@ -626,6 +646,9 @@ void adc1_2_isr(void) #if USE_AD3 if (ADC_SR(ADC3) & ADC_SR_JEOC){ ADC_SR(ADC3) &= ~ADC_SR_JEOC; +#if USE_ADC_WATCHDOG + if (shouldAccumulateValue) { +#endif for (channel = 0; channel < nb_adc3_channels; channel++) { buf = adc3_buffers[channel]; if (buf) { @@ -633,9 +656,13 @@ void adc1_2_isr(void) adc_push_sample(buf, value); } } +#if USE_ADC_WATCHDOG + } +#endif adc_new_data_trigger = TRUE; } #endif + return; } diff --git a/sw/airborne/arch/stm32/mcu_periph/adc_arch.h b/sw/airborne/arch/stm32/mcu_periph/adc_arch.h index e0fa6a14645..1bb04ce9aa4 100644 --- a/sw/airborne/arch/stm32/mcu_periph/adc_arch.h +++ b/sw/airborne/arch/stm32/mcu_periph/adc_arch.h @@ -33,7 +33,8 @@ #include BOARD_CONFIG // NB_ADCx_CHANNELS -enum adc_channels { + +enum adc1_channels { #ifdef AD1_1_CHANNEL AD1_1, #endif @@ -46,7 +47,10 @@ enum adc_channels { #ifdef AD1_4_CHANNEL AD1_4, #endif -// NB_ADC1_CHANNELS + NB_ADC1_CHANNELS +}; + +enum adc2_channels { #ifdef AD2_1_CHANNEL AD2_1, #endif @@ -59,7 +63,10 @@ enum adc_channels { #ifdef AD2_4_CHANNEL AD2_4, #endif -// NB_ADC2_CHANNELS + NB_ADC2_CHANNELS +}; + +enum adc3_channels { #ifdef AD3_1_CHANNEL AD3_1, #endif @@ -72,10 +79,11 @@ enum adc_channels { #ifdef AD3_4_CHANNEL AD3_4, #endif -// NB_ADC3_CHANNELS - NB_ADC + NB_ADC3_CHANNELS }; +#define NB_ADC (NB_ADC1_CHANNELS+NB_ADC2_CHANNELS+NB_ADC3_CHANNELS) + #if USE_ADC_WATCHDOG /* Watchdog callback type definition diff --git a/sw/airborne/mcu_periph/adc.h b/sw/airborne/mcu_periph/adc.h index feb7cf4c476..f57b4500cbd 100644 --- a/sw/airborne/mcu_periph/adc.h +++ b/sw/airborne/mcu_periph/adc.h @@ -31,8 +31,8 @@ * - register it with the ::adc_buf_channel function */ -#ifndef _ADC_H_ -#define _ADC_H_ +#ifndef MCU_PERIPH_ADC_H +#define MCU_PERIPH_ADC_H #include #include "mcu_periph/adc_arch.h" @@ -78,4 +78,5 @@ void adc_buf_channel(uint8_t adc_channel, struct adc_buf* s, uint8_t av_nb_sampl /** Starts conversions */ void adc_init( void ); + #endif diff --git a/sw/ext/libopencm3 b/sw/ext/libopencm3 index fb5c86db072..638eeebeec8 160000 --- a/sw/ext/libopencm3 +++ b/sw/ext/libopencm3 @@ -1 +1 @@ -Subproject commit fb5c86db0723aa64740df7aebb3a0fd69acf52fe +Subproject commit 638eeebeec8e0c241dcaca0e4bf06c9c681e0884