diff options
Diffstat (limited to 'tests/adc-power/adc-power.c')
-rw-r--r-- | tests/adc-power/adc-power.c | 211 |
1 files changed, 0 insertions, 211 deletions
diff --git a/tests/adc-power/adc-power.c b/tests/adc-power/adc-power.c deleted file mode 100644 index bcd9c87..0000000 --- a/tests/adc-power/adc-power.c +++ /dev/null @@ -1,211 +0,0 @@ -/** - * Testing ADC power up and power down, for timing and actual on/off - * Uses TIM6, because DWT_CYCCNT not available on cm0(+) :( - * (And with no DWT, no ITM timestamping either, get a real mcu!) - */ - -#include <stdio.h> -#include <stdint.h> -#include <libopencm3/stm32/adc.h> -#include <libopencm3/stm32/rcc.h> -#include <libopencm3/stm32/timer.h> - -#include "adc-power.h" - -/* Everyone has tim6 right? */ -#define TIMER TIM6 -#define TIMER_RCC RCC_TIM6 - -// TODO - stick this in libopencm3? -#define ARRAY_SIZE(a) (sizeof((a)) / sizeof((a)[0])) - -// Still have some bad shit to deal with... -#if defined(STM32F0) -#define SEPARATE_ADC_SAMPLING 0 -#define SAMPLE_TIME_BASIC ADC_SMPR_SMP_239DOT5 // 4usec or more for tempsensor -#define HAS_CALIBRATION 1 -#elif defined(STM32F1) -#define SEPARATE_ADC_SAMPLING 0 -#define SAMPLE_TIME_BASIC ADC_SMPR_SMP_28DOT5CYC // 17usecs or more. >~15cycles at 9Mhz -#define SEPARATE_VREF 0 -#define HAS_CALIBRATION 1 -#define HAS_ROM_CALIBRATION 0 -#elif defined(STM32F3) -#define SAMPLE_TIME_BASIC ADC_SMPR_SMP_181DOT5CYC -#define SAMPLE_TIME_TEMP ADC_SMPR_SMP_601DOT5CYC // 2.2usecs or more -#define SAMPLE_TIME_VREF SAMPLE_TIME_TEMP -#define HAS_CALIBRATION 1 -#elif defined(STM32F4) -#define SAMPLE_TIME_BASIC ADC_SMPR_SMP_28CYC -#define SAMPLE_TIME_TEMP ADC_SMPR_SMP_144CYC // 10 usecs or more, in theory needs 840cycles! -#define SAMPLE_TIME_VREF SAMPLE_TIME_TEMP -#define ADC_CHANNEL_TEMP ADC_CHANNEL_TEMP_F40 -#define SEPARATE_VREF 0 -#elif defined(STM32L1) -#define SAMPLE_TIME_BASIC ADC_SMPR_SMP_24CYC -#define SAMPLE_TIME_TEMP ADC_SMPR_SMP_192CYC -#define SAMPLE_TIME_VREF SAMPLE_TIME_TEMP -#define SEPARATE_VREF 0 -#elif defined(STM32L4) -#define SAMPLE_TIME_BASIC ADC_SMPR_SMP_247DOT5CYC -#define SAMPLE_TIME_TEMP ADC_SMPR_SMP_247DOT5CYC -#define SAMPLE_TIME_VREF SAMPLE_TIME_TEMP -#define HAS_CALIBRATION 1 -#else -#error "no sample time for your target yet?!" -#endif - -#ifndef SEPARATE_VREF -#define SEPARATE_VREF 1 -#endif -#ifndef SEPARATE_ADC_SAMPLING -#define SEPARATE_ADC_SAMPLING 1 -#endif -#ifndef HAS_CALIBRATION -#define HAS_CALIBRATION 0 -#endif -#ifndef HAS_ROM_CALIBRATION -#define HAS_ROM_CALIBRATION 1 -#endif - - -void adc_power_init(void) -{ - /* Some basic ADC config, that we won't touch again */ -#if defined(STM32F3) - /* silly f303 */ - rcc_periph_clock_enable(RCC_ADC12); - rcc_adc_prescale(RCC_CFGR2_ADCxPRES_PLL_CLK_DIV_1, RCC_CFGR2_ADCxPRES_PLL_CLK_DIV_1); - adc_enable_regulator(ADC1); -#elif defined (STM32L4) - /* same same but different */ - rcc_periph_clock_enable(RCC_ADC1); - ADC_CR(ADC1) &= ~ADC_CR_DEEPPWD; - RCC_CCIPR |= 3 << 28; // system clock as adc clock. (with CKMODE == 0) - adc_enable_regulator(ADC1); - - ADC_CR(ADC1) &= ~ADC_CR_ADCALDIF; - ADC_CR(ADC1) |= ADC_CR_ADCAL; - while (ADC_CR(ADC1) & ADC_CR_ADCAL); - - -#else - rcc_periph_clock_enable(RCC_ADC1); -#if 0 - // DANGER DANGER! doing this without DMA is dum. - // but... we're busy polling, we should be right... right? - // (dma across platforms is teh suck) - adc_enable_scan_mode(ADC1); - ADC_CR2 |= ADC_CR2_EOCS; // FIXME -#else - // FIXME - f0! adc_disable_scan_mode(ADC1); -#endif - -#endif -#if (SEPARATE_ADC_SAMPLING == 1) - adc_set_sample_time_on_all_channels(ADC1, SAMPLE_TIME_BASIC); - adc_set_sample_time(ADC1, ADC_CHANNEL_TEMP, SAMPLE_TIME_TEMP); - adc_set_sample_time(ADC1, ADC_CHANNEL_TEMP, SAMPLE_TIME_VREF); -#else - adc_set_sample_time_on_all_channels(ADC1, SAMPLE_TIME_BASIC); -#endif - adc_enable_temperature_sensor(); -#if (SEPARATE_VREF == 1) - adc_enable_vrefint(); -#endif - - /* - * We're going to setup a timer to run at top speed, so... "fast" - * but we don't actually care about the rate itself. We just - * want to collect how many ticks it takes to enable and disable - * the adc. - */ - rcc_periph_clock_enable(TIMER_RCC); - timer_reset(TIMER); - timer_set_prescaler(TIMER, 0); - timer_enable_counter(TIMER); -} - -static uint16_t read_adc_naiive(uint8_t channel) -{ - uint8_t channel_array[16]; - channel_array[0] = channel; - adc_set_regular_sequence(ADC1, 1, channel_array); - // FIXME - use a trigger, see f1 notes! -#if defined (STM32F1) - adc_start_conversion_direct(ADC1); -#else - adc_start_conversion_regular(ADC1); -#endif - while (!adc_eoc(ADC1)); - return adc_read_regular(ADC1); -} - -static float adc_calc_tempf(unsigned int ts_v, unsigned int vref) { -#if (HAS_ROM_CALIBRATION == 1) - float adjusted_vtemp = ts_v * ST_VREFINT_CAL * 1.0f / vref * 1.0f; - float slope = (110-30) * 1.0f / (ST_TSENSE_CAL2_110C - ST_TSENSE_CAL1_30C) * 1.0f; - return slope * (adjusted_vtemp - ST_TSENSE_CAL1_30C) + 30; -#else - (void)vref; - return ts_v * 1.0; -#endif -} - -static int adc_calc_tempi(unsigned int ts, unsigned int vref) { -#if (HAS_ROM_CALIBRATION == 1) - int adjusted_vtemp = ts * ST_VREFINT_CAL / vref; - int slope = (110-30) / (ST_TSENSE_CAL2_110C - ST_TSENSE_CAL1_30C); - return slope * (adjusted_vtemp - ST_TSENSE_CAL1_30C) + 30; -#else - (void)vref; - return ts * 1.00; -#endif -} - -void adc_power_task_up(void) { - TIM_CNT(TIMER) = 0; - // Welcome to f1 world. -#if defined (STM32F1) - adc_power_on(ADC1); - for (int i = 0; i < 0x80000; i++) { /* Wait a bit. */ - __asm__("NOP"); - } -#endif -#if (HAS_CALIBRATION == 1) - adc_calibrate(ADC1); -#endif - adc_power_on(ADC1); - unsigned int td = TIM_CNT(TIMER); - - /* just for kicks, let's time some sequences too.... - * I mean, we're going to do some conversions right? */ - adc_set_single_conversion_mode(ADC1); - TIM_CNT(TIMER) = 0; - unsigned int v1 = read_adc_naiive(1); // 8 for l4! - unsigned int v5 = read_adc_naiive(5); - unsigned int temp_adc = read_adc_naiive(ADC_CHANNEL_TEMP); - unsigned int vref_adc = read_adc_naiive(ADC_CHANNEL_VREF); - unsigned int tconv = TIM_CNT(TIMER); - TIM_CNT(TIMER) = 0; - float tempf = adc_calc_tempf(temp_adc, vref_adc); - int tconvf = TIM_CNT(TIMER); - TIM_CNT(TIMER) = 0; - int tempi = adc_calc_tempi(temp_adc, vref_adc); - int tconvi = TIM_CNT(TIMER); - - printf("ton: %u, tconv: %u, ch1: %u, ch5: %u\n", td, tconv, v1, v5); - printf("\tTemperature: %f (tc %d) or %d (tc %d) (raw ts: %d, raw vref: %d)\n", - tempf, tconvf, tempi, tconvi, temp_adc, vref_adc); - //printf("\tT1-30 %d, t2-110 %d, vrefcal: %d\n", ST_TSENSE_CAL1_30C, ST_TSENSE_CAL2_110C, ST_VREFINT_CAL); -} - -void adc_power_task_down() -{ - TIM_CNT(TIMER) = 0; - adc_power_off(ADC1); - /* double power off should be safe */ - adc_power_off(ADC1); - unsigned int td = TIM_CNT(TIMER); - printf("toff in: %u\n", td); -} |