diff options
Diffstat (limited to 'tests/adc-power')
-rw-r--r-- | tests/adc-power/Makefile.stm32f4-disco | 44 | ||||
-rw-r--r-- | tests/adc-power/adc-power.c | 94 | ||||
-rw-r--r-- | tests/adc-power/adc-power.h | 25 | ||||
-rw-r--r-- | tests/adc-power/main-stm32f4-disco.c | 52 |
4 files changed, 215 insertions, 0 deletions
diff --git a/tests/adc-power/Makefile.stm32f4-disco b/tests/adc-power/Makefile.stm32f4-disco new file mode 100644 index 0000000..b592384 --- /dev/null +++ b/tests/adc-power/Makefile.stm32f4-disco @@ -0,0 +1,44 @@ +## +## This file is part of the libopencm3 project. +## +## This library is free software: you can redistribute it and/or modify +## it under the terms of the GNU Lesser General Public License as published by +## the Free Software Foundation, either version 3 of the License, or +## (at your option) any later version. +## +## This library is distributed in the hope that it will be useful, +## but WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +## GNU Lesser General Public License for more details. +## +## You should have received a copy of the GNU Lesser General Public License +## along with this library. If not, see <http://www.gnu.org/licenses/>. +## + +BOARD = stm32f4-disco +PROJECT = adc-power-$(BOARD) +BUILD_DIR = bin-$(BOARD) + +SHARED_DIR = ../../shared + +CFILES = main-$(BOARD).c +CFILES += adc-power.c +CFILES += trace.c trace_stdio.c + +VPATH += $(SHARED_DIR) + +INCLUDES += $(patsubst %,-I%, . $(SHARED_DIR)) + +OPENCM3_DIR=../../libopencm3/ + +### This section can go to an arch shared rules eventually... +LDSCRIPT = ../../../libopencm3/lib/stm32/f4/stm32f405x6.ld +OPENCM3_LIB = opencm3_stm32f4 +OPENCM3_DEFS = -DSTM32F4 +FP_FLAGS ?= -mfloat-abi=hard -mfpu=fpv4-sp-d16 +ARCH_FLAGS = -mthumb -mcpu=cortex-m4 $(FP_FLAGS) +#OOCD_INTERFACE = stlink-v2 +#OOCD_TARGET = stm32f4x +OOCD_FILE = ../../openocd/openocd.stm32f4-disco.cfg + +include ../../rules.mk diff --git a/tests/adc-power/adc-power.c b/tests/adc-power/adc-power.c new file mode 100644 index 0000000..817671c --- /dev/null +++ b/tests/adc-power/adc-power.c @@ -0,0 +1,94 @@ +/** + * 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])) + + +void adc_power_init(void) +{ + /* Some basic ADC config, that we won't touch again */ + rcc_periph_clock_enable(RCC_ADC1); + adc_set_sample_time_on_all_channels(ADC1, ADC_SMPR_SMP_28CYC); +#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 + adc_disable_scan_mode(ADC1); +#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); + adc_start_conversion_regular(ADC1); + while (!adc_eoc(ADC1)); + return adc_read_regular(ADC1); +} + +void adc_power_task_up(void) { + TIM_CNT(TIMER) = 0; + 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); +#if 0 + uint8_t channels[2] = { 0, 1 }; + adc_set_regular_sequence(ADC1, ARRAY_SIZE(channels), channels); + TIM_CNT(TIMER) = 0; + adc_start_conversion_regular(ADC1); + while (!adc_eoc(ADC1)); + unsigned int v1 = adc_read_regular(ADC1); + while (!adc_eoc(ADC1)); + unsigned int v2 = adc_read_regular(ADC1); + unsigned int tconv = TIM_CNT(TIMER); +#else + TIM_CNT(TIMER) = 0; + unsigned int v1 = read_adc_naiive(0); + unsigned int v2 = read_adc_naiive(1); + unsigned int tconv = TIM_CNT(TIMER); +#endif + + printf("ton: %u, tconv: %u, v1: %u, v2: %u\n", td, tconv, v1, v2); +} + +void adc_power_task_down() +{ + TIM_CNT(TIMER) = 0; + adc_power_off(ADC1); + unsigned int td = TIM_CNT(TIMER); + printf("toff in: %u\n", td); +}
\ No newline at end of file diff --git a/tests/adc-power/adc-power.h b/tests/adc-power/adc-power.h new file mode 100644 index 0000000..2775d1a --- /dev/null +++ b/tests/adc-power/adc-power.h @@ -0,0 +1,25 @@ +/* + * File: adc-power.h + * Author: karlp + * + * Created on October 17, 2015, 12:19 AM + */ + +#ifndef ADC_POWER_H +#define ADC_POWER_H + +#ifdef __cplusplus +extern "C" { +#endif + + void adc_power_init(void); + void adc_power_task_up(void); + void adc_power_task_down(void); + + +#ifdef __cplusplus +} +#endif + +#endif /* ADC_POWER_H */ + diff --git a/tests/adc-power/main-stm32f4-disco.c b/tests/adc-power/main-stm32f4-disco.c new file mode 100644 index 0000000..f02e610 --- /dev/null +++ b/tests/adc-power/main-stm32f4-disco.c @@ -0,0 +1,52 @@ +/* + * Oct 2015 Karl Palsson <karlp@tweak.net.au> + */ + +#include <errno.h> +#include <stdio.h> +#include <unistd.h> +#include <libopencm3/cm3/nvic.h> +#include <libopencm3/stm32/adc.h> +#include <libopencm3/stm32/dac.h> +#include <libopencm3/stm32/gpio.h> +#include <libopencm3/stm32/rcc.h> +#include <libopencm3/stm32/usart.h> + +#include "trace.h" +#include "adc-power.h" + +#define LED_DISCO_GREEN_PORT GPIOD +#define LED_DISCO_GREEN_PIN GPIO12 + +int main(void) +{ + int i; + int j = 0; + rcc_clock_setup_hse_3v3(&hse_8mhz_3v3[CLOCK_3V3_168MHZ]); + rcc_periph_clock_enable(RCC_GPIOD); + printf("hi guys!\n"); + /* green led for ticking */ + gpio_mode_setup(LED_DISCO_GREEN_PORT, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, + LED_DISCO_GREEN_PIN); + + rcc_periph_clock_enable(RCC_GPIOA); + gpio_mode_setup(GPIOA, GPIO_MODE_ANALOG, GPIO_PUPD_NONE, GPIO0); + gpio_mode_setup(GPIOA, GPIO_MODE_ANALOG, GPIO_PUPD_NONE, GPIO1); + + adc_power_init(); + while (1) { + adc_power_task_up(); + gpio_toggle(LED_DISCO_GREEN_PORT, LED_DISCO_GREEN_PIN); + + for (i = 0; i < 0x1000000; i++) { /* Wait a bit. */ + __asm__("NOP"); + } + adc_power_task_down(); + gpio_toggle(LED_DISCO_GREEN_PORT, LED_DISCO_GREEN_PIN); + for (i = 0; i < 0x1000000; i++) { /* Wait a bit. */ + __asm__("NOP"); + } + } + + return 0; +} |