From 099a5626dba3a885d4e5b6903a5a5a642c3d6638 Mon Sep 17 00:00:00 2001 From: Oliver Dille Date: Fri, 7 Sep 2012 22:43:10 +0200 Subject: Random number generator example. --- .../stm32/f4/stm32f4-discovery/random/Makefile | 25 ++++++ examples/stm32/f4/stm32f4-discovery/random/README | 5 ++ .../stm32/f4/stm32f4-discovery/random/random.c | 88 ++++++++++++++++++++++ 3 files changed, 118 insertions(+) create mode 100644 examples/stm32/f4/stm32f4-discovery/random/Makefile create mode 100644 examples/stm32/f4/stm32f4-discovery/random/README create mode 100644 examples/stm32/f4/stm32f4-discovery/random/random.c (limited to 'examples') diff --git a/examples/stm32/f4/stm32f4-discovery/random/Makefile b/examples/stm32/f4/stm32f4-discovery/random/Makefile new file mode 100644 index 0000000..4f06835 --- /dev/null +++ b/examples/stm32/f4/stm32f4-discovery/random/Makefile @@ -0,0 +1,25 @@ +## +## This file is part of the libopencm3 project. +## +## Copyright (C) 2009 Uwe Hermann +## +## 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 . +## + +BINARY = random + +LDSCRIPT = ../stm32f4-discovery.ld + +include ../../Makefile.include + diff --git a/examples/stm32/f4/stm32f4-discovery/random/README b/examples/stm32/f4/stm32f4-discovery/random/README new file mode 100644 index 0000000..875e6bf --- /dev/null +++ b/examples/stm32/f4/stm32f4-discovery/random/README @@ -0,0 +1,5 @@ +------------------------------------------------------------------------------ +README +------------------------------------------------------------------------------ + +This example randomly blinks the green LED on the ST STM32F4DISCOVERY eval board. diff --git a/examples/stm32/f4/stm32f4-discovery/random/random.c b/examples/stm32/f4/stm32f4-discovery/random/random.c new file mode 100644 index 0000000..9305be3 --- /dev/null +++ b/examples/stm32/f4/stm32f4-discovery/random/random.c @@ -0,0 +1,88 @@ +/* + * 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 . + */ + + +#include +#include +#include +#include + +static void rcc_setup(void) +{ + rcc_clock_setup_hse_3v3(&hse_8mhz_3v3[CLOCK_3V3_120MHZ]); + + /* Enable GPIOD clock for onboard leds. */ + rcc_peripheral_enable_clock(&RCC_AHB1ENR, RCC_AHB1ENR_IOPDEN); + + /* Enable rng clock */ + rcc_peripheral_enable_clock(&RCC_AHB2ENR, RCC_AHB2ENR_RNGEN); +} + +static void rng_setup(void) +{ + /* Enable interupt */ + /* Set the IE bit in the RNG_CR register. */ + RNG_CR |= RNG_CR_IE; + /* Enable the random number generation by setting the RNGEN bit in the RNG_CR + register. This activates the analog part, the RNG_LFSR and the error detector. + */ + RNG_CR |= RNG_CR_EN; +} + +static void gpio_setup(void) +{ + /* Setup onboard led */ + gpio_mode_setup(GPIOD, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, GPIO12 | GPIO13); +} + +/* Tried to folow the guidelines in the stm32f4 user manual.*/ +static u32 random_int(void) +{ + static u32 last_value=0; + static u32 new_value=0; + u32 error_bits = 0; + error_bits = RNG_SR_SEIS | RNG_SR_CEIS; + while (new_value==last_value) { + /* Check for error flags and if data is ready. */ + if ( ((RNG_SR & error_bits) == 0) && ( (RNG_SR & RNG_SR_DRDY) == 1 ) ) + new_value=RNG_DR; + } + last_value=new_value; + return new_value; +} + + +int main(void) +{ + int i,j; + rcc_setup(); + gpio_setup(); + rng_setup(); + while(1){ + u32 rnd; + rnd = random_int(); + for(i=0;i!=32;++i){ + if ( (rnd & (1 << i))!=0 ) + gpio_set(GPIOD, GPIO12); + else + gpio_clear(GPIOD, GPIO12); + /* Delay */ + for(j=0;j!=5000000;++j) + __asm__("nop"); + } + } +} -- cgit v1.2.3 From 584052c28cdfe5c383f13471deb891ba9438843a Mon Sep 17 00:00:00 2001 From: Daniel Serpell Date: Wed, 22 Aug 2012 00:05:09 -0400 Subject: Compile stm32-f4 library with floating point support. This enables hard-float in the compilation of library and examples for the stm32f40* chips. --- examples/stm32/f4/Makefile.include | 5 +++-- lib/stm32/f4/Makefile | 3 ++- 2 files changed, 5 insertions(+), 3 deletions(-) (limited to 'examples') diff --git a/examples/stm32/f4/Makefile.include b/examples/stm32/f4/Makefile.include index b735aa6..9dfe9d0 100644 --- a/examples/stm32/f4/Makefile.include +++ b/examples/stm32/f4/Makefile.include @@ -36,12 +36,13 @@ endif TOOLCHAIN_DIR := ../../../../.. endif CFLAGS += -Os -g -Wall -Wextra -I$(TOOLCHAIN_DIR)/include \ - -fno-common -mcpu=cortex-m4 -mthumb -msoft-float -MD -DSTM32F4 + -fno-common -mcpu=cortex-m4 -mthumb \ + -mfloat-abi=hard -mfpu=fpv4-sp-d16 -MD -DSTM32F4 LDSCRIPT ?= $(BINARY).ld LDFLAGS += -lc -lnosys -L$(TOOLCHAIN_DIR)/lib \ -L$(TOOLCHAIN_DIR)/lib/stm32/f4 \ -T$(LDSCRIPT) -nostartfiles -Wl,--gc-sections \ - -mthumb -mcpu=cortex-m4 -march=armv7 -mfix-cortex-m3-ldrd -msoft-float + -mthumb -mcpu=cortex-m4 -mthumb -mfloat-abi=hard -mfpu=fpv4-sp-d16 OBJS += $(BINARY).o OOCD ?= openocd diff --git a/lib/stm32/f4/Makefile b/lib/stm32/f4/Makefile index 5760d29..881ef5d 100644 --- a/lib/stm32/f4/Makefile +++ b/lib/stm32/f4/Makefile @@ -24,7 +24,8 @@ PREFIX ?= arm-none-eabi CC = $(PREFIX)-gcc AR = $(PREFIX)-ar CFLAGS = -Os -g -Wall -Wextra -I../../../include -fno-common \ - -mcpu=cortex-m3 -mthumb -Wstrict-prototypes \ + -mcpu=cortex-m4 -mthumb -mfloat-abi=hard -mfpu=fpv4-sp-d16 \ + -Wstrict-prototypes \ -ffunction-sections -fdata-sections -MD -DSTM32F4 # ARFLAGS = rcsv ARFLAGS = rcs -- cgit v1.2.3 From aac5909ff133a71dc01037712f86e89f4e7877d7 Mon Sep 17 00:00:00 2001 From: Daniel Serpell Date: Wed, 22 Aug 2012 00:05:10 -0400 Subject: Add a floating-point example to the stm32f4. This example calculates a mandelbrot fractal using floating point in C. --- .../stm32/f4/stm32f4-discovery/mandelbrot/Makefile | 25 ++++ .../stm32/f4/stm32f4-discovery/mandelbrot/README | 12 ++ .../stm32/f4/stm32f4-discovery/mandelbrot/mandel.c | 127 +++++++++++++++++++++ 3 files changed, 164 insertions(+) create mode 100644 examples/stm32/f4/stm32f4-discovery/mandelbrot/Makefile create mode 100644 examples/stm32/f4/stm32f4-discovery/mandelbrot/README create mode 100644 examples/stm32/f4/stm32f4-discovery/mandelbrot/mandel.c (limited to 'examples') diff --git a/examples/stm32/f4/stm32f4-discovery/mandelbrot/Makefile b/examples/stm32/f4/stm32f4-discovery/mandelbrot/Makefile new file mode 100644 index 0000000..3879eca --- /dev/null +++ b/examples/stm32/f4/stm32f4-discovery/mandelbrot/Makefile @@ -0,0 +1,25 @@ +## +## This file is part of the libopencm3 project. +## +## Copyright (C) 2009 Uwe Hermann +## +## 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 . +## + +BINARY = mandel + +LDSCRIPT = ../stm32f4-discovery.ld + +include ../../Makefile.include + diff --git a/examples/stm32/f4/stm32f4-discovery/mandelbrot/README b/examples/stm32/f4/stm32f4-discovery/mandelbrot/README new file mode 100644 index 0000000..fe4fb13 --- /dev/null +++ b/examples/stm32/f4/stm32f4-discovery/mandelbrot/README @@ -0,0 +1,12 @@ +------------------------------------------------------------------------------ +README +------------------------------------------------------------------------------ + +This example program demonstrates the floating point coprocessor usage on +the ST STM32F4DISCOVERY eval board. + +A mandelbrot fractal is calculated and sent as "ascii-art" image through +the USART2. + +The terminal settings for the receiving device/PC are 38400 8n1. + diff --git a/examples/stm32/f4/stm32f4-discovery/mandelbrot/mandel.c b/examples/stm32/f4/stm32f4-discovery/mandelbrot/mandel.c new file mode 100644 index 0000000..5cbdafd --- /dev/null +++ b/examples/stm32/f4/stm32f4-discovery/mandelbrot/mandel.c @@ -0,0 +1,127 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2009 Uwe Hermann + * Copyright (C) 2011 Stephen Caudle + * Copyright (C) 2012 Daniel Serpell + * + * 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 . + */ + +#include +#include +#include + +void clock_setup(void) +{ + /* Enable high-speed clock at 120MHz */ + rcc_clock_setup_hse_3v3(&hse_8mhz_3v3[CLOCK_3V3_120MHZ]); + + /* Enable GPIOD clock for LED & USARTs. */ + rcc_peripheral_enable_clock(&RCC_AHB1ENR, RCC_AHB1ENR_IOPDEN); + rcc_peripheral_enable_clock(&RCC_AHB1ENR, RCC_AHB1ENR_IOPAEN); + + /* Enable clocks for USART2. */ + rcc_peripheral_enable_clock(&RCC_APB1ENR, RCC_APB1ENR_USART2EN); +} + +void usart_setup(void) +{ + /* Setup USART2 parameters. */ + usart_set_baudrate(USART2, 38400); + usart_set_databits(USART2, 8); + usart_set_stopbits(USART2, USART_STOPBITS_1); + usart_set_mode(USART2, USART_MODE_TX); + usart_set_parity(USART2, USART_PARITY_NONE); + usart_set_flow_control(USART2, USART_FLOWCONTROL_NONE); + + /* Finally enable the USART. */ + usart_enable(USART2); +} + +void gpio_setup(void) +{ + /* Setup GPIO pin GPIO12 on GPIO port D for LED. */ + gpio_mode_setup(GPIOD, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, GPIO12); + + /* Setup GPIO pins for USART2 transmit. */ + gpio_mode_setup(GPIOA, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO2); + + /* Setup USART2 TX pin as alternate function. */ + gpio_set_af(GPIOA, GPIO_AF7, GPIO2); +} + +/* Maximum number of iterations for the escape-time calculation */ +#define maxIter 32 +/* This array converts the iteration count to a character representation. */ +static char color[maxIter+1] = " .:++xxXXX%%%%%%################"; + +/* Main mandelbrot calculation */ +static int iterate(float px, float py) +{ + int it=0; + float x=0,y=0; + while(it 4 ) + return it; + // Zn+1 = Zn^2 + P + y = 2*x*y + py; + x = nx - ny + px; + it++; + } + return 0; +} + +static void mandel(float cX, float cY, float scale) +{ + int x,y; + for(x=-60;x<60;x++) + { + for(y=-50;y<50;y++) + { + int i = iterate(cX+x*scale, cY+y*scale); + usart_send_blocking(USART2, color[i]); + } + usart_send_blocking(USART2, '\r'); + usart_send_blocking(USART2, '\n'); + } +} + +int main(void) +{ + float scale = 0.25f, centerX = -0.5f, centerY = 0.0f; + + clock_setup(); + gpio_setup(); + usart_setup(); + + while (1) { + /* Blink the LED (PD12) on the board with each fractal drawn. */ + gpio_toggle(GPIOD, GPIO12); /* LED on/off */ + mandel(centerX,centerY,scale); /* draw mandelbrot */ + + /* Change scale and center */ + centerX += 0.175f * scale; + centerY += 0.522f * scale; + scale *= 0.875f; + + usart_send_blocking(USART2, '\r'); + usart_send_blocking(USART2, '\n'); + } + + return 0; +} -- cgit v1.2.3 From 7d0611609bc83abc6c942fe3fd6aeab16376fd7f Mon Sep 17 00:00:00 2001 From: Ken Sarkies Date: Fri, 5 Oct 2012 13:50:42 +0930 Subject: Code changes to stm32f1 adc.c and adc.h remove rcc_set_adc_clk - use rcc version Added functions: - adc_power_on - adc_start_conversion_direct - adc_set_dual_mode - adc_eoc - adc_eoc_injected - adc_read_regular - adc_read_injected - adc_set_injected_offset Tested dual mode scanned regular, but no tests of injected yet. Changes: "discontinuous" was misspelled. - adc_set_discontinuous_mode_regular - added "length" parameter - adc_disable_discontinuous_mode_regular - name change - adc_enable_discontinuous_mode_injected - name change - adc_enable_automatic_injected_group_conversion - disable triggers - adc_enable_jeoc_interrupt - name change to match common usage in lib - adc_disable_jeoc_interrupt - ditto - adc_enable_external_trigger_regular - remove incorrect test on parameter - adc_enable_external_trigger_injected - ditto - adc_set_sample_time - name change to match function's purpose - adc_set_conversion_time_on_all_channels - ditto - adc_set_injected_sequence - changed order of register loading (ref Barlow's issue) - adc_enable_analog_watchdog_on_all_channels - flipped AWDSGL - adc_enable_analog_watchdog_on_selected_channel - ditto added aliases for expected commonly used functions to avoid sudden user code breakage In adc.h, corrected errors in SQR names added "deprecated" compiler warnings to adc_on and to aliases defined in adc.c --- examples/stm32/f1/lisa-m-2/adc_regular/adc.c | 11 +- .../stm32/f1/other/adc_temperature_sensor/adc.c | 10 +- include/libopencm3/stm32/f1/adc.h | 89 ++++----- lib/stm32/f1/adc.c | 198 +++++++++++++++++---- 4 files changed, 219 insertions(+), 89 deletions(-) (limited to 'examples') diff --git a/examples/stm32/f1/lisa-m-2/adc_regular/adc.c b/examples/stm32/f1/lisa-m-2/adc_regular/adc.c index 91d029f..f6442b1 100644 --- a/examples/stm32/f1/lisa-m-2/adc_regular/adc.c +++ b/examples/stm32/f1/lisa-m-2/adc_regular/adc.c @@ -3,6 +3,7 @@ * * Copyright (C) 2010 Thomas Otto * Copyright (C) 2012 Piotr Esden-Tempski + * Copyright (C) 2012 Ken Sarkies * * 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 @@ -71,14 +72,13 @@ void adc_setup(void) /* We configure everything for one single conversion. */ adc_disable_scan_mode(ADC1); adc_set_single_conversion_mode(ADC1); - adc_enable_discontinous_mode_regular(ADC1); adc_disable_external_trigger_regular(ADC1); adc_set_right_aligned(ADC1); /* We want to read the temperature sensor, so we have to enable it. */ adc_enable_temperature_sensor(ADC1); - adc_set_conversion_time_on_all_channels(ADC1, ADC_SMPR_SMP_28DOT5CYC); + adc_set_sample_time_on_all_channels(ADC1, ADC_SMPR_SMP_28DOT5CYC); - adc_on(ADC1); + adc_power_on(ADC1); /* Wait for ADC starting up. */ for (i = 0; i < 800000; i++) /* Wait a bit. */ @@ -138,10 +138,9 @@ int main(void) /* Continously convert and poll the temperature ADC. */ while (1) { /* - * If the ADC_CR2_ON bit is already set -> setting it another time - * starts the conversion. + * Start the conversion directly (ie without a trigger). */ - adc_on(ADC1); + adc_start_conversion_direct(ADC1); /* Wait for end of conversion. */ while (!(ADC_SR(ADC1) & ADC_SR_EOC)); diff --git a/examples/stm32/f1/other/adc_temperature_sensor/adc.c b/examples/stm32/f1/other/adc_temperature_sensor/adc.c index dea6a7c..70cc5da 100644 --- a/examples/stm32/f1/other/adc_temperature_sensor/adc.c +++ b/examples/stm32/f1/other/adc_temperature_sensor/adc.c @@ -69,14 +69,13 @@ void adc_setup(void) /* We configure everything for one single conversion. */ adc_disable_scan_mode(ADC1); adc_set_single_conversion_mode(ADC1); - adc_enable_discontinous_mode_regular(ADC1); adc_disable_external_trigger_regular(ADC1); adc_set_right_aligned(ADC1); /* We want to read the temperature sensor, so we have to enable it. */ adc_enable_temperature_sensor(ADC1); - adc_set_conversion_time_on_all_channels(ADC1, ADC_SMPR_SMP_28DOT5CYC); + adc_set_sample_time_on_all_channels(ADC1, ADC_SMPR_SMP_28DOT5CYC); - adc_on(ADC1); + adc_power_on(ADC1); /* Wait for ADC starting up. */ for (i = 0; i < 800000; i++) /* Wait a bit. */ @@ -131,10 +130,9 @@ int main(void) adc_set_regular_sequence(ADC1, 1, channel_array); /* - * If the ADC_CR2_ON bit is already set -> setting it another time - * starts the conversion. + * Start the conversion directly (not trigger mode). */ - adc_on(ADC1); + adc_start_conversion_direct(ADC1); /* Wait for end of conversion. */ while (!(ADC_SR(ADC1) & ADC_SR_EOC)); diff --git a/include/libopencm3/stm32/f1/adc.h b/include/libopencm3/stm32/f1/adc.h index 116aeaa..aa54bdf 100644 --- a/include/libopencm3/stm32/f1/adc.h +++ b/include/libopencm3/stm32/f1/adc.h @@ -252,7 +252,7 @@ LGPL License Terms @ref lgpl_license #define ADC_CR1_DUALMOD_MASK (0xF << 16) #define ADC_CR1_DUALMOD_SHIFT 16 -/* DISCNUM[2:0]: Discontinous mode channel count. */ +/* DISCNUM[2:0]: Discontinuous mode channel count. */ /****************************************************************************/ /** @defgroup adc_cr1_discnum ADC Number of channels in discontinuous mode. @ingroup STM32F1xx_adc_defines @@ -270,10 +270,10 @@ LGPL License Terms @ref lgpl_license #define ADC_CR1_DISCNUM_MASK (0x7 << 13) #define ADC_CR1_DISCNUM_SHIFT 13 -/* JDISCEN: */ /** Discontinous mode on injected channels. */ +/* JDISCEN: */ /** Discontinuous mode on injected channels. */ #define ADC_CR1_JDISCEN (1 << 12) -/* DISCEN: */ /** Discontinous mode on regular channels. */ +/* DISCEN: */ /** Discontinuous mode on regular channels. */ #define ADC_CR1_DISCEN (1 << 11) /* JAUTO: */ /** Automatic Injection Group conversion. */ @@ -557,7 +557,7 @@ LGPL License Terms @ref lgpl_license /* --- ADC_SMPRx generic values -------------------------------------------- */ /****************************************************************************/ /* ADC_SMPRG ADC Sample Time Selection for Channels */ -/** @defgroup adc_sample_rg ADC Sample Time Selection Generic +/** @defgroup adc_sample_rg ADC Sample Time Selection for All Channels @ingroup STM32F1xx_adc_defines @{*/ @@ -587,18 +587,11 @@ LGPL License Terms @ref lgpl_license #define ADC_SQR1_SQ15_LSB 10 #define ADC_SQR1_SQ14_LSB 5 #define ADC_SQR1_SQ13_LSB 0 -#define ADC_SQR1_L_MSK (0xf << ADC_L_LSB) -#define ADC_SQR1_SQ16_MSK (0x1f << ADC_SQ16_LSB) -#define ADC_SQR1_SQ15_MSK (0x1f << ADC_SQ15_LSB) -#define ADC_SQR1_SQ14_MSK (0x1f << ADC_SQ14_LSB) -#define ADC_SQR1_SQ13_MSK (0x1f << ADC_SQ13_LSB) -/* TODO Fix error #define ADC_SQR1_L_MSK (0xf << ADC_SQR1_L_LSB) #define ADC_SQR1_SQ16_MSK (0x1f << ADC_SQR1_SQ16_LSB) #define ADC_SQR1_SQ15_MSK (0x1f << ADC_SQR1_SQ15_LSB) #define ADC_SQR1_SQ14_MSK (0x1f << ADC_SQR1_SQ14_LSB) #define ADC_SQR1_SQ13_MSK (0x1f << ADC_SQR1_SQ13_LSB) -*/ /* --- ADC_SQR2 values ----------------------------------------------------- */ @@ -608,20 +601,12 @@ LGPL License Terms @ref lgpl_license #define ADC_SQR2_SQ9_LSB 10 #define ADC_SQR2_SQ8_LSB 5 #define ADC_SQR2_SQ7_LSB 0 -#define ADC_SQR2_SQ12_MSK (0x1f << ADC_SQ12_LSB) -#define ADC_SQR2_SQ11_MSK (0x1f << ADC_SQ11_LSB) -#define ADC_SQR2_SQ10_MSK (0x1f << ADC_SQ10_LSB) -#define ADC_SQR2_SQ9_MSK (0x1f << ADC_SQ9_LSB) -#define ADC_SQR2_SQ8_MSK (0x1f << ADC_SQ8_LSB) -#define ADC_SQR2_SQ7_MSK (0x1f << ADC_SQ7_LSB) -/* TODO Fix error #define ADC_SQR2_SQ12_MSK (0x1f << ADC_SQR2_SQ12_LSB) #define ADC_SQR2_SQ11_MSK (0x1f << ADC_SQR2_SQ11_LSB) #define ADC_SQR2_SQ10_MSK (0x1f << ADC_SQR2_SQ10_LSB) #define ADC_SQR2_SQ9_MSK (0x1f << ADC_SQR2_SQ9_LSB) #define ADC_SQR2_SQ8_MSK (0x1f << ADC_SQR2_SQ8_LSB) #define ADC_SQR2_SQ7_MSK (0x1f << ADC_SQR2_SQ7_LSB) -*/ /* --- ADC_SQR3 values ----------------------------------------------------- */ @@ -631,20 +616,12 @@ LGPL License Terms @ref lgpl_license #define ADC_SQR3_SQ3_LSB 10 #define ADC_SQR3_SQ2_LSB 5 #define ADC_SQR3_SQ1_LSB 0 -#define ADC_SQR3_SQ6_MSK (0x1f << ADC_SQ6_LSB) -#define ADC_SQR3_SQ5_MSK (0x1f << ADC_SQ5_LSB) -#define ADC_SQR3_SQ4_MSK (0x1f << ADC_SQ4_LSB) -#define ADC_SQR3_SQ3_MSK (0x1f << ADC_SQ3_LSB) -#define ADC_SQR3_SQ2_MSK (0x1f << ADC_SQ2_LSB) -#define ADC_SQR3_SQ1_MSK (0x1f << ADC_SQ1_LSB) -/* TODO Fix error #define ADC_SQR3_SQ6_MSK (0x1f << ADC_SQR3_SQ6_LSB) #define ADC_SQR3_SQ5_MSK (0x1f << ADC_SQR3_SQ5_LSB) #define ADC_SQR3_SQ4_MSK (0x1f << ADC_SQR3_SQ4_LSB) #define ADC_SQR3_SQ3_MSK (0x1f << ADC_SQR3_SQ3_LSB) #define ADC_SQR3_SQ2_MSK (0x1f << ADC_SQR3_SQ2_LSB) #define ADC_SQR3_SQ1_MSK (0x1f << ADC_SQR3_SQ1_LSB) -*/ /* --- ADC_JSQR values ----------------------------------------------------- */ #define ADC_JSQR_JL_LSB 20 @@ -652,18 +629,24 @@ LGPL License Terms @ref lgpl_license #define ADC_JSQR_JSQ3_LSB 10 #define ADC_JSQR_JSQ2_LSB 5 #define ADC_JSQR_JSQ1_LSB 0 -#define ADC_JSQR_JL_MSK (0x2 << ADC_JL_LSB) -#define ADC_JSQR_JSQ4_MSK (0x1f << ADC_JSQ4_LSB) -#define ADC_JSQR_JSQ3_MSK (0x1f << ADC_JSQ3_LSB) -#define ADC_JSQR_JSQ2_MSK (0x1f << ADC_JSQ2_LSB) -#define ADC_JSQR_JSQ1_MSK (0x1f << ADC_JSQ1_LSB) -/* TODO Fix error + +/* JL[2:0]: Discontinous mode channel count injected channels. */ +/****************************************************************************/ +/** @defgroup adc_jsqr_jl ADC Number of channels in discontinuous mode fro injected channels. +@ingroup STM32F1xx_adc_defines + +@{*/ +#define ADC_JSQR_JL_1CHANNELS (0x0 << ADC_JSQR_JL_LSB) +#define ADC_JSQR_JL_2CHANNELS (0x1 << ADC_JSQR_JL_LSB) +#define ADC_JSQR_JL_3CHANNELS (0x2 << ADC_JSQR_JL_LSB) +#define ADC_JSQR_JL_4CHANNELS (0x3 << ADC_JSQR_JL_LSB) +/**@}*/ +#define ADC_JSQR_JL_SHIFT 13 #define ADC_JSQR_JL_MSK (0x2 << ADC_JSQR_JL_LSB) #define ADC_JSQR_JSQ4_MSK (0x1f << ADC_JSQR_JSQ4_LSB) #define ADC_JSQR_JSQ3_MSK (0x1f << ADC_JSQR_JSQ3_LSB) #define ADC_JSQR_JSQ2_MSK (0x1f << ADC_JSQR_JSQ2_LSB) #define ADC_JSQR_JSQ1_MSK (0x1f << ADC_JSQR_JSQ1_LSB) -*/ /* --- ADC_JDRx, ADC_DR values --------------------------------------------- */ @@ -679,22 +662,31 @@ LGPL License Terms @ref lgpl_license BEGIN_DECLS +void adc_power_on(u32 adc); +void adc_start_conversion_direct(u32 adc); +void adc_set_single_channel(u32 adc, u8 channel); +void adc_set_dual_mode(u32 mode); +bool adc_eoc(u32 adc); +bool adc_eoc_injected(u32 adc); +u32 adc_read_regular(u32 adc); +u32 adc_read_injected(u32 adc, u8 reg); +void adc_set_injected_offset(u32 adc, u8 reg, u32 offset); void adc_enable_analog_watchdog_regular(u32 adc); void adc_disable_analog_watchdog_regular(u32 adc); void adc_enable_analog_watchdog_injected(u32 adc); void adc_disable_analog_watchdog_injected(u32 adc); -void adc_enable_discontinous_mode_regular(u32 adc); -void adc_disable_discontinous_mode_regular(u32 adc); -void adc_enable_discontinous_mode_injected(u32 adc); -void adc_disable_discontinous_mode_injected(u32 adc); +void adc_enable_discontinuous_mode_regular(u32 adc, u8 length); +void adc_disable_discontinuous_mode_regular(u32 adc); +void adc_enable_discontinuous_mode_injected(u32 adc); +void adc_disable_discontinuous_mode_injected(u32 adc); void adc_enable_automatic_injected_group_conversion(u32 adc); void adc_disable_automatic_injected_group_conversion(u32 adc); void adc_enable_analog_watchdog_on_all_channels(u32 adc); void adc_enable_analog_watchdog_on_selected_channel(u32 adc, u8 channel); void adc_enable_scan_mode(u32 adc); void adc_disable_scan_mode(u32 adc); -void adc_enable_jeoc_interrupt(u32 adc); -void adc_disable_jeoc_interrupt(u32 adc); +void adc_enable_eoc_interrupt_injected(u32 adc); +void adc_disable_eoc_interrupt_injected(u32 adc); void adc_enable_awd_interrupt(u32 adc); void adc_disable_awd_interrupt(u32 adc); void adc_enable_eoc_interrupt(u32 adc); @@ -713,17 +705,28 @@ void adc_enable_dma(u32 adc); void adc_disable_dma(u32 adc); void adc_reset_calibration(u32 adc); void adc_calibration(u32 adc); -void adc_set_continous_conversion_mode(u32 adc); +void adc_set_continuous_conversion_mode(u32 adc); void adc_set_single_conversion_mode(u32 adc); +#ifdef __GNUC__ +void adc_on(u32 adc) __attribute__ ((deprecated ("will be removed in the first release"))); +#else void adc_on(u32 adc); +#endif void adc_off(u32 adc); -void adc_set_conversion_time(u32 adc, u8 channel, u8 time); -void adc_set_conversion_time_on_all_channels(u32 adc, u8 time); +void adc_set_sample_time(u32 adc, u8 channel, u8 time); +void adc_set_sample_time_on_all_channels(u32 adc, u8 time); void adc_set_watchdog_high_threshold(u32 adc, u16 threshold); void adc_set_watchdog_low_threshold(u32 adc, u16 threshold); void adc_set_regular_sequence(u32 adc, u8 length, u8 channel[]); void adc_set_injected_sequence(u32 adc, u8 length, u8 channel[]); +#ifdef __GNUC__ +void adc_set_continous_conversion_mode(u32 adc) __attribute__ ((deprecated ("change to adc_set_continuous_conversion_mode"))); +void adc_set_conversion_time(u32 adc, u8 channel, u8 time) __attribute__ ((deprecated ("change to adc_set_sample_time"))); +void adc_set_conversion_time_on_all_channels(u32 adc, u8 time) __attribute__ ((deprecated ("change to adc_set_sample_time_on_all_channels"))); +void adc_enable_jeoc_interrupt(u32 adc) __attribute__ ((deprecated ("change to adc_enable_eoc_interrupt_injected"))); +void adc_disable_jeoc_interrupt(u32 adc) __attribute__ ((deprecated ("change to adc_disable_eoc_interrupt_injected"))); +#endif END_DECLS #endif diff --git a/lib/stm32/f1/adc.c b/lib/stm32/f1/adc.c index 433cdd2..a8bb746 100644 --- a/lib/stm32/f1/adc.c +++ b/lib/stm32/f1/adc.c @@ -102,38 +102,156 @@ LGPL License Terms @ref lgpl_license #include -void rcc_set_adc_clk(u32 prescaler) +/*-----------------------------------------------------------------------------*/ +/** @brief ADC Power On + +If the ADC is in power-down mode then it is powered up. The application needs +to wait a time of about 3 microseconds for stabilization before using the ADC. +If the ADC is already on this function call has no effect. + +@param[in] adc Unsigned int32. ADC block register address base @ref adc_reg_base +*/ + +void adc_power_on(u32 adc) { - /* TODO */ + if (!(ADC_CR2(adc) & ADC_CR2_ADON)) + ADC_CR2(adc) |= ADC_CR2_ADON; +} + +/*-----------------------------------------------------------------------------*/ +/** @brief ADC Start a Conversion Without Trigger + +This initiates a conversion by software without a trigger. The ADC needs to be +powered on before this is called, otherwise this function has no effect. + +Note that this is not available in other STM32F families. To ensure code compatibility, +enable triggering and use a software trigger source @see adc_start_conversion_regular. - /* FIXME: QUICK HACK to prevent compiler warnings. */ - prescaler = prescaler; +@param[in] adc Unsigned int32. ADC block register address base @ref adc_reg_base +*/ + +void adc_start_conversion_direct(u32 adc) +{ + if (ADC_CR2(adc) & ADC_CR2_ADON) + ADC_CR2(adc) |= ADC_CR2_ADON; } -void adc_set_mode(u32 block, /* TODO */ u8 mode) +/*-----------------------------------------------------------------------------*/ +/** @brief ADC Set Dual A/D Mode + +The dual mode uses ADC1 as master and ADC2 in a slave arrangement. This setting +is applied to ADC1 only. Start of conversion when triggered can cause simultaneous +conversion with ADC2, or alternate conversion. Regular and injected conversions +can be configured, each one being separately simultaneous or alternate. + +@param[in] mode Unsigned int32. Dual mode selection from @ref adc_cr1_dualmod +*/ + +void adc_set_dual_mode(u32 mode) { - /* TODO */ + ADC1_CR1 |= mode; +} + +/*-----------------------------------------------------------------------------*/ +/** @brief ADC Read the End-of-Conversion Flag + +This flag is set after all channels of a regular or injected group have been +converted. - /* FIXME: QUICK HACK to prevent compiler warnings. */ - block = block; - mode = mode; +@param[in] adc Unsigned int32. ADC block register address base @ref adc_reg_base +@returns bool. End of conversion flag. +*/ + +bool adc_eoc(u32 adc) +{ + return ((ADC_SR(adc) & ADC_SR_EOC) != 0); } /*-----------------------------------------------------------------------------*/ -/** @brief ADC Read from a Conversion Result Register +/** @brief ADC Read the End-of-Conversion Flag for Injected Conversion + +This flag is set after all channels of an injected group have been converted. + +@param[in] adc Unsigned int32. ADC block register address base @ref adc_reg_base +@returns bool. End of conversion flag. +*/ + +bool adc_eoc_injected(u32 adc) +{ + return ((ADC_SR(adc) & ADC_SR_JEOC) != 0); +} + +/*-----------------------------------------------------------------------------*/ +/** @brief ADC Read from the Regular Conversion Result Register + +The result read back is 12 bits, right or left aligned within the first 16 bits. +For ADC1 only, the higher 16 bits will hold the result from ADC2 if +an appropriate dual mode has been set @see adc_set_dual_mode. + +@param[in] adc Unsigned int32. ADC block register address base @ref adc_reg_base +@returns Unsigned int32 conversion result. +*/ + +u32 adc_read_regular(u32 adc) +{ + return ADC_DR(adc); +} + +/*-----------------------------------------------------------------------------*/ +/** @brief ADC Read from an Injected Conversion Result Register + +The result read back from the selected injected result register (one of four) is +12 bits, right or left aligned within the first 16 bits. The result can have a +negative value if the injected channel offset has been set @see adc_set_injected_offset. @param[in] adc Unsigned int32. ADC block register address base @ref adc_reg_base @param[in] reg Unsigned int8. Register number (1 ... 4). @returns Unsigned int32 conversion result. */ -void adc_read(u32 block, u32 channel) +u32 adc_read_injected(u32 adc, u8 reg) { - /* TODO */ + switch (reg) { + case 1: + return ADC_JDR1(adc); + case 2: + return ADC_JDR2(adc); + case 3: + return ADC_JDR3(adc); + case 4: + return ADC_JDR4(adc); + } + return 0; +} - /* FIXME: QUICK HACK to prevent compiler warnings. */ - block = block; - channel = channel; +/*-----------------------------------------------------------------------------*/ +/** @brief ADC Set the Injected Channel Data Offset + +This value is subtracted from the injected channel results after conversion +is complete, and can result in negative results. A separate value can be specified +for each injected data register. + +@param[in] adc Unsigned int32. ADC block register address base @ref adc_reg_base +@param[in] reg Unsigned int8. Register number (1 ... 4). +@param[in] offset Unsigned int32. +*/ + +void adc_set_injected_offset(u32 adc, u8 reg, u32 offset) +{ + switch (reg) { + case 1: + ADC_JOFR1(adc) = offset; + break; + case 2: + ADC_JOFR2(adc) = offset; + break; + case 3: + ADC_JOFR3(adc) = offset; + break; + case 4: + ADC_JOFR4(adc) = offset; + break; + } } /*-----------------------------------------------------------------------------*/ @@ -203,9 +321,11 @@ of the subgroup at the beginning of the whole group. @param[in] length Unsigned int8. Number of channels in the group @ref adc_cr1_discnum */ -void adc_enable_discontinous_mode_regular(u32 adc) +void adc_enable_discontinuous_mode_regular(u32 adc, u8 length) { - ADC_CR1(adc) |= ADC_CR1_DISCEN; + if ( (length-1) > 7 ) return; + ADC_CR1(adc) |= ADC_CR1_DISCEN; + ADC_CR2(adc) |= ((length-1) << ADC_CR1_DISCNUM_SHIFT); } /*-----------------------------------------------------------------------------*/ @@ -214,7 +334,7 @@ void adc_enable_discontinous_mode_regular(u32 adc) @param[in] adc Unsigned int32. ADC block register address base @ref adc_reg_base */ -void adc_disable_discontinous_mode_regular(u32 adc) +void adc_disable_discontinuous_mode_regular(u32 adc) { ADC_CR1(adc) &= ~ADC_CR1_DISCEN; } @@ -229,7 +349,7 @@ entire group has been converted. @param[in] adc Unsigned int32. ADC block register address base @ref adc_reg_base */ -void adc_enable_discontinous_mode_injected(u32 adc) +void adc_enable_discontinuous_mode_injected(u32 adc) { ADC_CR1(adc) |= ADC_CR1_JDISCEN; } @@ -240,7 +360,7 @@ void adc_enable_discontinous_mode_injected(u32 adc) @param[in] adc Unsigned int32. ADC block register address base @ref adc_reg_base */ -void adc_disable_discontinous_mode_injected(u32 adc) +void adc_disable_discontinuous_mode_injected(u32 adc) { ADC_CR1(adc) &= ~ADC_CR1_JDISCEN; } @@ -257,6 +377,7 @@ channels is disabled as required. void adc_enable_automatic_injected_group_conversion(u32 adc) { + adc_disable_external_trigger_injected(adc); ADC_CR1(adc) |= ADC_CR1_JAUTO; } @@ -288,7 +409,7 @@ disabled. void adc_enable_analog_watchdog_on_all_channels(u32 adc) { - ADC_CR1(adc) |= ADC_CR1_AWDSGL; + ADC_CR1(adc) &= ~ADC_CR1_AWDSGL; } /*-----------------------------------------------------------------------------*/ @@ -315,7 +436,7 @@ void adc_enable_analog_watchdog_on_selected_channel(u32 adc, u8 channel) if (channel < 18) reg32 |= channel; ADC_CR1(adc) = reg32; - ADC_CR1(adc) &= ~ADC_CR1_AWDSGL; + ADC_CR1(adc) |= ADC_CR1_AWDSGL; } /*-----------------------------------------------------------------------------*/ @@ -350,7 +471,7 @@ void adc_disable_scan_mode(u32 adc) @param[in] adc Unsigned int32. ADC block register address base @ref adc_reg_base */ -void adc_enable_jeoc_interrupt(u32 adc) +void adc_enable_eoc_interrupt_injected(u32 adc) { ADC_CR1(adc) |= ADC_CR1_JEOCIE; } @@ -361,7 +482,7 @@ void adc_enable_jeoc_interrupt(u32 adc) @param[in] adc Unsigned int32. ADC block register address base @ref adc_reg_base */ -void adc_disable_jeoc_interrupt(u32 adc) +void adc_disable_eoc_interrupt_injected(u32 adc) { ADC_CR1(adc) &= ~ADC_CR1_JEOCIE; } @@ -519,8 +640,7 @@ void adc_enable_external_trigger_regular(u32 adc, u32 trigger) u32 reg32; reg32 = (ADC_CR2(adc) & ~(ADC_CR2_EXTSEL_MASK)); - if (trigger < 8) - reg32 |= (trigger); + reg32 |= (trigger); ADC_CR2(adc) = reg32; ADC_CR2(adc) |= ADC_CR2_EXTTRIG; } @@ -565,14 +685,12 @@ For ADC3 @param[in] trigger Unsigned int8. Trigger identifier @ref adc_trigger_injected_12 for ADC1 and ADC2, or @ref adc_trigger_injected_3 for ADC3 */ - void adc_enable_external_trigger_injected(u32 adc, u32 trigger) { u32 reg32; reg32 = (ADC_CR2(adc) & ~(ADC_CR2_JEXTSEL_MASK)); /* Clear bits [12:14]. */ - if (trigger < 8) - reg32 |= (trigger); + reg32 |= (trigger); ADC_CR2(adc) = reg32; ADC_CR2(adc) |= ADC_CR2_JEXTTRIG; } @@ -681,7 +799,7 @@ group immediately following completion of the previous channel group conversion. @param[in] adc Unsigned int32. ADC block register address base @ref adc_reg_base */ -void adc_set_continous_conversion_mode(u32 adc) +void adc_set_continuous_conversion_mode(u32 adc) { ADC_CR2(adc) |= ADC_CR2_CONT; } @@ -707,7 +825,7 @@ If the ADC is in power-down mode then it is powered up. The application needs to wait a time of about 3 microseconds for stabilization before using the ADC. If the ADC is already on this function call will initiate a conversion. -@todo fix this. +@deprecated to be removed in a later release @param[in] adc Unsigned int32. ADC block register address base @ref adc_reg_base */ @@ -740,7 +858,7 @@ The sampling time can be selected in ADC clock cycles from 1.5 to 239.5. @param[in] time Unsigned int8. Sampling time selection from @ref adc_sample_rg */ -void adc_set_conversion_time(u32 adc, u8 channel, u8 time) +void adc_set_sample_time(u32 adc, u8 channel, u8 time) { u32 reg32; @@ -767,7 +885,7 @@ all channels. @param[in] time Unsigned int8. Sampling time selection from @ref adc_sample_rg */ -void adc_set_conversion_time_on_all_channels(u32 adc, u8 time) +void adc_set_sample_time_on_all_channels(u32 adc, u8 time) { u8 i; u32 reg32 = 0; @@ -871,12 +989,24 @@ void adc_set_injected_sequence(u32 adc, u8 length, u8 channel[]) return; for (i = 1; i <= length; i++) - reg32 |= (channel[i - 1] << ((i - 1) * 5)); + reg32 |= (channel[4 - i] << ((4 - i) * 5)); reg32 |= ((length - 1) << ADC_JSQR_JL_LSB); ADC_JSQR(adc) = reg32; } +/*-----------------------------------------------------------------------------*/ + +/* Aliases */ + +#ifdef __GNUC__ +void adc_set_continous_conversion_mode(u32 adc) __attribute__ ((alias("adc_set_continuous_conversion_mode"))); +void adc_set_conversion_time(u32 adc, u8 channel, u8 time) __attribute__ ((alias ("adc_set_sample_time"))); +void adc_set_conversion_time_on_all_channels(u32 adc, u8 time) __attribute__ ((alias ("adc_set_sample_time_on_all_channels"))); +void adc_enable_jeoc_interrupt(u32 adc) __attribute__ ((alias ("adc_enable_eoc_interrupt_injected"))); +void adc_disable_jeoc_interrupt(u32 adc) __attribute__ ((alias ("adc_disable_eoc_interrupt_injected"))); +#endif + /**@}*/ -- cgit v1.2.3 From bece4c30d3b953cd7f469d9db06559ca443df189 Mon Sep 17 00:00:00 2001 From: Stephen Dwyer Date: Fri, 5 Oct 2012 11:40:21 -0600 Subject: added different ADC sampling examples for the LisaM v2 including: * simple polling of an injected channel * timer triggered sampling of an injected channel * timer triggered sampling and IRQ handling of an injected channel * timer triggered sampling and IRQ handling of 4 injected channels --- examples/stm32/f1/lisa-m-2/adc_injec/Makefile | 27 +++ examples/stm32/f1/lisa-m-2/adc_injec/README | 11 + examples/stm32/f1/lisa-m-2/adc_injec/adc_injec.c | 174 ++++++++++++++++ .../stm32/f1/lisa-m-2/adc_injec_timtrig/Makefile | 27 +++ .../stm32/f1/lisa-m-2/adc_injec_timtrig/README | 11 + .../lisa-m-2/adc_injec_timtrig/adc_injec_timtrig.c | 195 +++++++++++++++++ .../f1/lisa-m-2/adc_injec_timtrig_irq/Makefile | 27 +++ .../stm32/f1/lisa-m-2/adc_injec_timtrig_irq/README | 12 ++ .../adc_injec_timtrig_irq/adc_injec_timtrig_irq.c | 211 +++++++++++++++++++ .../f1/lisa-m-2/adc_injec_timtrig_irq_4ch/Makefile | 27 +++ .../f1/lisa-m-2/adc_injec_timtrig_irq_4ch/README | 12 ++ .../adc_injec_timtrig_irq_4ch.c | 230 +++++++++++++++++++++ 12 files changed, 964 insertions(+) create mode 100644 examples/stm32/f1/lisa-m-2/adc_injec/Makefile create mode 100644 examples/stm32/f1/lisa-m-2/adc_injec/README create mode 100644 examples/stm32/f1/lisa-m-2/adc_injec/adc_injec.c create mode 100644 examples/stm32/f1/lisa-m-2/adc_injec_timtrig/Makefile create mode 100644 examples/stm32/f1/lisa-m-2/adc_injec_timtrig/README create mode 100644 examples/stm32/f1/lisa-m-2/adc_injec_timtrig/adc_injec_timtrig.c create mode 100644 examples/stm32/f1/lisa-m-2/adc_injec_timtrig_irq/Makefile create mode 100644 examples/stm32/f1/lisa-m-2/adc_injec_timtrig_irq/README create mode 100644 examples/stm32/f1/lisa-m-2/adc_injec_timtrig_irq/adc_injec_timtrig_irq.c create mode 100644 examples/stm32/f1/lisa-m-2/adc_injec_timtrig_irq_4ch/Makefile create mode 100644 examples/stm32/f1/lisa-m-2/adc_injec_timtrig_irq_4ch/README create mode 100644 examples/stm32/f1/lisa-m-2/adc_injec_timtrig_irq_4ch/adc_injec_timtrig_irq_4ch.c (limited to 'examples') diff --git a/examples/stm32/f1/lisa-m-2/adc_injec/Makefile b/examples/stm32/f1/lisa-m-2/adc_injec/Makefile new file mode 100644 index 0000000..20355ce --- /dev/null +++ b/examples/stm32/f1/lisa-m-2/adc_injec/Makefile @@ -0,0 +1,27 @@ +## +## This file is part of the libopencm3 project. +## +## Copyright (C) 2009 Uwe Hermann +## +## 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 . +## + +BINARY = adc +# Comment the following line if you _don't_ have luftboot flashed! +LDFLAGS += -Wl,-Ttext=0x8002000 +CFLAGS += -std=c99 +LDSCRIPT = ../lisa-m.ld + +include ../../Makefile.include + diff --git a/examples/stm32/f1/lisa-m-2/adc_injec/README b/examples/stm32/f1/lisa-m-2/adc_injec/README new file mode 100644 index 0000000..f0c7d62 --- /dev/null +++ b/examples/stm32/f1/lisa-m-2/adc_injec/README @@ -0,0 +1,11 @@ +------------------------------------------------------------------------------ +README +------------------------------------------------------------------------------ + +This is a simple polling example that sends the value read out from the +temperature sensor ADC channel of the STM32 to the USART2. + +This example polls injected channels. + +The terminal settings for the receiving device/PC are 115200 8n1. + diff --git a/examples/stm32/f1/lisa-m-2/adc_injec/adc_injec.c b/examples/stm32/f1/lisa-m-2/adc_injec/adc_injec.c new file mode 100644 index 0000000..cba90f6 --- /dev/null +++ b/examples/stm32/f1/lisa-m-2/adc_injec/adc_injec.c @@ -0,0 +1,174 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2010 Thomas Otto + * Copyright (C) 2012 Piotr Esden-Tempski + * Copyright (C) 2012 Stephen Dwyer + * + * 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 . + */ + +#include +#include +#include +#include +#include + +void usart_setup(void) +{ + /* Enable clocks for GPIO port A (for GPIO_USART1_TX) and USART1. */ + rcc_peripheral_enable_clock(&RCC_APB2ENR, RCC_APB2ENR_IOPAEN); + rcc_peripheral_enable_clock(&RCC_APB1ENR, RCC_APB1ENR_USART2EN); + + /* Setup GPIO pin GPIO_USART1_TX/GPIO9 on GPIO port A for transmit. */ + gpio_set_mode(GPIOA, GPIO_MODE_OUTPUT_50_MHZ, + GPIO_CNF_OUTPUT_ALTFN_PUSHPULL, GPIO_USART2_TX); + + /* Setup UART parameters. */ + usart_set_baudrate(USART2, 115200); + usart_set_databits(USART2, 8); + usart_set_stopbits(USART2, USART_STOPBITS_1); + usart_set_mode(USART2, USART_MODE_TX_RX); + usart_set_parity(USART2, USART_PARITY_NONE); + usart_set_flow_control(USART2, USART_FLOWCONTROL_NONE); + + /* Finally enable the USART. */ + usart_enable(USART2); +} + +void gpio_setup(void) +{ + /* Enable GPIO clocks. */ + rcc_peripheral_enable_clock(&RCC_APB2ENR, RCC_APB2ENR_IOPAEN); + rcc_peripheral_enable_clock(&RCC_APB2ENR, RCC_APB2ENR_IOPCEN); + + /* Setup the LEDs. */ + gpio_set_mode(GPIOA, GPIO_MODE_OUTPUT_2_MHZ, + GPIO_CNF_OUTPUT_PUSHPULL, GPIO8); + gpio_set_mode(GPIOC, GPIO_MODE_OUTPUT_2_MHZ, + GPIO_CNF_OUTPUT_PUSHPULL, GPIO15); +} + +void adc_setup(void) +{ + int i; + + rcc_peripheral_enable_clock(&RCC_APB2ENR, RCC_APB2ENR_ADC1EN); + + /* Make sure the ADC doesn't run during config. */ + adc_off(ADC1); + + /* We configure everything for one single injected conversion. */ + adc_disable_scan_mode(ADC1); + adc_set_single_conversion_mode(ADC1); + /* We can only use discontinuous mode on either the regular OR injected channels, not both */ + adc_disable_discontinous_mode_regular(ADC1); + adc_enable_discontinous_mode_injected(ADC1); + /* We want to start the injected conversion in software */ + adc_enable_external_trigger_injected(ADC1,ADC_CR2_JEXTSEL_JSWSTART); + adc_set_right_aligned(ADC1); + /* We want to read the temperature sensor, so we have to enable it. */ + adc_enable_temperature_sensor(ADC1); + adc_set_conversion_time_on_all_channels(ADC1, ADC_SMPR_SMP_28DOT5CYC); + + adc_on(ADC1); + + /* Wait for ADC starting up. */ + for (i = 0; i < 800000; i++) /* Wait a bit. */ + __asm__("nop"); + + adc_reset_calibration(ADC1); + while ((ADC_CR2(ADC1) & ADC_CR2_RSTCAL) != 0); //added this check + adc_calibration(ADC1); + while ((ADC_CR2(ADC1) & ADC_CR2_CAL) != 0); //added this check +} + +void my_usart_print_int(u32 usart, int value) +{ + s8 i; + u8 nr_digits = 0; + char buffer[25]; + + if (value < 0) { + usart_send_blocking(usart, '-'); + value = value * -1; + } + + while (value > 0) { + buffer[nr_digits++] = "0123456789"[value % 10]; + value /= 10; + } + + for (i = (nr_digits - 1); i >= 0; i--) { + usart_send_blocking(usart, buffer[i]); + } + + usart_send_blocking(usart, '\r'); +} + +int main(void) +{ + u8 channel_array[16]; + u16 temperature = 0; + + rcc_clock_setup_in_hse_12mhz_out_72mhz(); + gpio_setup(); + usart_setup(); + adc_setup(); + + gpio_set(GPIOA, GPIO8); /* LED1 on */ + gpio_set(GPIOC, GPIO15); /* LED2 on */ + + /* Send a message on USART1. */ + usart_send_blocking(USART2, 's'); + usart_send_blocking(USART2, 't'); + usart_send_blocking(USART2, 'm'); + usart_send_blocking(USART2, '\r'); + usart_send_blocking(USART2, '\n'); + + /* Select the channel we want to convert. 16=temperature_sensor. */ + channel_array[0] = 16; + /* Set the injected sequence here, with number of channels */ + adc_set_injected_sequence(ADC1, 1, channel_array); + + /* Continously convert and poll the temperature ADC. */ + while (1) { + /* + * If the ADC_CR2_ON bit is already set -> setting it another time + * starts a regular conversion. Injected conversion is started + * explicitly with the JSWSTART bit as an external trigger. It may + * also work by setting no regular channels and setting JAUTO to + * automatically convert the injected channels after the regular + * channels (of which there would be none). (Not tested.) + */ + adc_start_conversion_injected(ADC1); + + /* Wait for end of conversion. */ + while (!(ADC_SR(ADC1) & ADC_SR_JEOC)); + ADC_SR(ADC2) &= ~ADC_SR_JEOC; //clear injected end of conversion + + temperature = ADC_JDR1(ADC1); //get the result from ADC_JDR1 on ADC1 (only bottom 16bits) + + /* + * That's actually not the real temperature - you have to compute it + * as described in the datasheet. + */ + my_usart_print_int(USART2, temperature); + + gpio_toggle(GPIOA, GPIO8); /* LED2 on */ + + } + + return 0; +} diff --git a/examples/stm32/f1/lisa-m-2/adc_injec_timtrig/Makefile b/examples/stm32/f1/lisa-m-2/adc_injec_timtrig/Makefile new file mode 100644 index 0000000..20355ce --- /dev/null +++ b/examples/stm32/f1/lisa-m-2/adc_injec_timtrig/Makefile @@ -0,0 +1,27 @@ +## +## This file is part of the libopencm3 project. +## +## Copyright (C) 2009 Uwe Hermann +## +## 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 . +## + +BINARY = adc +# Comment the following line if you _don't_ have luftboot flashed! +LDFLAGS += -Wl,-Ttext=0x8002000 +CFLAGS += -std=c99 +LDSCRIPT = ../lisa-m.ld + +include ../../Makefile.include + diff --git a/examples/stm32/f1/lisa-m-2/adc_injec_timtrig/README b/examples/stm32/f1/lisa-m-2/adc_injec_timtrig/README new file mode 100644 index 0000000..d690f8a --- /dev/null +++ b/examples/stm32/f1/lisa-m-2/adc_injec_timtrig/README @@ -0,0 +1,11 @@ +------------------------------------------------------------------------------ +README +------------------------------------------------------------------------------ + +This is a simple example that sends the value read out from the +temperature sensor ADC channel of the STM32 to the USART2. + +This example uses a timer trigger to automatically sample the adc channel. + +The terminal settings for the receiving device/PC are 115200 8n1. + diff --git a/examples/stm32/f1/lisa-m-2/adc_injec_timtrig/adc_injec_timtrig.c b/examples/stm32/f1/lisa-m-2/adc_injec_timtrig/adc_injec_timtrig.c new file mode 100644 index 0000000..cb9f15d --- /dev/null +++ b/examples/stm32/f1/lisa-m-2/adc_injec_timtrig/adc_injec_timtrig.c @@ -0,0 +1,195 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2010 Thomas Otto + * Copyright (C) 2012 Piotr Esden-Tempski + * Copyright (C) 2012 Stephen Dwyer + * + * 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 . + */ + +#include +#include +#include +#include +#include +#include + +void usart_setup(void) +{ + /* Enable clocks for GPIO port A (for GPIO_USART1_TX) and USART1. */ + rcc_peripheral_enable_clock(&RCC_APB2ENR, RCC_APB2ENR_IOPAEN); + rcc_peripheral_enable_clock(&RCC_APB1ENR, RCC_APB1ENR_USART2EN); + + /* Setup GPIO pin GPIO_USART1_TX/GPIO9 on GPIO port A for transmit. */ + gpio_set_mode(GPIOA, GPIO_MODE_OUTPUT_50_MHZ, + GPIO_CNF_OUTPUT_ALTFN_PUSHPULL, GPIO_USART2_TX); + + /* Setup UART parameters. */ + usart_set_baudrate(USART2, 115200); + usart_set_databits(USART2, 8); + usart_set_stopbits(USART2, USART_STOPBITS_1); + usart_set_mode(USART2, USART_MODE_TX_RX); + usart_set_parity(USART2, USART_PARITY_NONE); + usart_set_flow_control(USART2, USART_FLOWCONTROL_NONE); + + /* Finally enable the USART. */ + usart_enable(USART2); +} + +void gpio_setup(void) +{ + /* Enable GPIO clocks. */ + rcc_peripheral_enable_clock(&RCC_APB2ENR, RCC_APB2ENR_IOPAEN); + rcc_peripheral_enable_clock(&RCC_APB2ENR, RCC_APB2ENR_IOPCEN); + + /* Setup the LEDs. */ + gpio_set_mode(GPIOA, GPIO_MODE_OUTPUT_2_MHZ, + GPIO_CNF_OUTPUT_PUSHPULL, GPIO8); + gpio_set_mode(GPIOC, GPIO_MODE_OUTPUT_2_MHZ, + GPIO_CNF_OUTPUT_PUSHPULL, GPIO15); +} + +void timer_setup(void) +{ + /* Set up the timer TIM2 for injected sampling */ + uint32_t timer; + volatile uint32_t *rcc_apbenr; + uint32_t rcc_apb; + + timer = TIM2; + rcc_apbenr = &RCC_APB1ENR; + rcc_apb = RCC_APB1ENR_TIM2EN; + + rcc_peripheral_enable_clock(rcc_apbenr, rcc_apb); + + /* Time Base configuration */ + timer_reset(timer); + timer_set_mode(timer, TIM_CR1_CKD_CK_INT, + TIM_CR1_CMS_EDGE, TIM_CR1_DIR_UP); + timer_set_period(timer, 0xFF); + timer_set_prescaler(timer, 0x8); + timer_set_clock_division(timer, 0x0); + /* Generate TRGO on every update. */ + timer_set_master_mode(timer, TIM_CR2_MMS_UPDATE); + timer_enable_counter(timer); +} + +void adc_setup(void) +{ + int i; + + rcc_peripheral_enable_clock(&RCC_APB2ENR, RCC_APB2ENR_ADC1EN); + + /* Make sure the ADC doesn't run during config. */ + adc_off(ADC1); + + /* We configure everything for one single timer triggered injected conversion. */ + adc_disable_scan_mode(ADC1); + adc_set_single_conversion_mode(ADC1); + /* We can only use discontinuous mode on either the regular OR injected channels, not both */ + adc_disable_discontinous_mode_regular(ADC1); + adc_enable_discontinous_mode_injected(ADC1); + /* We want to start the injected conversion with the TIM2 TRGO */ + adc_enable_external_trigger_injected(ADC1,ADC_CR2_JEXTSEL_TIM2_TRGO); + adc_set_right_aligned(ADC1); + /* We want to read the temperature sensor, so we have to enable it. */ + adc_enable_temperature_sensor(ADC1); + adc_set_conversion_time_on_all_channels(ADC1, ADC_SMPR_SMP_28DOT5CYC); + + adc_on(ADC1); + + /* Wait for ADC starting up. */ + for (i = 0; i < 800000; i++) /* Wait a bit. */ + __asm__("nop"); + + adc_reset_calibration(ADC1); + while ((ADC_CR2(ADC1) & ADC_CR2_RSTCAL) != 0); + adc_calibration(ADC1); + while ((ADC_CR2(ADC1) & ADC_CR2_CAL) != 0); +} + +void my_usart_print_int(u32 usart, int value) +{ + s8 i; + u8 nr_digits = 0; + char buffer[25]; + + if (value < 0) { + usart_send_blocking(usart, '-'); + value = value * -1; + } + + while (value > 0) { + buffer[nr_digits++] = "0123456789"[value % 10]; + value /= 10; + } + + for (i = (nr_digits - 1); i >= 0; i--) { + usart_send_blocking(usart, buffer[i]); + } + + usart_send_blocking(usart, '\r'); +} + +int main(void) +{ + u8 channel_array[16]; + u16 temperature = 0; + + rcc_clock_setup_in_hse_12mhz_out_72mhz(); + gpio_setup(); + usart_setup(); + timer_setup(); + adc_setup(); + + gpio_set(GPIOA, GPIO8); /* LED1 on */ + gpio_set(GPIOC, GPIO15); /* LED2 on */ + + /* Send a message on USART1. */ + usart_send_blocking(USART2, 's'); + usart_send_blocking(USART2, 't'); + usart_send_blocking(USART2, 'm'); + usart_send_blocking(USART2, '\r'); + usart_send_blocking(USART2, '\n'); + + /* Select the channel we want to convert. 16=temperature_sensor. */ + channel_array[0] = 16; + /* Set the injected sequence here, with number of channels */ + adc_set_injected_sequence(ADC1, 1, channel_array); + + /* Continously convert and poll the temperature ADC. */ + while (1) { + /* + * Since the injected sampling is triggered by the timer, it gets + * updated automatically, we just need to periodically read out the value. + * It would be better to check if the JEOC bit is set, and clear it following + * so that you do not read the same value twice, especially for a slower + * sampling rate. + */ + + temperature = ADC_JDR1(ADC1); //get the result from ADC_JDR1 on ADC1 (only bottom 16bits) + + /* + * That's actually not the real temperature - you have to compute it + * as described in the datasheet. + */ + my_usart_print_int(USART2, temperature); + + gpio_toggle(GPIOA, GPIO8); /* LED2 on */ + + } + + return 0; +} diff --git a/examples/stm32/f1/lisa-m-2/adc_injec_timtrig_irq/Makefile b/examples/stm32/f1/lisa-m-2/adc_injec_timtrig_irq/Makefile new file mode 100644 index 0000000..20355ce --- /dev/null +++ b/examples/stm32/f1/lisa-m-2/adc_injec_timtrig_irq/Makefile @@ -0,0 +1,27 @@ +## +## This file is part of the libopencm3 project. +## +## Copyright (C) 2009 Uwe Hermann +## +## 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 . +## + +BINARY = adc +# Comment the following line if you _don't_ have luftboot flashed! +LDFLAGS += -Wl,-Ttext=0x8002000 +CFLAGS += -std=c99 +LDSCRIPT = ../lisa-m.ld + +include ../../Makefile.include + diff --git a/examples/stm32/f1/lisa-m-2/adc_injec_timtrig_irq/README b/examples/stm32/f1/lisa-m-2/adc_injec_timtrig_irq/README new file mode 100644 index 0000000..175edce --- /dev/null +++ b/examples/stm32/f1/lisa-m-2/adc_injec_timtrig_irq/README @@ -0,0 +1,12 @@ +------------------------------------------------------------------------------ +README +------------------------------------------------------------------------------ + +This is a simple example that sends the value read out from the +temperature sensor ADC channel of the STM32 to the USART2. + +This example uses a timer trigger to sample an injected adc channel and +then uses an interrupt routine to retrieve the sample from the data register. + +The terminal settings for the receiving device/PC are 115200 8n1. + diff --git a/examples/stm32/f1/lisa-m-2/adc_injec_timtrig_irq/adc_injec_timtrig_irq.c b/examples/stm32/f1/lisa-m-2/adc_injec_timtrig_irq/adc_injec_timtrig_irq.c new file mode 100644 index 0000000..73814d8 --- /dev/null +++ b/examples/stm32/f1/lisa-m-2/adc_injec_timtrig_irq/adc_injec_timtrig_irq.c @@ -0,0 +1,211 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2010 Thomas Otto + * Copyright (C) 2012 Piotr Esden-Tempski + * Copyright (C) 2012 Stephen Dwyer + * + * 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 . + */ + +#include +#include +#include +#include +#include +#include +#include + +volatile u16 temperature = 0; + +void usart_setup(void) +{ + /* Enable clocks for GPIO port A (for GPIO_USART1_TX) and USART1. */ + rcc_peripheral_enable_clock(&RCC_APB2ENR, RCC_APB2ENR_IOPAEN); + rcc_peripheral_enable_clock(&RCC_APB1ENR, RCC_APB1ENR_USART2EN); + + /* Setup GPIO pin GPIO_USART1_TX/GPIO9 on GPIO port A for transmit. */ + gpio_set_mode(GPIOA, GPIO_MODE_OUTPUT_50_MHZ, + GPIO_CNF_OUTPUT_ALTFN_PUSHPULL, GPIO_USART2_TX); + + /* Setup UART parameters. */ + usart_set_baudrate(USART2, 115200); + usart_set_databits(USART2, 8); + usart_set_stopbits(USART2, USART_STOPBITS_1); + usart_set_mode(USART2, USART_MODE_TX_RX); + usart_set_parity(USART2, USART_PARITY_NONE); + usart_set_flow_control(USART2, USART_FLOWCONTROL_NONE); + + /* Finally enable the USART. */ + usart_enable(USART2); +} + +void gpio_setup(void) +{ + /* Enable GPIO clocks. */ + rcc_peripheral_enable_clock(&RCC_APB2ENR, RCC_APB2ENR_IOPAEN); + rcc_peripheral_enable_clock(&RCC_APB2ENR, RCC_APB2ENR_IOPCEN); + + /* Setup the LEDs. */ + gpio_set_mode(GPIOA, GPIO_MODE_OUTPUT_2_MHZ, + GPIO_CNF_OUTPUT_PUSHPULL, GPIO8); + gpio_set_mode(GPIOC, GPIO_MODE_OUTPUT_2_MHZ, + GPIO_CNF_OUTPUT_PUSHPULL, GPIO15); +} + +void timer_setup(void) +{ + /* Set up the timer TIM2 for injected sampling */ + uint32_t timer; + volatile uint32_t *rcc_apbenr; + uint32_t rcc_apb; + + timer = TIM2; + rcc_apbenr = &RCC_APB1ENR; + rcc_apb = RCC_APB1ENR_TIM2EN; + + rcc_peripheral_enable_clock(rcc_apbenr, rcc_apb); + + /* Time Base configuration */ + timer_reset(timer); + timer_set_mode(timer, TIM_CR1_CKD_CK_INT, + TIM_CR1_CMS_EDGE, TIM_CR1_DIR_UP); + timer_set_period(timer, 0xFF); + timer_set_prescaler(timer, 0x8); + timer_set_clock_division(timer, 0x0); + /* Generate TRGO on every update. */ + timer_set_master_mode(timer, TIM_CR2_MMS_UPDATE); + timer_enable_counter(timer); +} + +void irq_setup(void) +{ + /* Enable the adc1_2_isr() routine */ + nvic_set_priority(NVIC_ADC1_2_IRQ, 0); + nvic_enable_irq(NVIC_ADC1_2_IRQ); +} + +void adc_setup(void) +{ + int i; + + rcc_peripheral_enable_clock(&RCC_APB2ENR, RCC_APB2ENR_ADC1EN); + + /* Make sure the ADC doesn't run during config. */ + adc_off(ADC1); + + /* We configure everything for one single timer triggered injected conversion with interrupt generation. */ + /* While not needed for a single channel, try out scan mode which does all channels in one sweep and + * generates the interrupt/EOC/JEOC flags set at the end of all channels, not each one. + */ + adc_enable_scan_mode(ADC1); + adc_set_single_conversion_mode(ADC1); + /* We want to start the injected conversion with the TIM2 TRGO */ + adc_enable_external_trigger_injected(ADC1,ADC_CR2_JEXTSEL_TIM2_TRGO); + /* Generate the ADC1_2_IRQ */ + adc_enable_jeoc_interrupt(ADC1); + adc_set_right_aligned(ADC1); + /* We want to read the temperature sensor, so we have to enable it. */ + adc_enable_temperature_sensor(ADC1); + adc_set_conversion_time_on_all_channels(ADC1, ADC_SMPR_SMP_28DOT5CYC); + + adc_on(ADC1); + + /* Wait for ADC starting up. */ + for (i = 0; i < 800000; i++) /* Wait a bit. */ + __asm__("nop"); + + adc_reset_calibration(ADC1); + while ((ADC_CR2(ADC1) & ADC_CR2_RSTCAL) != 0); + adc_calibration(ADC1); + while ((ADC_CR2(ADC1) & ADC_CR2_CAL) != 0); +} + +void my_usart_print_int(u32 usart, int value) +{ + s8 i; + u8 nr_digits = 0; + char buffer[25]; + + if (value < 0) { + usart_send_blocking(usart, '-'); + value = value * -1; + } + + while (value > 0) { + buffer[nr_digits++] = "0123456789"[value % 10]; + value /= 10; + } + + for (i = (nr_digits - 1); i >= 0; i--) { + usart_send_blocking(usart, buffer[i]); + } + + usart_send_blocking(usart, '\r'); +} + +int main(void) +{ + u8 channel_array[16]; + + rcc_clock_setup_in_hse_12mhz_out_72mhz(); + gpio_setup(); + usart_setup(); + timer_setup(); + irq_setup(); + adc_setup(); + + gpio_set(GPIOA, GPIO8); /* LED1 on */ + gpio_set(GPIOC, GPIO15); /* LED2 on */ + + /* Send a message on USART1. */ + usart_send_blocking(USART2, 's'); + usart_send_blocking(USART2, 't'); + usart_send_blocking(USART2, 'm'); + usart_send_blocking(USART2, '\r'); + usart_send_blocking(USART2, '\n'); + + /* Select the channel we want to convert. 16=temperature_sensor. */ + channel_array[0] = 16; + /* Set the injected sequence here, with number of channels */ + adc_set_injected_sequence(ADC1, 1, channel_array); + + /* Continously convert and poll the temperature ADC. */ + while (1) { + /* + * Since sampling is triggered by the timer and copying the value + * out of the data register is handled by the interrupt routine, + * we just need to print the value and toggle the LED. It may be useful + * to buffer the adc values in some cases. + */ + + /* + * That's actually not the real temperature - you have to compute it + * as described in the datasheet. + */ + my_usart_print_int(USART2, temperature); + + gpio_toggle(GPIOA, GPIO8); /* LED2 on */ + + } + + return 0; +} + +void adc1_2_isr(void) +{ + /* Clear Injected End Of Conversion (JEOC) */ + ADC_SR(ADC1) &= ~ADC_SR_JEOC; + temperature = ADC_JDR1(ADC1); +} diff --git a/examples/stm32/f1/lisa-m-2/adc_injec_timtrig_irq_4ch/Makefile b/examples/stm32/f1/lisa-m-2/adc_injec_timtrig_irq_4ch/Makefile new file mode 100644 index 0000000..20355ce --- /dev/null +++ b/examples/stm32/f1/lisa-m-2/adc_injec_timtrig_irq_4ch/Makefile @@ -0,0 +1,27 @@ +## +## This file is part of the libopencm3 project. +## +## Copyright (C) 2009 Uwe Hermann +## +## 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 . +## + +BINARY = adc +# Comment the following line if you _don't_ have luftboot flashed! +LDFLAGS += -Wl,-Ttext=0x8002000 +CFLAGS += -std=c99 +LDSCRIPT = ../lisa-m.ld + +include ../../Makefile.include + diff --git a/examples/stm32/f1/lisa-m-2/adc_injec_timtrig_irq_4ch/README b/examples/stm32/f1/lisa-m-2/adc_injec_timtrig_irq_4ch/README new file mode 100644 index 0000000..0339a11 --- /dev/null +++ b/examples/stm32/f1/lisa-m-2/adc_injec_timtrig_irq_4ch/README @@ -0,0 +1,12 @@ +------------------------------------------------------------------------------ +README +------------------------------------------------------------------------------ + +This is a simple example that sends the values read out from four ADC +channels of the STM32 to the USART2. + +This example uses a timer trigger to sample the injected adc channels and +then uses an interrupt routine to retrieve the samples from the data registers. + +The terminal settings for the receiving device/PC are 115200 8n1. + diff --git a/examples/stm32/f1/lisa-m-2/adc_injec_timtrig_irq_4ch/adc_injec_timtrig_irq_4ch.c b/examples/stm32/f1/lisa-m-2/adc_injec_timtrig_irq_4ch/adc_injec_timtrig_irq_4ch.c new file mode 100644 index 0000000..9331bb9 --- /dev/null +++ b/examples/stm32/f1/lisa-m-2/adc_injec_timtrig_irq_4ch/adc_injec_timtrig_irq_4ch.c @@ -0,0 +1,230 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2010 Thomas Otto + * Copyright (C) 2012 Piotr Esden-Tempski + * Copyright (C) 2012 Stephen Dwyer + * + * 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 . + */ + +#include +#include +#include +#include +#include +#include +#include + +volatile u16 temperature = 0; +volatile u16 v_refint = 0; +volatile u16 lisam_adc1 = 0; +volatile u16 lisam_adc2 = 0; +u8 channel_array[4]; /* for injected sampling, 4 channels max, for regular, 16 max */ + +void usart_setup(void) +{ + /* Enable clocks for GPIO port A (for GPIO_USART1_TX) and USART1. */ + rcc_peripheral_enable_clock(&RCC_APB2ENR, RCC_APB2ENR_IOPAEN); + rcc_peripheral_enable_clock(&RCC_APB1ENR, RCC_APB1ENR_USART2EN); + + /* Setup GPIO pin GPIO_USART1_TX/GPIO9 on GPIO port A for transmit. */ + gpio_set_mode(GPIOA, GPIO_MODE_OUTPUT_50_MHZ, + GPIO_CNF_OUTPUT_ALTFN_PUSHPULL, GPIO_USART2_TX); + + /* Setup UART parameters. */ + usart_set_baudrate(USART2, 115200); + usart_set_databits(USART2, 8); + usart_set_stopbits(USART2, USART_STOPBITS_1); + usart_set_mode(USART2, USART_MODE_TX_RX); + usart_set_parity(USART2, USART_PARITY_NONE); + usart_set_flow_control(USART2, USART_FLOWCONTROL_NONE); + + /* Finally enable the USART. */ + usart_enable(USART2); +} + +void gpio_setup(void) +{ + /* Enable GPIO clocks. */ + rcc_peripheral_enable_clock(&RCC_APB2ENR, RCC_APB2ENR_IOPAEN); + rcc_peripheral_enable_clock(&RCC_APB2ENR, RCC_APB2ENR_IOPCEN); + + /* Setup the LEDs. */ + gpio_set_mode(GPIOA, GPIO_MODE_OUTPUT_2_MHZ, + GPIO_CNF_OUTPUT_PUSHPULL, GPIO8); + gpio_set_mode(GPIOC, GPIO_MODE_OUTPUT_2_MHZ, + GPIO_CNF_OUTPUT_PUSHPULL, GPIO15); + + /* Setup Lisa/M v2 ADC1,2 on ANALOG1 connector */ + gpio_set_mode(GPIOC, GPIO_MODE_INPUT, GPIO_CNF_INPUT_ANALOG, \ + GPIO3 | GPIO0 ); +} + +void timer_setup(void) +{ + /* Set up the timer TIM2 for injected sampling */ + uint32_t timer; + volatile uint32_t *rcc_apbenr; + uint32_t rcc_apb; + + timer = TIM2; + rcc_apbenr = &RCC_APB1ENR; + rcc_apb = RCC_APB1ENR_TIM2EN; + + rcc_peripheral_enable_clock(rcc_apbenr, rcc_apb); + + /* Time Base configuration */ + timer_reset(timer); + timer_set_mode(timer, TIM_CR1_CKD_CK_INT, + TIM_CR1_CMS_EDGE, TIM_CR1_DIR_UP); + timer_set_period(timer, 0xFF); + timer_set_prescaler(timer, 0x8); + timer_set_clock_division(timer, 0x0); + /* Generate TRGO on every update. */ + timer_set_master_mode(timer, TIM_CR2_MMS_UPDATE); + timer_enable_counter(timer); +} + +void irq_setup(void) +{ + /* Enable the adc1_2_isr() routine */ + nvic_set_priority(NVIC_ADC1_2_IRQ, 0); + nvic_enable_irq(NVIC_ADC1_2_IRQ); +} + +void adc_setup(void) +{ + int i; + + rcc_peripheral_enable_clock(&RCC_APB2ENR, RCC_APB2ENR_ADC1EN); + + /* Make sure the ADC doesn't run during config. */ + adc_off(ADC1); + + /* We configure everything for one single timer triggered injected conversion with interrupt generation. */ + /* While not needed for a single channel, try out scan mode which does all channels in one sweep and + * generates the interrupt/EOC/JEOC flags set at the end of all channels, not each one. + */ + adc_enable_scan_mode(ADC1); + adc_set_single_conversion_mode(ADC1); + /* We want to start the injected conversion with the TIM2 TRGO */ + adc_enable_external_trigger_injected(ADC1,ADC_CR2_JEXTSEL_TIM2_TRGO); + /* Generate the ADC1_2_IRQ */ + adc_enable_jeoc_interrupt(ADC1); + adc_set_right_aligned(ADC1); + /* We want to read the temperature sensor, so we have to enable it. */ + adc_enable_temperature_sensor(ADC1); + adc_set_conversion_time_on_all_channels(ADC1, ADC_SMPR_SMP_28DOT5CYC); + + /* Select the channels we want to convert. + * 16=temperature_sensor, 17=Vrefint, 13=ADC1, 10=ADC2 + */ + channel_array[0] = 16; + channel_array[1] = 17; + channel_array[2] = 13; + channel_array[3] = 10; + adc_set_injected_sequence(ADC1, 4, channel_array); + + adc_on(ADC1); + + /* Wait for ADC starting up. */ + for (i = 0; i < 800000; i++) /* Wait a bit. */ + __asm__("nop"); + + adc_reset_calibration(ADC1); + while ((ADC_CR2(ADC1) & ADC_CR2_RSTCAL) != 0); //added this check + adc_calibration(ADC1); + while ((ADC_CR2(ADC1) & ADC_CR2_CAL) != 0); //added this check +} + +void my_usart_print_int(u32 usart, int value) +{ + s8 i; + u8 nr_digits = 0; + char buffer[25]; + + if (value < 0) { + usart_send_blocking(usart, '-'); + value = value * -1; + } + + while (value > 0) { + buffer[nr_digits++] = "0123456789"[value % 10]; + value /= 10; + } + + for (i = (nr_digits - 1); i >= 0; i--) { + usart_send_blocking(usart, buffer[i]); + } + + //usart_send_blocking(usart, '\r'); +} + +int main(void) +{ + + rcc_clock_setup_in_hse_12mhz_out_72mhz(); + gpio_setup(); + usart_setup(); + timer_setup(); + irq_setup(); + adc_setup(); + + gpio_set(GPIOA, GPIO8); /* LED1 off */ + gpio_set(GPIOC, GPIO15); /* LED5 off */ + + /* Send a message on USART1. */ + usart_send_blocking(USART2, 's'); + usart_send_blocking(USART2, 't'); + usart_send_blocking(USART2, 'm'); + usart_send_blocking(USART2, '\r'); + usart_send_blocking(USART2, '\n'); + + /* Moved the channel selection and sequence init to adc_setup() */ + + /* Continously convert and poll the temperature ADC. */ + while (1) { + /* + * Since sampling is triggered by the timer and copying the values + * out of the data registers is handled by the interrupt routine, + * we just need to print the values and toggle the LED. It may be useful + * to buffer the adc values in some cases. + */ + + my_usart_print_int(USART2, temperature); + usart_send_blocking(USART2, ' '); + my_usart_print_int(USART2, v_refint); + usart_send_blocking(USART2, ' '); + my_usart_print_int(USART2, lisam_adc1); + usart_send_blocking(USART2, ' '); + my_usart_print_int(USART2, lisam_adc2); + usart_send_blocking(USART2, '\r'); + + gpio_toggle(GPIOA, GPIO8); /* LED2 on */ + + } + + return 0; +} + +void adc1_2_isr(void) +{ + /* Clear Injected End Of Conversion (JEOC) */ + ADC_SR(ADC1) &= ~ADC_SR_JEOC; + temperature = ADC_JDR1(ADC1); + v_refint = ADC_JDR2(ADC1); + lisam_adc1 = ADC_JDR3(ADC1); + lisam_adc2 = ADC_JDR4(ADC1); +} -- cgit v1.2.3 From 794f3fbeda3ec1dc7de1b9023eef44e4169a7ea1 Mon Sep 17 00:00:00 2001 From: Stephen Dwyer Date: Fri, 5 Oct 2012 11:47:33 -0600 Subject: oops, had to update bin names in makefiles for adc examples --- examples/stm32/f1/lisa-m-2/adc_injec/Makefile | 2 +- examples/stm32/f1/lisa-m-2/adc_injec_timtrig/Makefile | 2 +- examples/stm32/f1/lisa-m-2/adc_injec_timtrig_irq/Makefile | 2 +- examples/stm32/f1/lisa-m-2/adc_injec_timtrig_irq_4ch/Makefile | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) (limited to 'examples') diff --git a/examples/stm32/f1/lisa-m-2/adc_injec/Makefile b/examples/stm32/f1/lisa-m-2/adc_injec/Makefile index 20355ce..e50737b 100644 --- a/examples/stm32/f1/lisa-m-2/adc_injec/Makefile +++ b/examples/stm32/f1/lisa-m-2/adc_injec/Makefile @@ -17,7 +17,7 @@ ## along with this library. If not, see . ## -BINARY = adc +BINARY = adc_injec # Comment the following line if you _don't_ have luftboot flashed! LDFLAGS += -Wl,-Ttext=0x8002000 CFLAGS += -std=c99 diff --git a/examples/stm32/f1/lisa-m-2/adc_injec_timtrig/Makefile b/examples/stm32/f1/lisa-m-2/adc_injec_timtrig/Makefile index 20355ce..af2e9e6 100644 --- a/examples/stm32/f1/lisa-m-2/adc_injec_timtrig/Makefile +++ b/examples/stm32/f1/lisa-m-2/adc_injec_timtrig/Makefile @@ -17,7 +17,7 @@ ## along with this library. If not, see . ## -BINARY = adc +BINARY = adc_injec_timtrig # Comment the following line if you _don't_ have luftboot flashed! LDFLAGS += -Wl,-Ttext=0x8002000 CFLAGS += -std=c99 diff --git a/examples/stm32/f1/lisa-m-2/adc_injec_timtrig_irq/Makefile b/examples/stm32/f1/lisa-m-2/adc_injec_timtrig_irq/Makefile index 20355ce..c88152e 100644 --- a/examples/stm32/f1/lisa-m-2/adc_injec_timtrig_irq/Makefile +++ b/examples/stm32/f1/lisa-m-2/adc_injec_timtrig_irq/Makefile @@ -17,7 +17,7 @@ ## along with this library. If not, see . ## -BINARY = adc +BINARY = adc_injec_timtrig_irq # Comment the following line if you _don't_ have luftboot flashed! LDFLAGS += -Wl,-Ttext=0x8002000 CFLAGS += -std=c99 diff --git a/examples/stm32/f1/lisa-m-2/adc_injec_timtrig_irq_4ch/Makefile b/examples/stm32/f1/lisa-m-2/adc_injec_timtrig_irq_4ch/Makefile index 20355ce..d9a74a2 100644 --- a/examples/stm32/f1/lisa-m-2/adc_injec_timtrig_irq_4ch/Makefile +++ b/examples/stm32/f1/lisa-m-2/adc_injec_timtrig_irq_4ch/Makefile @@ -17,7 +17,7 @@ ## along with this library. If not, see . ## -BINARY = adc +BINARY = adc_injec_timtrig_irq_4ch # Comment the following line if you _don't_ have luftboot flashed! LDFLAGS += -Wl,-Ttext=0x8002000 CFLAGS += -std=c99 -- cgit v1.2.3 From 2b8fbfc433fe75efaa323d0b085e6d54a1221975 Mon Sep 17 00:00:00 2001 From: Stephen Dwyer Date: Sun, 7 Oct 2012 17:53:09 -0600 Subject: updated the lisa_m_2 (STM32 F1) ADC examples for recent code changes to stm32f1 adc.c and adc.h --- examples/stm32/f1/lisa-m-2/adc_injec/adc_injec.c | 12 ++++++------ .../f1/lisa-m-2/adc_injec_timtrig/adc_injec_timtrig.c | 10 +++++----- .../lisa-m-2/adc_injec_timtrig_irq/adc_injec_timtrig_irq.c | 8 ++++---- .../adc_injec_timtrig_irq_4ch/adc_injec_timtrig_irq_4ch.c | 14 +++++++------- examples/stm32/f1/lisa-m-2/adc_regular/adc.c | 4 ++-- 5 files changed, 24 insertions(+), 24 deletions(-) (limited to 'examples') diff --git a/examples/stm32/f1/lisa-m-2/adc_injec/adc_injec.c b/examples/stm32/f1/lisa-m-2/adc_injec/adc_injec.c index cba90f6..eab7887 100644 --- a/examples/stm32/f1/lisa-m-2/adc_injec/adc_injec.c +++ b/examples/stm32/f1/lisa-m-2/adc_injec/adc_injec.c @@ -73,16 +73,16 @@ void adc_setup(void) adc_disable_scan_mode(ADC1); adc_set_single_conversion_mode(ADC1); /* We can only use discontinuous mode on either the regular OR injected channels, not both */ - adc_disable_discontinous_mode_regular(ADC1); - adc_enable_discontinous_mode_injected(ADC1); + adc_disable_discontinuous_mode_regular(ADC1); + adc_enable_discontinuous_mode_injected(ADC1); /* We want to start the injected conversion in software */ adc_enable_external_trigger_injected(ADC1,ADC_CR2_JEXTSEL_JSWSTART); adc_set_right_aligned(ADC1); /* We want to read the temperature sensor, so we have to enable it. */ adc_enable_temperature_sensor(ADC1); - adc_set_conversion_time_on_all_channels(ADC1, ADC_SMPR_SMP_28DOT5CYC); + adc_set_sample_time_on_all_channels(ADC1, ADC_SMPR_SMP_28DOT5CYC); - adc_on(ADC1); + adc_power_on(ADC1); /* Wait for ADC starting up. */ for (i = 0; i < 800000; i++) /* Wait a bit. */ @@ -155,10 +155,10 @@ int main(void) adc_start_conversion_injected(ADC1); /* Wait for end of conversion. */ - while (!(ADC_SR(ADC1) & ADC_SR_JEOC)); + while (!(adc_eoc_injected(ADC1))); ADC_SR(ADC2) &= ~ADC_SR_JEOC; //clear injected end of conversion - temperature = ADC_JDR1(ADC1); //get the result from ADC_JDR1 on ADC1 (only bottom 16bits) + temperature = adc_read_injected(ADC1,1); //get the result from ADC_JDR1 on ADC1 (only bottom 16bits) /* * That's actually not the real temperature - you have to compute it diff --git a/examples/stm32/f1/lisa-m-2/adc_injec_timtrig/adc_injec_timtrig.c b/examples/stm32/f1/lisa-m-2/adc_injec_timtrig/adc_injec_timtrig.c index cb9f15d..d675723 100644 --- a/examples/stm32/f1/lisa-m-2/adc_injec_timtrig/adc_injec_timtrig.c +++ b/examples/stm32/f1/lisa-m-2/adc_injec_timtrig/adc_injec_timtrig.c @@ -99,16 +99,16 @@ void adc_setup(void) adc_disable_scan_mode(ADC1); adc_set_single_conversion_mode(ADC1); /* We can only use discontinuous mode on either the regular OR injected channels, not both */ - adc_disable_discontinous_mode_regular(ADC1); - adc_enable_discontinous_mode_injected(ADC1); + adc_disable_discontinuous_mode_regular(ADC1); + adc_enable_discontinuous_mode_injected(ADC1); /* We want to start the injected conversion with the TIM2 TRGO */ adc_enable_external_trigger_injected(ADC1,ADC_CR2_JEXTSEL_TIM2_TRGO); adc_set_right_aligned(ADC1); /* We want to read the temperature sensor, so we have to enable it. */ adc_enable_temperature_sensor(ADC1); - adc_set_conversion_time_on_all_channels(ADC1, ADC_SMPR_SMP_28DOT5CYC); + adc_set_sample_time_on_all_channels(ADC1, ADC_SMPR_SMP_28DOT5CYC); - adc_on(ADC1); + adc_power_on(ADC1); /* Wait for ADC starting up. */ for (i = 0; i < 800000; i++) /* Wait a bit. */ @@ -179,7 +179,7 @@ int main(void) * sampling rate. */ - temperature = ADC_JDR1(ADC1); //get the result from ADC_JDR1 on ADC1 (only bottom 16bits) + temperature = adc_read_injected(ADC1,1); //get the result from ADC_JDR1 on ADC1 (only bottom 16bits) /* * That's actually not the real temperature - you have to compute it diff --git a/examples/stm32/f1/lisa-m-2/adc_injec_timtrig_irq/adc_injec_timtrig_irq.c b/examples/stm32/f1/lisa-m-2/adc_injec_timtrig_irq/adc_injec_timtrig_irq.c index 73814d8..bda1d9d 100644 --- a/examples/stm32/f1/lisa-m-2/adc_injec_timtrig_irq/adc_injec_timtrig_irq.c +++ b/examples/stm32/f1/lisa-m-2/adc_injec_timtrig_irq/adc_injec_timtrig_irq.c @@ -114,13 +114,13 @@ void adc_setup(void) /* We want to start the injected conversion with the TIM2 TRGO */ adc_enable_external_trigger_injected(ADC1,ADC_CR2_JEXTSEL_TIM2_TRGO); /* Generate the ADC1_2_IRQ */ - adc_enable_jeoc_interrupt(ADC1); + adc_enable_eoc_interrupt_injected(ADC1); adc_set_right_aligned(ADC1); /* We want to read the temperature sensor, so we have to enable it. */ adc_enable_temperature_sensor(ADC1); - adc_set_conversion_time_on_all_channels(ADC1, ADC_SMPR_SMP_28DOT5CYC); + adc_set_sample_time_on_all_channels(ADC1, ADC_SMPR_SMP_28DOT5CYC); - adc_on(ADC1); + adc_power_on(ADC1); /* Wait for ADC starting up. */ for (i = 0; i < 800000; i++) /* Wait a bit. */ @@ -207,5 +207,5 @@ void adc1_2_isr(void) { /* Clear Injected End Of Conversion (JEOC) */ ADC_SR(ADC1) &= ~ADC_SR_JEOC; - temperature = ADC_JDR1(ADC1); + temperature = adc_read_injected(ADC1,1); } diff --git a/examples/stm32/f1/lisa-m-2/adc_injec_timtrig_irq_4ch/adc_injec_timtrig_irq_4ch.c b/examples/stm32/f1/lisa-m-2/adc_injec_timtrig_irq_4ch/adc_injec_timtrig_irq_4ch.c index 9331bb9..1334184 100644 --- a/examples/stm32/f1/lisa-m-2/adc_injec_timtrig_irq_4ch/adc_injec_timtrig_irq_4ch.c +++ b/examples/stm32/f1/lisa-m-2/adc_injec_timtrig_irq_4ch/adc_injec_timtrig_irq_4ch.c @@ -122,11 +122,11 @@ void adc_setup(void) /* We want to start the injected conversion with the TIM2 TRGO */ adc_enable_external_trigger_injected(ADC1,ADC_CR2_JEXTSEL_TIM2_TRGO); /* Generate the ADC1_2_IRQ */ - adc_enable_jeoc_interrupt(ADC1); + adc_enable_eoc_interrupt_injected(ADC1); adc_set_right_aligned(ADC1); /* We want to read the temperature sensor, so we have to enable it. */ adc_enable_temperature_sensor(ADC1); - adc_set_conversion_time_on_all_channels(ADC1, ADC_SMPR_SMP_28DOT5CYC); + adc_set_sample_time_on_all_channels(ADC1, ADC_SMPR_SMP_28DOT5CYC); /* Select the channels we want to convert. * 16=temperature_sensor, 17=Vrefint, 13=ADC1, 10=ADC2 @@ -137,7 +137,7 @@ void adc_setup(void) channel_array[3] = 10; adc_set_injected_sequence(ADC1, 4, channel_array); - adc_on(ADC1); + adc_power_on(ADC1); /* Wait for ADC starting up. */ for (i = 0; i < 800000; i++) /* Wait a bit. */ @@ -223,8 +223,8 @@ void adc1_2_isr(void) { /* Clear Injected End Of Conversion (JEOC) */ ADC_SR(ADC1) &= ~ADC_SR_JEOC; - temperature = ADC_JDR1(ADC1); - v_refint = ADC_JDR2(ADC1); - lisam_adc1 = ADC_JDR3(ADC1); - lisam_adc2 = ADC_JDR4(ADC1); + temperature = adc_read_injected(ADC1,1); + v_refint = adc_read_injected(ADC1,2); + lisam_adc1 = adc_read_injected(ADC1,3); + lisam_adc2 = adc_read_injected(ADC1,4); } diff --git a/examples/stm32/f1/lisa-m-2/adc_regular/adc.c b/examples/stm32/f1/lisa-m-2/adc_regular/adc.c index f6442b1..9bbbe03 100644 --- a/examples/stm32/f1/lisa-m-2/adc_regular/adc.c +++ b/examples/stm32/f1/lisa-m-2/adc_regular/adc.c @@ -143,9 +143,9 @@ int main(void) adc_start_conversion_direct(ADC1); /* Wait for end of conversion. */ - while (!(ADC_SR(ADC1) & ADC_SR_EOC)); + while (!(adc_eoc(ADC1))); - temperature = ADC_DR(ADC1); + temperature = adc_read_regular(ADC1); /* * That's actually not the real temperature - you have to compute it -- cgit v1.2.3 From b7ebe6e705b42030a4a6ff0002b7542464917e38 Mon Sep 17 00:00:00 2001 From: Felix Ruess Date: Sat, 13 Oct 2012 15:35:19 +0200 Subject: fix clean target for example makefiles if the compiler is not in PATH --- Makefile | 2 +- examples/lm3s/Makefile.include | 6 +++++- examples/lpc13xx/Makefile.include | 6 +++++- examples/lpc17xx/Makefile.include | 6 +++++- examples/lpc43xx/Makefile.include | 6 +++++- examples/stm32/f1/Makefile.include | 8 ++++++-- examples/stm32/f2/Makefile.include | 6 +++++- examples/stm32/f4/Makefile.include | 6 +++++- 8 files changed, 37 insertions(+), 9 deletions(-) (limited to 'examples') diff --git a/Makefile b/Makefile index 37c0c40..492b618 100644 --- a/Makefile +++ b/Makefile @@ -26,7 +26,7 @@ SHAREDIR = $(DESTDIR)/$(PREFIX)/share/libopencm3/scripts INSTALL = install SRCLIBDIR = $(shell pwd)/lib -TARGETS = stm32/f1 stm32/f2 stm32/f4 lpc13xx lpc17xx lpc43xx lm3s +TARGETS = stm32/f1 stm32/f2 stm32/f4 lpc13xx lpc17xx lpc43xx lm3s # Be silent per default, but 'make V=1' will show all compiler calls. ifneq ($(V),1) diff --git a/examples/lm3s/Makefile.include b/examples/lm3s/Makefile.include index 0e18bd6..f519063 100644 --- a/examples/lm3s/Makefile.include +++ b/examples/lm3s/Makefile.include @@ -24,14 +24,18 @@ CC = $(PREFIX)-gcc LD = $(PREFIX)-gcc OBJCOPY = $(PREFIX)-objcopy OBJDUMP = $(PREFIX)-objdump + +TOOLCHAIN_DIR ?= ../../../.. ifeq ($(wildcard ../../../../lib/libopencm3_lm3s.a),) +ifneq ($(strip $(shell which $(CC))),) TOOLCHAIN_DIR := $(shell dirname `which $(CC)`)/../$(PREFIX) +endif else ifeq ($(V),1) $(info We seem to be building the example in the source directory. Using local library!) endif -TOOLCHAIN_DIR := ../../../.. endif + CFLAGS += -O0 -g3 -Wall -Wextra -I$(TOOLCHAIN_DIR)/include -fno-common \ -mcpu=cortex-m3 -mthumb -MD LDSCRIPT ?= $(BINARY).ld diff --git a/examples/lpc13xx/Makefile.include b/examples/lpc13xx/Makefile.include index cc668f8..d8aeff0 100644 --- a/examples/lpc13xx/Makefile.include +++ b/examples/lpc13xx/Makefile.include @@ -24,14 +24,18 @@ CC = $(PREFIX)-gcc LD = $(PREFIX)-gcc OBJCOPY = $(PREFIX)-objcopy OBJDUMP = $(PREFIX)-objdump + +TOOLCHAIN_DIR ?= ../../../.. ifeq ($(wildcard ../../../../lib/libopencm3_lpc13xx.a),) +ifneq ($(strip $(shell which $(CC))),) TOOLCHAIN_DIR := $(shell dirname `which $(CC)`)/../$(PREFIX) +endif else ifeq ($(V),1) $(info We seem to be building the example in the source directory. Using local library!) endif -TOOLCHAIN_DIR := ../../../.. endif + CFLAGS += -Os -g -Wall -Wextra -I$(TOOLCHAIN_DIR)/include -fno-common \ -mcpu=cortex-m3 -mthumb -MD LDSCRIPT ?= $(BINARY).ld diff --git a/examples/lpc17xx/Makefile.include b/examples/lpc17xx/Makefile.include index 66688d3..6d7bbfe 100644 --- a/examples/lpc17xx/Makefile.include +++ b/examples/lpc17xx/Makefile.include @@ -24,14 +24,18 @@ CC = $(PREFIX)-gcc LD = $(PREFIX)-gcc OBJCOPY = $(PREFIX)-objcopy OBJDUMP = $(PREFIX)-objdump + +TOOLCHAIN_DIR ?= ../../../.. ifeq ($(wildcard ../../../../lib/libopencm3_lpc17xx.a),) +ifneq ($(strip $(shell which $(CC))),) TOOLCHAIN_DIR := $(shell dirname `which $(CC)`)/../$(PREFIX) +endif else ifeq ($(V),1) $(info We seem to be building the example in the source directory. Using local library!) endif -TOOLCHAIN_DIR := ../../../.. endif + CFLAGS += -O0 -g -Wall -Wextra -I$(TOOLCHAIN_DIR)/include -fno-common \ -mcpu=cortex-m3 -mthumb -MD LDSCRIPT ?= $(BINARY).ld diff --git a/examples/lpc43xx/Makefile.include b/examples/lpc43xx/Makefile.include index 4b1a092..15e523b 100644 --- a/examples/lpc43xx/Makefile.include +++ b/examples/lpc43xx/Makefile.include @@ -27,14 +27,18 @@ LD = $(PREFIX)-gcc OBJCOPY = $(PREFIX)-objcopy OBJDUMP = $(PREFIX)-objdump GDB = $(PREFIX)-gdb + +TOOLCHAIN_DIR ?= ../../../.. ifeq ($(wildcard ../../../../lib/libopencm3_lpc43xx.a),) +ifneq ($(strip $(shell which $(CC))),) TOOLCHAIN_DIR := $(shell dirname `which $(CC)`)/../$(PREFIX) +endif else ifeq ($(V),1) $(info We seem to be building the example in the source directory. Using local library!) endif -TOOLCHAIN_DIR := ../../../.. endif + CFLAGS += -O2 -g -Wall -Wextra -I$(TOOLCHAIN_DIR)/include -fno-common \ -mcpu=cortex-m4 -mthumb -MD \ -mfloat-abi=hard -mfpu=fpv4-sp-d16 diff --git a/examples/stm32/f1/Makefile.include b/examples/stm32/f1/Makefile.include index 60f44e7..6b87b98 100644 --- a/examples/stm32/f1/Makefile.include +++ b/examples/stm32/f1/Makefile.include @@ -25,14 +25,18 @@ LD = $(PREFIX)-gcc OBJCOPY = $(PREFIX)-objcopy OBJDUMP = $(PREFIX)-objdump GDB = $(PREFIX)-gdb + +TOOLCHAIN_DIR ?= ../../../../.. ifeq ($(wildcard ../../../../../lib/libopencm3_stm32f1.a),) +ifneq ($(strip $(shell which $(CC))),) TOOLCHAIN_DIR := $(shell dirname `which $(CC)`)/../$(PREFIX) +endif else ifeq ($(V),1) -$(info We seem to be building the example in the source directory. Using local library!) +$(info We seem to be building the example in the source directory. Using local library!) endif -TOOLCHAIN_DIR := ../../../../.. endif + ARCH_FLAGS = -mthumb -mcpu=cortex-m3 -msoft-float CFLAGS += -Os -g -Wall -Wextra -I$(TOOLCHAIN_DIR)/include \ -fno-common $(ARCH_FLAGS) -MD -DSTM32F1 diff --git a/examples/stm32/f2/Makefile.include b/examples/stm32/f2/Makefile.include index 690f8c4..10eed79 100644 --- a/examples/stm32/f2/Makefile.include +++ b/examples/stm32/f2/Makefile.include @@ -26,14 +26,18 @@ LD = $(PREFIX)-gcc OBJCOPY = $(PREFIX)-objcopy OBJDUMP = $(PREFIX)-objdump GDB = $(PREFIX)-gdb + +TOOLCHAIN_DIR ?= ../../../../.. ifeq ($(wildcard ../../../../../lib/libopencm3_stm32f2.a),) +ifneq ($(strip $(shell which $(CC))),) TOOLCHAIN_DIR := $(shell dirname `which $(CC)`)/../$(PREFIX) +endif else ifeq ($(V),1) $(info We seem to be building the example in the source directory. Using local library!) endif -TOOLCHAIN_DIR := ../../../../.. endif + CFLAGS += -Os -g -Wall -Wextra -I$(TOOLCHAIN_DIR)/include \ -fno-common -mcpu=cortex-m3 -mthumb -msoft-float -MD -DSTM32F2 LDSCRIPT ?= $(BINARY).ld diff --git a/examples/stm32/f4/Makefile.include b/examples/stm32/f4/Makefile.include index f436bc8..815f375 100644 --- a/examples/stm32/f4/Makefile.include +++ b/examples/stm32/f4/Makefile.include @@ -27,14 +27,18 @@ OBJCOPY = $(PREFIX)-objcopy OBJDUMP = $(PREFIX)-objdump GDB = $(PREFIX)-gdb FLASH = $(shell which st-flash) + +TOOLCHAIN_DIR ?= ../../../../.. ifeq ($(wildcard ../../../../../lib/libopencm3_stm32f4.a),) +ifneq ($(strip $(shell which $(CC))),) TOOLCHAIN_DIR := $(shell dirname `which $(CC)`)/../$(PREFIX) +endif else ifeq ($(V),1) $(info We seem to be building the example in the source directory. Using local library!) endif -TOOLCHAIN_DIR := ../../../../.. endif + CFLAGS += -Os -g -Wall -Wextra -I$(TOOLCHAIN_DIR)/include \ -fno-common -mcpu=cortex-m4 -mthumb \ -mfloat-abi=hard -mfpu=fpv4-sp-d16 -MD -DSTM32F4 -- cgit v1.2.3