diff --git a/arch/arm/include/stm32/chip.h b/arch/arm/include/stm32/chip.h index e476bff892e..8f06701b518 100644 --- a/arch/arm/include/stm32/chip.h +++ b/arch/arm/include/stm32/chip.h @@ -1101,7 +1101,6 @@ * c = C (48pins) R (68 pins) V (100 pins) * c = K (32 pins), C (48 pins), R (68 pins), V (100 pins) * f = 6 (32KB FLASH), 8 (64KB FLASH), B (128KB FLASH), C (256KB FLASH) - * f = 8 (64KB FLASH), B (128KB FLASH), C (256KB FLASH) * xxx = Package, temperature range, options (ignored here) */ @@ -1534,7 +1533,8 @@ # define STM32_NLCD 0 /* (0) No LCD */ # define STM32_NUSBOTG 0 /* USB FS device, but no USB OTG FS/HS */ # define STM32_NGPIO 87 /* GPIOA-F */ -# define STM32_NADC 1 /* (3) 12-bit ADC1 */ +# define STM32_NADC 1 /* (1) 12-bit ADC1 */ +# define STM32_NSDADC 3 /* (3) 16-bit SDADC1-3 */ # define STM32_NDAC 2 /* (2) 12-bit DAC1-2 */ # define STM32_NCAPSENSE 0 /* (0) No capacitive sensing channels */ # define STM32_NCRC 1 /* (1) CRC calculation unit */ diff --git a/arch/arm/src/stm32/Kconfig b/arch/arm/src/stm32/Kconfig index f914f760e19..abfdf719855 100644 --- a/arch/arm/src/stm32/Kconfig +++ b/arch/arm/src/stm32/Kconfig @@ -1394,6 +1394,9 @@ config STM32_STM32F37XX select STM32_HAVE_TIM15 select STM32_HAVE_TIM16 select STM32_HAVE_TIM17 + select STM32_HAVE_SDADC1 + select STM32_HAVE_SDADC2 + select STM32_HAVE_SDADC3 select STM32_HAVE_CAN1 select STM32_HAVE_DAC1 select STM32_HAVE_DAC2 @@ -1777,6 +1780,30 @@ config STM32_HAVE_ADC4_DMA bool default n +config STM32_HAVE_SDADC1 + bool + default n + +config STM32_HAVE_SDADC2 + bool + default n + +config STM32_HAVE_SDADC3 + bool + default n + +config STM32_HAVE_SDADC1_DMA + bool + default n + +config STM32_HAVE_SDADC2_DMA + bool + default n + +config STM32_HAVE_SDADC3_DMA + bool + default n + config STM32_HAVE_CAN1 bool default n @@ -1844,6 +1871,7 @@ config STM32_ADC1 default n select STM32_ADC select STM32_HAVE_ADC1_DMA if STM32_STM32F10XX && STM32_DMA1 + select STM32_HAVE_ADC1_DMA if STM32_STM32F37XX && STM32_DMA1 select STM32_HAVE_ADC1_DMA if !STM32_STM32F10XX && STM32_DMA2 config STM32_ADC2 @@ -1867,6 +1895,27 @@ config STM32_ADC4 depends on STM32_HAVE_ADC4 select STM32_HAVE_ADC4_DMA if STM32_DMA2 +config STM32_SDADC1 + bool "SDADC1" + default n + select STM32_SDADC + depends on STM32_HAVE_SDADC1 + select STM32_HAVE_SDADC1_DMA if STM32_DMA2 + +config STM32_SDADC2 + bool "SDADC2" + default n + select STM32_SDADC + depends on STM32_HAVE_SDADC2 + select STM32_HAVE_SDADC2_DMA if STM32_DMA2 + +config STM32_SDADC3 + bool "SDADC3" + default n + select STM32_SDADC + depends on STM32_HAVE_SDADC3 + select STM32_HAVE_SDADC3_DMA if STM32_DMA2 + config STM32_COMP bool "COMP" default n @@ -2239,6 +2288,9 @@ endmenu config STM32_ADC bool +config STM32_SDADC + bool + config STM32_DAC bool @@ -5403,6 +5455,38 @@ config STM32_ADC4_DMA endmenu +menu "SDADC Configuration" + depends on STM32_SDADC + +config STM32_SDADC1_DMA + bool "SDADC1 DMA" + depends on STM32_SDADC1 && STM32_HAVE_SDADC1_DMA + default n + ---help--- + If DMA is selected, then the SDADC may be configured to support + DMA transfer, which is advisable if multiple channels are read + or if very high trigger frequencies are used. + +config STM32_SDADC2_DMA + bool "SDADC2 DMA" + depends on STM32_SDADC2 && STM32_HAVE_SDADC2_DMA + default n + ---help--- + If DMA is selected, then the SDADC may be configured to support + DMA transfer, which is advisable if multiple channels are read + or if very high trigger frequencies are used. + +config STM32_SDADC3_DMA + bool "SDADC3 DMA" + depends on STM32_SDADC3 && STM32_HAVE_SDADC3_DMA + default n + ---help--- + If DMA is selected, then the SDADC may be configured to support + DMA transfer, which is advisable if multiple channels are read + or if very high trigger frequencies are used. + +endmenu + menu "DAC Configuration" depends on STM32_DAC1 || STM32_DAC2 diff --git a/arch/arm/src/stm32/Make.defs b/arch/arm/src/stm32/Make.defs index 31bd92eee42..5cd35648931 100644 --- a/arch/arm/src/stm32/Make.defs +++ b/arch/arm/src/stm32/Make.defs @@ -148,6 +148,8 @@ ifeq ($(CONFIG_STM32_I2C_ALT),y) CHIP_CSRCS += stm32_i2c_alt.c else ifeq ($(CONFIG_STM32_STM32F30XX),y) CHIP_CSRCS += stm32f30xxx_i2c.c +else ifeq ($(CONFIG_STM32_STM32F37XX),y) +CHIP_CSRCS += stm32f30xxx_i2c.c else ifeq ($(CONFIG_STM32_STM32F40XX),y) CHIP_CSRCS += stm32f40xxx_i2c.c else @@ -217,6 +219,10 @@ ifeq ($(CONFIG_STM32_ADC),y) CHIP_CSRCS += stm32_adc.c endif +ifeq ($(CONFIG_STM32_SDADC),y) +CHIP_CSRCS += stm32_sdadc.c +endif + ifeq ($(CONFIG_DAC),y) CHIP_CSRCS += stm32_dac.c endif diff --git a/arch/arm/src/stm32/chip/stm32_dac.h b/arch/arm/src/stm32/chip/stm32_dac.h index 1eadecb8949..81a69b71e68 100644 --- a/arch/arm/src/stm32/chip/stm32_dac.h +++ b/arch/arm/src/stm32/chip/stm32_dac.h @@ -66,20 +66,56 @@ /* Register Addresses ***************************************************************/ -#define STM32_DAC_CR (STM32_DAC_BASE+STM32_DAC_CR_OFFSET) -#define STM32_DAC_SWTRIGR (STM32_DAC_BASE+STM32_DAC_SWTRIGR_OFFSET) -#define STM32_DAC_DHR12R1 (STM32_DAC_BASE+STM32_DAC_DHR12R1_OFFSET) -#define STM32_DAC_DHR12L1 (STM32_DAC_BASE+STM32_DAC_DHR12L1_OFFSET) -#define STM32_DAC_DHR8R1 (STM32_DAC_BASE+STM32_DAC_DHR8R1_OFFSET) -#define STM32_DAC_DHR12R2 (STM32_DAC_BASE+STM32_DAC_DHR12R2_OFFSET) -#define STM32_DAC_DHR12L2 (STM32_DAC_BASE+STM32_DAC_DHR12L2_OFFSET) -#define STM32_DAC_DHR8R2 (STM32_DAC_BASE+STM32_DAC_DHR8R2_OFFSET) -#define STM32_DAC_DHR12RD (STM32_DAC_BASE+STM32_DAC_DHR12RD_OFFSET) -#define STM32_DAC_DHR12LD (STM32_DAC_BASE+STM32_DAC_DHR12LD_OFFSET) -#define STM32_DAC_DHR8RD (STM32_DAC_BASE+STM32_DAC_DHR8RD_OFFSET) -#define STM32_DAC_DOR1 (STM32_DAC_BASE+STM32_DAC_DOR1_OFFSET) -#define STM32_DAC_DOR2 (STM32_DAC_BASE+STM32_DAC_DOR2_OFFSET) -#define STM32_DAC_SR (STM32_DAC_BASE+STM32_DAC_SR_OFFSET) +#if STM32_NDAC < 2 +# define STM32_DAC_CR (STM32_DAC_BASE+STM32_DAC_CR_OFFSET) +# define STM32_DAC_SWTRIGR (STM32_DAC_BASE+STM32_DAC_SWTRIGR_OFFSET) +# define STM32_DAC_DHR12R1 (STM32_DAC_BASE+STM32_DAC_DHR12R1_OFFSET) +# define STM32_DAC_DHR12L1 (STM32_DAC_BASE+STM32_DAC_DHR12L1_OFFSET) +# define STM32_DAC_DHR8R1 (STM32_DAC_BASE+STM32_DAC_DHR8R1_OFFSET) +# define STM32_DAC_DHR12R2 (STM32_DAC_BASE+STM32_DAC_DHR12R2_OFFSET) +# define STM32_DAC_DHR12L2 (STM32_DAC_BASE+STM32_DAC_DHR12L2_OFFSET) +# define STM32_DAC_DHR8R2 (STM32_DAC_BASE+STM32_DAC_DHR8R2_OFFSET) +# define STM32_DAC_DHR12RD (STM32_DAC_BASE+STM32_DAC_DHR12RD_OFFSET) +# define STM32_DAC_DHR12LD (STM32_DAC_BASE+STM32_DAC_DHR12LD_OFFSET) +# define STM32_DAC_DHR8RD (STM32_DAC_BASE+STM32_DAC_DHR8RD_OFFSET) +# define STM32_DAC_DOR1 (STM32_DAC_BASE+STM32_DAC_DOR1_OFFSET) +# define STM32_DAC_DOR2 (STM32_DAC_BASE+STM32_DAC_DOR2_OFFSET) +# define STM32_DAC_SR (STM32_DAC_BASE+STM32_DAC_SR_OFFSET) +#else +/* DAC1 */ + +# define STM32_DAC1_CR (STM32_DAC1_BASE+STM32_DAC_CR_OFFSET) +# define STM32_DAC1_SWTRIGR (STM32_DAC1_BASE+STM32_DAC_SWTRIGR_OFFSET) +# define STM32_DAC1_DHR12R1 (STM32_DAC1_BASE+STM32_DAC_DHR12R1_OFFSET) +# define STM32_DAC1_DHR12L1 (STM32_DAC1_BASE+STM32_DAC_DHR12L1_OFFSET) +# define STM32_DAC1_DHR8R1 (STM32_DAC1_BASE+STM32_DAC_DHR8R1_OFFSET) +# define STM32_DAC1_DHR12R2 (STM32_DAC1_BASE+STM32_DAC_DHR12R2_OFFSET) +# define STM32_DAC1_DHR12L2 (STM32_DAC1_BASE+STM32_DAC_DHR12L2_OFFSET) +# define STM32_DAC1_DHR8R2 (STM32_DAC1_BASE+STM32_DAC_DHR8R2_OFFSET) +# define STM32_DAC1_DHR12RD (STM32_DAC1_BASE+STM32_DAC_DHR12RD_OFFSET) +# define STM32_DAC1_DHR12LD (STM32_DAC1_BASE+STM32_DAC_DHR12LD_OFFSET) +# define STM32_DAC1_DHR8RD (STM32_DAC1_BASE+STM32_DAC_DHR8RD_OFFSET) +# define STM32_DAC1_DOR1 (STM32_DAC1_BASE+STM32_DAC_DOR1_OFFSET) +# define STM32_DAC1_DOR2 (STM32_DAC1_BASE+STM32_DAC_DOR2_OFFSET) +# define STM32_DAC1_SR (STM32_DAC1_BASE+STM32_DAC_SR_OFFSET) + +/* DAC2 */ + +# define STM32_DAC2_CR (STM32_DAC2_BASE+STM32_DAC_CR_OFFSET) +# define STM32_DAC2_SWTRIGR (STM32_DAC2_BASE+STM32_DAC_SWTRIGR_OFFSET) +# define STM32_DAC2_DHR12R1 (STM32_DAC2_BASE+STM32_DAC_DHR12R1_OFFSET) +# define STM32_DAC2_DHR12L1 (STM32_DAC2_BASE+STM32_DAC_DHR12L1_OFFSET) +# define STM32_DAC2_DHR8R1 (STM32_DAC2_BASE+STM32_DAC_DHR8R1_OFFSET) +# define STM32_DAC2_DHR12R2 (STM32_DAC2_BASE+STM32_DAC_DHR12R2_OFFSET) +# define STM32_DAC2_DHR12L2 (STM32_DAC2_BASE+STM32_DAC_DHR12L2_OFFSET) +# define STM32_DAC2_DHR8R2 (STM32_DAC2_BASE+STM32_DAC_DHR8R2_OFFSET) +# define STM32_DAC2_DHR12RD (STM32_DAC2_BASE+STM32_DAC_DHR12RD_OFFSET) +# define STM32_DAC2_DHR12LD (STM32_DAC2_BASE+STM32_DAC_DHR12LD_OFFSET) +# define STM32_DAC2_DHR8RD (STM32_DAC2_BASE+STM32_DAC_DHR8RD_OFFSET) +# define STM32_DAC2_DOR1 (STM32_DAC2_BASE+STM32_DAC_DOR1_OFFSET) +# define STM32_DAC2_DOR2 (STM32_DAC2_BASE+STM32_DAC_DOR2_OFFSET) +# define STM32_DAC2_SR (STM32_DAC2_BASE+STM32_DAC_SR_OFFSET) +#endif /* Register Bitfield Definitions ****************************************************/ diff --git a/arch/arm/src/stm32/chip/stm32_pwr.h b/arch/arm/src/stm32/chip/stm32_pwr.h index 9c1e64e57bd..f2c2fdde0bf 100644 --- a/arch/arm/src/stm32/chip/stm32_pwr.h +++ b/arch/arm/src/stm32/chip/stm32_pwr.h @@ -105,6 +105,12 @@ # endif #endif +#if defined(CONFIG_STM32_STM32F37XX) +#define PWR_CR_ENSD1 (1 << 9) /* Bit 9: Enable SDADC1 */ +#define PWR_CR_ENSD2 (1 << 10) /* Bit 10: Enable SDADC2 */ +#define PWR_CR_ENSD3 (1 << 11) /* Bit 11: Enable SDADC3 */ +#endif + #if defined(CONFIG_STM32_STM32L15XX) # define PWR_CR_ULP (1 << 9) /* Ultralow power mode */ # define PWR_CR_FWU (1 << 10) /* Fast wake-up */ @@ -132,7 +138,8 @@ #define PWR_CSR_SBF (1 << 1) /* Bit 1: Standby Flag */ #define PWR_CSR_PVDO (1 << 2) /* Bit 2: PVD Output */ -#if defined(CONFIG_STM32_STM32F20XX) || defined(CONFIG_STM32_STM32F40XX) +#if defined(CONFIG_STM32_STM32F20XX) || defined(CONFIG_STM32_STM32F37XX) || \ + defined(CONFIG_STM32_STM32F40XX) # define PWR_CSR_BRR (1 << 3) /* Bit 3: Backup regulator ready */ #elif defined(CONFIG_STM32_STM32L15XX) # define PWR_CSR_VREFINTRDYF (1 << 3) /* Bit 3: Internal voltage reference (VREFINT) ready flag */ @@ -143,7 +150,7 @@ #if defined(CONFIG_STM32_STM32F30XX) # define PWR_CSR_EWUP1 (1 << 8) /* Bit 8: Enable WKUP1 pin */ # define PWR_CSR_EWUP2 (1 << 9) /* Bit 9: Enable WKUP2 pin */ -#elif defined(CONFIG_STM32_STM32L15XX) +#elif defined(CONFIG_STM32_STM32L15XX) || defined(CONFIG_STM32_STM32F37XX) # define PWR_CSR_EWUP1 (1 << 8) /* Bit 8: Enable WKUP1 pin */ # define PWR_CSR_EWUP2 (1 << 9) /* Bit 9: Enable WKUP2 pin */ # define PWR_CSR_EWUP3 (1 << 10) /* Bit 8: Enable WKUP3 pin */ diff --git a/arch/arm/src/stm32/chip/stm32f30xxx_adc.h b/arch/arm/src/stm32/chip/stm32f30xxx_adc.h index 5763260eb9c..7c9da24b0c1 100644 --- a/arch/arm/src/stm32/chip/stm32f30xxx_adc.h +++ b/arch/arm/src/stm32/chip/stm32f30xxx_adc.h @@ -60,8 +60,8 @@ #define STM32_ADC_SMPR1_OFFSET 0x0014 /* ADC sample time register 1 */ #define STM32_ADC_SMPR2_OFFSET 0x0018 /* ADC sample time register 2 */ #define STM32_ADC_TR1_OFFSET 0x0020 /* ADC watchdog threshold register 1 */ -#define STM32_ADC_TR2_OFFSET 0x0020 /* ADC watchdog threshold register 2 */ -#define STM32_ADC_TR3_OFFSET 0x0020 /* ADC watchdog threshold register 3 */ +#define STM32_ADC_TR2_OFFSET 0x0024 /* ADC watchdog threshold register 2 */ +#define STM32_ADC_TR3_OFFSET 0x0028 /* ADC watchdog threshold register 3 */ #define STM32_ADC_SQR1_OFFSET 0x0030 /* ADC regular sequence register 1 */ #define STM32_ADC_SQR2_OFFSET 0x0034 /* ADC regular sequence register 2 */ #define STM32_ADC_SQR3_OFFSET 0x0038 /* ADC regular sequence register 3 */ diff --git a/arch/arm/src/stm32/chip/stm32f37xxx_adc.h b/arch/arm/src/stm32/chip/stm32f37xxx_adc.h new file mode 100644 index 00000000000..95a40ade448 --- /dev/null +++ b/arch/arm/src/stm32/chip/stm32f37xxx_adc.h @@ -0,0 +1,321 @@ +/**************************************************************************************************** + * arch/arm/src/stm32/chip/stm32f30xxx_adc.h + * + * Copyright (C) 2009, 2011, 2013 Gregory Nutt. All rights reserved. + * Copyright (C) 2016 Studelec SA. All rights reserved. + * Authors: Gregory Nutt + * Marc Rechté + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_STM32_CHIP_STM32F37XXX_ADC_H +#define __ARCH_ARM_SRC_STM32_CHIP_STM32F37XXX_ADC_H + +/**************************************************************************************************** + * Included Files + ****************************************************************************************************/ + +#include + +#include "chip.h" + +/**************************************************************************************************** + * Pre-processor Definitions + ****************************************************************************************************/ + +/* Register Offsets *********************************************************************************/ + +#define STM32_ADC_SR_OFFSET 0x0000 /* ADC status register */ +#define STM32_ADC_CR1_OFFSET 0x0004 /* ADC control register 1 */ +#define STM32_ADC_CR2_OFFSET 0x0008 /* ADC control register 2 */ +#define STM32_ADC_SMPR1_OFFSET 0x000c /* ADC sample time register 1 */ +#define STM32_ADC_SMPR2_OFFSET 0x0010 /* ADC sample time register 2 */ +#define STM32_ADC_JOFR1_OFFSET 0x0014 /* ADC injected channel data offset register 1 */ +#define STM32_ADC_JOFR2_OFFSET 0x0018 /* ADC injected channel data offset register 2 */ +#define STM32_ADC_JOFR3_OFFSET 0x001c /* ADC injected channel data offset register 3 */ +#define STM32_ADC_JOFR4_OFFSET 0x0020 /* ADC injected channel data offset register 4 */ +#define STM32_ADC_HTR_OFFSET 0x0024 /* ADC watchdog high threshold register */ +#define STM32_ADC_LTR_OFFSET 0x0028 /* ADC watchdog low threshold register */ +#define STM32_ADC_SQR1_OFFSET 0x002c /* ADC regular sequence register 1 */ +#define STM32_ADC_SQR2_OFFSET 0x0030 /* ADC regular sequence register 2 */ +#define STM32_ADC_SQR3_OFFSET 0x0034 /* ADC regular sequence register 3 */ +#define STM32_ADC_JSQR_OFFSET 0x0038 /* ADC injected sequence register */ +#define STM32_ADC_JDR1_OFFSET 0x003c /* ADC injected data register 1 */ +#define STM32_ADC_JDR2_OFFSET 0x0040 /* ADC injected data register 2 */ +#define STM32_ADC_JDR3_OFFSET 0x0044 /* ADC injected data register 3 */ +#define STM32_ADC_JDR4_OFFSET 0x0048 /* ADC injected data register 4 */ +#define STM32_ADC_DR_OFFSET 0x004c /* ADC regular data register */ + +/* Register Addresses *******************************************************************************/ + +#define STM32_ADC_SR (STM32_ADC_BASE+STM32_ADC_SR_OFFSET) +#define STM32_ADC_CR1 (STM32_ADC_BASE+STM32_ADC_CR1_OFFSET) +#define STM32_ADC_CR2 (STM32_ADC_BASE+STM32_ADC_CR2_OFFSET) +#define STM32_ADC_SMPR1 (STM32_ADC_BASE+STM32_ADC_SMPR1_OFFSET) +#define STM32_ADC_SMPR2 (STM32_ADC_BASE+STM32_ADC_SMPR2_OFFSET) +#define STM32_ADC_JOFR1 (STM32_ADC_BASE+STM32_ADC_JOFR1_OFFSET) +#define STM32_ADC_JOFR2 (STM32_ADC_BASE+STM32_ADC_JOFR2_OFFSET) +#define STM32_ADC_JOFR3 (STM32_ADC_BASE+STM32_ADC_JOFR3_OFFSET) +#define STM32_ADC_JOFR4 (STM32_ADC_BASE+STM32_ADC_JOFR4_OFFSET) +#define STM32_ADC_HTR (STM32_ADC_BASE+STM32_ADC_HTR_OFFSET) +#define STM32_ADC_LTR (STM32_ADC_BASE+STM32_ADC_LTR_OFFSET) +#define STM32_ADC_SQR1 (STM32_ADC_BASE+STM32_ADC_SQR1_OFFSET) +#define STM32_ADC_SQR2 (STM32_ADC_BASE+STM32_ADC_SQR2_OFFSET) +#define STM32_ADC_SQR3 (STM32_ADC_BASE+STM32_ADC_SQR3_OFFSET) +#define STM32_ADC_JSQR (STM32_ADC_BASE+STM32_ADC_JSQR_OFFSET) +#define STM32_ADC_JDR1 (STM32_ADC_BASE+STM32_ADC_JDR1_OFFSET) +#define STM32_ADC_JDR2 (STM32_ADC_BASE+STM32_ADC_JDR2_OFFSET) +#define STM32_ADC_JDR3 (STM32_ADC_BASE+STM32_ADC_JDR3_OFFSET) +#define STM32_ADC_JDR4 (STM32_ADC_BASE+STM32_ADC_JDR4_OFFSET) +#define STM32_ADC_DR (STM32_ADC_BASE+STM32_ADC_DR_OFFSET) + +/* Register Bitfield Definitions ********************************************************************/ +/* ADC status register (SR) */ + +#define ADC_SR_AWD (1 << 0) /* Bit 0: Analog wtchdog flag */ +#define ADC_SR_EOC (1 << 1) /* Bit 1: End of conversion */ +#define ADC_SR_JEOC (1 << 2) /* Bit 2: Injected channel end of conversion */ +#define ADC_SR_JSTRT (1 << 3) /* Bit 3: Injected channel start flag */ +#define ADC_SR_RSTRT (1 << 4) /* Bit 4: Regular channel start flag */ + +/* ADC control register 1 */ + +#define ADC_CR1_AWDCH_SHIFT (0) /* Bits 0-4: Analog watchdog channel select bits */ +#define ADC_CR1_AWDCH_MASK (0x1f << ADC_CR1_AWDCH_SHIFT) +#define ADC_CR1_EOCIE (1 << 5) /* Bit 5: Interrupt enable EOC */ +#define ADC_CR1_AWDIE (1 << 6) /* Bit 6: Analog watchdog interrupt enable */ +#define ADC_CR1_JEOCIE (1 << 7) /* Bit 7: Interrupt enable for injected channels */ +#define ADC_CR1_SCAN (1 << 8) /* Bit 8: Scan mode */ +#define ADC_CR1_AWDSGL (1 << 9) /* Bit 9: Enable the watchdog on a single channel in scan mode */ +#define ADC_CR1_JAUTO (1 << 10) /* Bit 10: Automatic Injected Group conversion */ +#define ADC_CR1_DISCEN (1 << 11) /* Bit 11: Discontinuous mode on regular channels */ +#define ADC_CR1_JDISCEN (1 << 12) /* Bit 12: Discontinuous mode on injected channels */ +#define ADC_CR1_DISNUM_SHIFT (13) /* Bit 13-15: Discontinuous mode channel count */ +#define ADC_CR1_DISNUM_MASK (0x7 << ADC_CR1_DISNUM_SHIFT) +#define ADC_CR1_JAWDEN (1 << 22) /* Bit 22: Analog watchdog enable on injected channels */ +#define ADC_CR1_AWDEN (1 << 23) /* Bit 23: Analog watchdog enable on regular channels */ + +/* ADC control register 2 */ + +#define ADC_CR2_ADON (1 << 0) /* Bit 0: A/D converter ON / OFF */ +#define ADC_CR2_CONT (1 << 1) /* Bit 1: Continuous conversion */ +#define ADC_CR2_CAL (1 << 2) /* Bit 2: A/D Calibration */ +#define ADC_CR2_RSTCAL (1 << 3) /* Bit 3: Reset calibration */ +#define ADC_CR2_DMA (1 << 8) /* Bit 8: Direct memory access mode */ +#define ADC_CR2_ALIGN (1 << 11) /* Bit 11: Data alignment */ +#define ADC_CR2_JEXTSEL_SHIFT (12) /* Bit 12-14: External event select for injected group */ +#define ADC_CR2_JEXTSEL_MASK (0x7 << ADC_CR2_JEXTSEL_SHIFT) +# define ADC_CR2_JEXTSEL_TIM19_CC1 (0 << ADC_CR2_JEXTSEL_SHIFT) +# define ADC_CR2_JEXTSEL_TIM19_CC2 (1 << ADC_CR2_JEXTSEL_SHIFT) +# define ADC_CR2_JEXTSEL_TIM2_TRGO (2 << ADC_CR2_JEXTSEL_SHIFT) +# define ADC_CR2_JEXTSEL_TIM2_CC1 (3 << ADC_CR2_JEXTSEL_SHIFT) +# define ADC_CR2_JEXTSEL_TIM3_CC4 (4 << ADC_CR2_JEXTSEL_SHIFT) +# define ADC_CR2_JEXTSEL_TIM4_TRGO (5 << ADC_CR2_JEXTSEL_SHIFT) +# define ADC_CR2_JEXTSEL_EXTI15 (6 << ADC_CR2_JEXTSEL_SHIFT) +# define ADC_CR2_JEXTSEL_JSWSTART (7 << ADC_CR2_JEXTSEL_SHIFT) +#define ADC_CR2_JEXTTRIG (1 << 15) /* Bit 15: External trigger conversion mode for injected channels */ +#define ADC_CR2_EXTSEL_SHIFT (17) /* Bit 17-19: External event select for regular group */ +#define ADC_CR2_EXTSEL_MASK (0x7 << ADC_CR2_EXTSEL_SHIFT) +# define ADC_CR2_EXTSEL_TIM19_TRGO (0 << ADC_CR2_EXTSEL_SHIFT) +# define ADC_CR2_EXTSEL_TIM19_CC3 (1 << ADC_CR2_EXTSEL_SHIFT) +# define ADC_CR2_EXTSEL_TIM19_CC4 (2 << ADC_CR2_EXTSEL_SHIFT) +# define ADC_CR2_EXTSEL_TIM2_CC2 (3 << ADC_CR2_EXTSEL_SHIFT) +# define ADC_CR2_EXTSEL_TIM3_TRGO (4 << ADC_CR2_EXTSEL_SHIFT) +# define ADC_CR2_EXTSEL_TIM4_CC4 (5 << ADC_CR2_EXTSEL_SHIFT) +# define ADC_CR2_EXTSEL_EXTI11 (6 << ADC_CR2_EXTSEL_SHIFT) +# define ADC_CR2_EXTSEL_SWSTART (7 << ADC_CR2_EXTSEL_SHIFT) +#define ADC_CR2_EXTTRIG (1 << 20) /* Bit 20: External trigger conversion mode for regular channels */ +#define ADC_CR2_JSWSTART (1 << 21) /* Bit 21: Start conversion of injected channels */ +#define ADC_CR2_SWSTART (1 << 22) /* Bit 22: Start conversion of regular channels */ +#define ADC_CR2_TSVREFE (1 << 23) /* Bit 23: Temperature sensor and V REFINT enable */ + +/* ADC sample time register 1 */ + +#define ADC_SMPR_1p5 0 /* 000: 1.5 cycles */ +#define ADC_SMPR_7p5 1 /* 001: 7.5 cycles */ +#define ADC_SMPR_13p5 2 /* 010: 13.5 cycles */ +#define ADC_SMPR_28p5 3 /* 011: 28.5 cycles */ +#define ADC_SMPR_41p5 4 /* 100: 41.5 cycles */ +#define ADC_SMPR_55p5 5 /* 101: 55.5 cycles */ +#define ADC_SMPR_71p5 6 /* 110: 71.5 cycles */ +#define ADC_SMPR_239p5 7 /* 111: 239.5 cycles */ + +#define ADC_SMPR1_SMP10_SHIFT (0) /* Bits 0-2: Channel 10 Sample time selection */ +#define ADC_SMPR1_SMP10_MASK (7 << ADC_SMPR1_SMP10_SHIFT) +#define ADC_SMPR1_SMP11_SHIFT (3) /* Bits 3-5: Channel 11 Sample time selection */ +#define ADC_SMPR1_SMP11_MASK (7 << ADC_SMPR1_SMP11_SHIFT) +#define ADC_SMPR1_SMP12_SHIFT (6) /* Bits 6-8: Channel 12 Sample time selection */ +#define ADC_SMPR1_SMP12_MASK (7 << ADC_SMPR1_SMP12_SHIFT) +#define ADC_SMPR1_SMP13_SHIFT (9) /* Bits 9-11: Channel 13 Sample time selection */ +#define ADC_SMPR1_SMP13_MASK (7 << ADC_SMPR1_SMP13_SHIFT) +#define ADC_SMPR1_SMP14_SHIFT (12) /* Bits 12-14: Channel 14 Sample time selection */ +#define ADC_SMPR1_SMP14_MASK (7 << ADC_SMPR1_SMP14_SHIFT) +#define ADC_SMPR1_SMP15_SHIFT (15) /* Bits 15-17: Channel 15 Sample time selection */ +#define ADC_SMPR1_SMP15_MASK (7 << ADC_SMPR1_SMP15_SHIFT) +#define ADC_SMPR1_SMP16_SHIFT (18) /* Bits 18-20: Channel 16 Sample time selection */ +#define ADC_SMPR1_SMP16_MASK (7 << ADC_SMPR1_SMP16_SHIFT) +#define ADC_SMPR1_SMP17_SHIFT (21) /* Bits 21-23: Channel 17 Sample time selection */ +#define ADC_SMPR1_SMP17_MASK (7 << ADC_SMPR1_SMP17_SHIFT) +#define ADC_SMPR1_SMP18_SHIFT (21) /* Bits 24-26: Channel 18 Sample time selection */ +#define ADC_SMPR1_SMP18_MASK (7 << ADC_SMPR1_SMP17_SHIFT) + +/* ADC sample time register 2 */ + +#define ADC_SMPR2_SMP0_SHIFT (0) /* Bits 2-0: Channel 0 Sample time selection */ +#define ADC_SMPR2_SMP0_MASK (7 << ADC_SMPR2_SMP0_SHIFT) +#define ADC_SMPR2_SMP1_SHIFT (3) /* Bits 5-3: Channel 1 Sample time selection */ +#define ADC_SMPR2_SMP1_MASK (7 << ADC_SMPR2_SMP1_SHIFT) +#define ADC_SMPR2_SMP2_SHIFT (6) /* Bits 8-6: Channel 2 Sample time selection */ +#define ADC_SMPR2_SMP2_MASK (7 << ADC_SMPR2_SMP2_SHIFT) +#define ADC_SMPR2_SMP3_SHIFT (9) /* Bits 11-9: Channel 3 Sample time selection */ +#define ADC_SMPR2_SMP3_MASK (7 << ADC_SMPR2_SMP3_SHIFT) +#define ADC_SMPR2_SMP4_SHIFT (12) /* Bits 14-12: Channel 4 Sample time selection */ +#define ADC_SMPR2_SMP4_MASK (7 << ADC_SMPR2_SMP4_SHIFT) +#define ADC_SMPR2_SMP5_SHIFT (15) /* Bits 17-15: Channel 5 Sample time selection */ +#define ADC_SMPR2_SMP5_MASK (7 << ADC_SMPR2_SMP5_SHIFT) +#define ADC_SMPR2_SMP6_SHIFT (18) /* Bits 20-18: Channel 6 Sample time selection */ +#define ADC_SMPR2_SMP6_MASK (7 << ADC_SMPR2_SMP6_SHIFT) +#define ADC_SMPR2_SMP7_SHIFT (21) /* Bits 23-21: Channel 7 Sample time selection */ +#define ADC_SMPR2_SMP7_MASK (7 << ADC_SMPR2_SMP7_SHIFT) +#define ADC_SMPR2_SMP8_SHIFT (24) /* Bits 26-24: Channel 8 Sample time selection */ +#define ADC_SMPR2_SMP8_MASK (7 << ADC_SMPR2_SMP8_SHIFT) +#define ADC_SMPR2_SMP9_SHIFT (27) /* Bits 29-27: Channel 9 Sample time selection */ +#define ADC_SMPR2_SMP9_MASK (7 << ADC_SMPR2_SMP9_SHIFT) + +/* ADC injected channel data offset register 1, 2, 3, and 4 */ + +#define ADC_JOFR_OFFSETX_SHIFT (0) /* Bits 0-11: Data offset for injected channel x */ +#define ADC_JOFR_OFFSETX_MASK (0x0fff << ADC_JOFR_OFFSETX_SHIFT) + +/* ADC watchdog high threshold register */ + +#define ADC_HTR_HT_SHIFT (0) /* Bits 0-11: Analog watchdog high threshold */ +#define ADC_HTR_HT_MASK (0xfff << ADC_HTR_HT_SHIFT) + +/* ADC watchdog low threshold register */ + +#define ADC_LTR_LT_SHIFT (0) /* Bits 0-11: Analog watchdog low threshold */ +#define ADC_LTR_LT_MASK (0xfff << ADC_LTR_LT_SHIFT) + +/* Offset between SQ bits */ + +#define ADC_SQ_OFFSET (5) + +/* ADC regular sequence register 1 */ + +#define ADC_SQR1_SQ13_SHIFT (0) /* Bits 0-4: 13th conversion in regular sequence */ +#define ADC_SQR1_SQ13_MASK (0x1f << ADC_SQR1_SQ13_SHIFT) +#define ADC_SQR1_SQ14_SHIFT (5) /* Bits 5-9: 14th conversion in regular sequence */ +#define ADC_SQR1_SQ14_MASK (0x1f << ADC_SQR1_SQ14_SHIFT) +#define ADC_SQR1_SQ15_SHIFT (10) /* Bits 10-14: 15th conversion in regular sequence */ +#define ADC_SQR1_SQ15_MASK (0x1f << ADC_SQR1_SQ15_SHIFT) +#define ADC_SQR1_SQ16_SHIFT (15) /* Bits 15-19: 16th conversion in regular sequence */ +#define ADC_SQR1_SQ16_MASK (0x1f << ADC_SQR1_SQ16_SHIFT) +#define ADC_SQR1_L_SHIFT (20) /* Bits 20-23: Regular channel sequence length */ +#define ADC_SQR1_L_MASK (0xf << ADC_SQR1_L_SHIFT) +#define ADC_SQR1_RESERVED (0xff000000) +#define ADC_SQR1_FIRST (13) +#define ADC_SQR1_LAST (16) +#define ADC_SQR1_SQ_OFFSET (0) + +/* ADC regular sequence register 2 */ + +#define ADC_SQR2_SQ7_SHIFT (0) /* Bits 0-4: 7th conversion in regular sequence */ +#define ADC_SQR2_SQ7_MASK (0x1f << ADC_SQR2_SQ7_SHIFT) +#define ADC_SQR2_SQ8_SHIFT (5) /* Bits 5-9: 8th conversion in regular sequence */ +#define ADC_SQR2_SQ8_MASK (0x1f << ADC_SQR2_SQ8_SHIFT) +#define ADC_SQR2_SQ9_SHIFT (10) /* Bits 10-14: 9th conversion in regular sequence */ +#define ADC_SQR2_SQ9_MASK (0x1f << ADC_SQR2_SQ9_SHIFT) +#define ADC_SQR2_SQ10_SHIFT (15) /* Bits 15-19: 10th conversion in regular sequence */ +#define ADC_SQR2_SQ10_MASK (0x1f << ADC_SQR2_SQ10_SHIFT) +#define ADC_SQR2_SQ11_SHIFT (15) /* Bits 20-24: 11th conversion in regular sequence */ +#define ADC_SQR2_SQ11_MASK (0x1f << ADC_SQR2_SQ11_SHIFT) +#define ADC_SQR2_SQ12_SHIFT (15) /* Bits 25-29: 12th conversion in regular sequence */ +#define ADC_SQR2_SQ12_MASK (0x1f << ADC_SQR2_SQ12_SHIFT) +#define ADC_SQR2_RESERVED (0xc0000000) +#define ADC_SQR2_FIRST (7) +#define ADC_SQR2_LAST (12) +#define ADC_SQR2_SQ_OFFSET (0) + +/* ADC regular sequence register 3 */ + +#define ADC_SQR3_SQ1_SHIFT (0) /* Bits 0-4: 1rst conversion in regular sequence */ +#define ADC_SQR3_SQ1_MASK (0x1f << ADC_SQR3_SQ1_SHIFT) +#define ADC_SQR3_SQ2_SHIFT (5) /* Bits 5-9: 2nd conversion in regular sequence */ +#define ADC_SQR3_SQ2_MASK (0x1f << ADC_SQR3_SQ2_SHIFT) +#define ADC_SQR3_SQ3_SHIFT (10) /* Bits 10-14: 3rd conversion in regular sequence */ +#define ADC_SQR3_SQ3_MASK (0x1f << ADC_SQR3_SQ3_SHIFT) +#define ADC_SQR3_SQ4_SHIFT (15) /* Bits 15-19: 4th conversion in regular sequence */ +#define ADC_SQR3_SQ4_MASK (0x1f << ADC_SQR3_SQ4_SHIFT) +#define ADC_SQR3_SQ5_SHIFT (15) /* Bits 20-24: 5th conversion in regular sequence */ +#define ADC_SQR3_SQ5_MASK (0x1f << ADC_SQR3_SQ5_SHIFT) +#define ADC_SQR3_SQ6_SHIFT (15) /* Bits 25-29: 6th conversion in regular sequence */ +#define ADC_SQR3_SQ6_MASK (0x1f << ADC_SQR3_SQ6_SHIFT) +#define ADC_SQR3_RESERVED (0xc0000000) +#define ADC_SQR3_FIRST (1) +#define ADC_SQR3_LAST (6) +#define ADC_SQR3_SQ_OFFSET (0) + +/* ADC injected sequence register */ + +#define ADC_JSQR_JSQ1_SHIFT (0) /* Bits 0-4: 1rst conversion in injected sequence */ +#define ADC_JSQR_JSQ1_MASK (0x1f << ADC_JSQR_JSQ1_SHIFT) +#define ADC_JSQR_JSQ2_SHIFT (5) /* Bits 5-9: 2nd conversion in injected sequence */ +#define ADC_JSQR_JSQ2_MASK (0x1f << ADC_JSQR_JSQ2_SHIFT) +#define ADC_JSQR_JSQ3_SHIFT (10) /* Bits 10-14: 3rd conversion in injected sequence */ +#define ADC_JSQR_JSQ3_MASK (0x1f << ADC_JSQR_JSQ3_SHIFT) +#define ADC_JSQR_JSQ4_SHIFT (15) /* Bits 15-19: 4th conversion in injected sequence */ +#define ADC_JSQR_JSQ4_MASK (0x1f << ADC_JSQR_JSQ4_SHIFT) +#define ADC_JSQR_JL_SHIFT (20) /* Bits 20-21: Injected sequence length */ +#define ADC_JSQR_JL_MASK (0x3 << ADC_JSQR_JL_SHIFT) + +/* ADC injected data register 1, 2, 3, and 4 */ + +#define ADC_JDR_JDATA_SHIFT (0) +#define ADC_JDR_JDATA_MASK (0xffff << ADC_JDR_JDATA_SHIFT) + +/* ADC regular data register */ + +#define ADC_DR_RDATA_SHIFT (0) +#define ADC_DR_RDATA_MASK (0xffff << ADC_DR_RDATA_SHIFT) + +/**************************************************************************************************** + * Public Types + ****************************************************************************************************/ + +/**************************************************************************************************** + * Public Data + ****************************************************************************************************/ + +/**************************************************************************************************** + * Public Function Prototypes + ****************************************************************************************************/ + +#endif /* __ARCH_ARM_SRC_STM32_CHIP_STM32F37XXX_ADC_H */ diff --git a/arch/arm/src/stm32/chip/stm32f37xxx_memorymap.h b/arch/arm/src/stm32/chip/stm32f37xxx_memorymap.h index a9116019bfe..4c703be930c 100644 --- a/arch/arm/src/stm32/chip/stm32f37xxx_memorymap.h +++ b/arch/arm/src/stm32/chip/stm32f37xxx_memorymap.h @@ -117,7 +117,7 @@ #define STM32_SYSCFG_BASE 0x40010000 /* 0x40010000-0x400103FF SYSCFG + COMP + OPAMP */ #define STM32_EXTI_BASE 0x40010400 /* 0x40010400-0x400107FF EXTI */ -#define STM32_ADC1_BASE 0x40012400 /* 0x40012400-0x400127ff ADC1 */ +#define STM32_ADC_BASE 0x40012400 /* 0x40012400-0x400127ff ADC */ #define STM32_SPI1_BASE 0x40013000 /* 0x40013000-0x400133ff SPI1 */ #define STM32_USART1_BASE 0x40013800 /* 0x40013800-0x40013bff USART1 */ #define STM32_TIM15_BASE 0x40014000 /* 0x40014000-0x400143ff TIM15 */ @@ -128,6 +128,8 @@ #define STM32_SDADC2_BASE 0x40016400 /* 0x40016000-0x400167ff SDADC2 */ #define STM32_SDADC3_BASE 0x40016800 /* 0x40016000-0x40016bff SDADC3 */ +#define STM32_ADC1_BASE STM32_ADC_BASE + /* AHB1 Base Addresses **************************************************************/ #define STM32_DMA1_BASE 0x40020000 /* 0x40020000-0x400203ff: DMA1 */ diff --git a/arch/arm/src/stm32/chip/stm32f37xxx_pinmap.h b/arch/arm/src/stm32/chip/stm32f37xxx_pinmap.h index 6f48b4bf1e8..a20ae8577f3 100644 --- a/arch/arm/src/stm32/chip/stm32f37xxx_pinmap.h +++ b/arch/arm/src/stm32/chip/stm32f37xxx_pinmap.h @@ -69,6 +69,71 @@ * pins in this file. */ +/* ADC */ + +#define GPIO_ADC_IN1 (GPIO_ANALOG|GPIO_PORTA|GPIO_PIN1) +#define GPIO_ADC_IN2 (GPIO_ANALOG|GPIO_PORTA|GPIO_PIN2) +#define GPIO_ADC_IN3 (GPIO_ANALOG|GPIO_PORTA|GPIO_PIN3) +#define GPIO_ADC_IN4 (GPIO_ANALOG|GPIO_PORTA|GPIO_PIN4) +#define GPIO_ADC_IN5 (GPIO_ANALOG|GPIO_PORTA|GPIO_PIN5) +#define GPIO_ADC_IN6 (GPIO_ANALOG|GPIO_PORTA|GPIO_PIN6) +#define GPIO_ADC_IN7 (GPIO_ANALOG|GPIO_PORTA|GPIO_PIN7) +#define GPIO_ADC_IN8 (GPIO_ANALOG|GPIO_PORTB|GPIO_PIN0) +#define GPIO_ADC_IN9 (GPIO_ANALOG|GPIO_PORTB|GPIO_PIN1) +#define GPIO_ADC_IN10 (GPIO_ANALOG|GPIO_PORTC|GPIO_PIN0) +#define GPIO_ADC_IN11 (GPIO_ANALOG|GPIO_PORTC|GPIO_PIN1) +#define GPIO_ADC_IN12 (GPIO_ANALOG|GPIO_PORTC|GPIO_PIN2) +#define GPIO_ADC_IN13 (GPIO_ANALOG|GPIO_PORTC|GPIO_PIN3) +#define GPIO_ADC_IN14 (GPIO_ANALOG|GPIO_PORTC|GPIO_PIN4) +#define GPIO_ADC_IN15 (GPIO_ANALOG|GPIO_PORTC|GPIO_PIN5) + +/* SDADC */ + +#define GPIO_SDADC1_AIN0P (GPIO_ANALOG|GPIO_PORTE|GPIO_PIN12) +#define GPIO_SDADC1_AIN0M (GPIO_ANALOG|GPIO_PORTE|GPIO_PIN13) +#define GPIO_SDADC1_AIN1P (GPIO_ANALOG|GPIO_PORTE|GPIO_PIN11) +#define GPIO_SDADC1_AIN2P (GPIO_ANALOG|GPIO_PORTE|GPIO_PIN10) +#define GPIO_SDADC1_AIN2M (GPIO_ANALOG|GPIO_PORTE|GPIO_PIN11) +#define GPIO_SDADC1_AIN3P (GPIO_ANALOG|GPIO_PORTE|GPIO_PIN7) +#define GPIO_SDADC1_AIN4P (GPIO_ANALOG|GPIO_PORTB|GPIO_PIN2) +#define GPIO_SDADC1_AIN4M (GPIO_ANALOG|GPIO_PORTE|GPIO_PIN7) +#define GPIO_SDADC1_AIN5P (GPIO_ANALOG|GPIO_PORTB|GPIO_PIN1) +#define GPIO_SDADC1_AIN6P (GPIO_ANALOG|GPIO_PORTB|GPIO_PIN0) +#define GPIO_SDADC1_AIN6M (GPIO_ANALOG|GPIO_PORTB|GPIO_PIN1) +#define GPIO_SDADC1_AIN7P (GPIO_ANALOG|GPIO_PORTE|GPIO_PIN9) +#define GPIO_SDADC1_AIN8P (GPIO_ANALOG|GPIO_PORTE|GPIO_PIN8) +#define GPIO_SDADC1_AIN8M (GPIO_ANALOG|GPIO_PORTE|GPIO_PIN9) + +#define GPIO_SDADC2_AIN0P (GPIO_ANALOG|GPIO_PORTE|GPIO_PIN15) +#define GPIO_SDADC2_AIN0M (GPIO_ANALOG|GPIO_PORTB|GPIO_PIN10) +#define GPIO_SDADC2_AIN1P (GPIO_ANALOG|GPIO_PORTE|GPIO_PIN14) +#define GPIO_SDADC2_AIN2P (GPIO_ANALOG|GPIO_PORTE|GPIO_PIN13) +#define GPIO_SDADC2_AIN2M (GPIO_ANALOG|GPIO_PORTE|GPIO_PIN14) +#define GPIO_SDADC2_AIN3P (GPIO_ANALOG|GPIO_PORTE|GPIO_PIN12) +#define GPIO_SDADC2_AIN4P (GPIO_ANALOG|GPIO_PORTE|GPIO_PIN11) +#define GPIO_SDADC2_AIN4M (GPIO_ANALOG|GPIO_PORTE|GPIO_PIN12) +#define GPIO_SDADC2_AIN5P (GPIO_ANALOG|GPIO_PORTE|GPIO_PIN7) +#define GPIO_SDADC2_AIN6P (GPIO_ANALOG|GPIO_PORTB|GPIO_PIN2) +#define GPIO_SDADC2_AIN6M (GPIO_ANALOG|GPIO_PORTE|GPIO_PIN7) +#define GPIO_SDADC2_AIN7P (GPIO_ANALOG|GPIO_PORTE|GPIO_PIN9) +#define GPIO_SDADC2_AIN8P (GPIO_ANALOG|GPIO_PORTE|GPIO_PIN8) +#define GPIO_SDADC2_AIN8M (GPIO_ANALOG|GPIO_PORTE|GPIO_PIN9) + +#define GPIO_SDADC3_AIN0P (GPIO_ANALOG|GPIO_PORTD|GPIO_PIN14) +#define GPIO_SDADC3_AIN0M (GPIO_ANALOG|GPIO_PORTD|GPIO_PIN15) +#define GPIO_SDADC3_AIN1P (GPIO_ANALOG|GPIO_PORTD|GPIO_PIN13) +#define GPIO_SDADC3_AIN2P (GPIO_ANALOG|GPIO_PORTD|GPIO_PIN12) +#define GPIO_SDADC3_AIN2M (GPIO_ANALOG|GPIO_PORTD|GPIO_PIN13) +#define GPIO_SDADC3_AIN3P (GPIO_ANALOG|GPIO_PORTD|GPIO_PIN11) +#define GPIO_SDADC3_AIN4P (GPIO_ANALOG|GPIO_PORTD|GPIO_PIN10) +#define GPIO_SDADC3_AIN4M (GPIO_ANALOG|GPIO_PORTD|GPIO_PIN11) +#define GPIO_SDADC3_AIN5P (GPIO_ANALOG|GPIO_PORTD|GPIO_PIN9) +#define GPIO_SDADC3_AIN6P (GPIO_ANALOG|GPIO_PORTD|GPIO_PIN8) +#define GPIO_SDADC3_AIN6M (GPIO_ANALOG|GPIO_PORTD|GPIO_PIN9) +#define GPIO_SDADC3_AIN7P (GPIO_ANALOG|GPIO_PORTB|GPIO_PIN15) +#define GPIO_SDADC3_AIN8P (GPIO_ANALOG|GPIO_PORTB|GPIO_PIN14) +#define GPIO_SDADC3_AIN8M (GPIO_ANALOG|GPIO_PORTB|GPIO_PIN15) + /* CAN */ #define GPIO_CAN_RX_1 (GPIO_ALT|GPIO_AF9|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTA|GPIO_PIN11) @@ -96,9 +161,9 @@ * should first be configured to analog (AIN)". */ -#define GPIO_DAC1_1_OUT (GPIO_ANALOG|GPIO_PORTA|GPIO_PIN4) -#define GPIO_DAC1_2_OUT (GPIO_ANALOG|GPIO_PORTA|GPIO_PIN5) -#define GPIO_DAC2_1_OUT (GPIO_ANALOG|GPIO_PORTA|GPIO_PIN6) +#define GPIO_DAC1_OUT1 (GPIO_ANALOG|GPIO_PORTA|GPIO_PIN4) +#define GPIO_DAC1_OUT2 (GPIO_ANALOG|GPIO_PORTA|GPIO_PIN5) +#define GPIO_DAC2_OUT1 (GPIO_ANALOG|GPIO_PORTA|GPIO_PIN6) /* I2C */ @@ -233,7 +298,6 @@ #define GPIO_SPI3_SCK_2 (GPIO_ALT|GPIO_AF6|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTB|GPIO_PIN3) #define GPIO_SPI3_SCK_3 (GPIO_ALT|GPIO_AF6|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTC|GPIO_PIN10) - /* Timers */ #define GPIO_TIM2_CH1_ETR_1 (GPIO_ALT|GPIO_FLOAT|GPIO_AF1|GPIO_SPEED_50MHz|GPIO_PORTA|GPIO_PIN0) @@ -544,6 +608,5 @@ #define GPIO_PF9_EVENT_OUT (GPIO_ALT|GPIO_AF1|GPIO_PORTF|GPIO_PIN9) #define GPIO_PF10_EVENT_OUT (GPIO_ALT|GPIO_AF1|GPIO_PORTF|GPIO_PIN10) - #endif /* __ARCH_ARM_SRC_STM32_CHIP_STM32F37XXX_PINMAP_H */ diff --git a/arch/arm/src/stm32/chip/stm32f37xxx_rcc.h b/arch/arm/src/stm32/chip/stm32f37xxx_rcc.h index 9c48bbd5d57..1e1f6daf6a6 100644 --- a/arch/arm/src/stm32/chip/stm32f37xxx_rcc.h +++ b/arch/arm/src/stm32/chip/stm32f37xxx_rcc.h @@ -128,6 +128,12 @@ # define RCC_CFGR_PPRE2_HCLKd4 (5 << RCC_CFGR_PPRE2_SHIFT) /* 101: HCLK divided by 4 */ # define RCC_CFGR_PPRE2_HCLKd8 (6 << RCC_CFGR_PPRE2_SHIFT) /* 110: HCLK divided by 8 */ # define RCC_CFGR_PPRE2_HCLKd16 (7 << RCC_CFGR_PPRE2_SHIFT) /* 111: HCLK divided by 16 */ +#define RCC_CFGR_ADCPRE_SHIFT (13) /* Bits 14-15: ADC prescaler */ +#define RCC_CFGR_ADCPRE_MASK (7 << RCC_CFGR_ADCPRE_SHIFT) +# define RCC_CFGR_ADCPRE_PCLKd2 (0 << RCC_CFGR_ADCPRE_SHIFT) /* 00: PCLK divided by 2 */ +# define RCC_CFGR_ADCPRE_PCLKd4 (1 << RCC_CFGR_ADCPRE_SHIFT) /* 01: PCLK divided by 4 */ +# define RCC_CFGR_ADCPRE_PCLKd6 (2 << RCC_CFGR_ADCPRE_SHIFT) /* 10: PCLK divided by 6 */ +# define RCC_CFGR_ADCPRE_PCLKd8 (3 << RCC_CFGR_ADCPRE_SHIFT) /* 11: PCLK divided by 8 */ #define RCC_CFGR_PLLSRC (1 << 16) /* Bit 16: PLL entry clock source */ #define RCC_CFGR_PLLXTPRE (1 << 17) /* Bit 17: HSE divider for PLL entry */ #define RCC_CFGR_PLLMUL_SHIFT (18) /* Bits 21-18: PLL Multiplication Factor */ @@ -157,24 +163,24 @@ # define RCC_CFGR_MCO_HSICLK (5 << RCC_CFGR_MCO_SHIFT) /* 101: HSI clock selected */ # define RCC_CFGR_MCO_HSECLK (6 << RCC_CFGR_MCO_SHIFT) /* 101: HSE clock selected */ # define RCC_CFGR_PLLCLKd2 (7 << RCC_CFGR_MCO_SHIFT) /* 111: PLL clock divided by 2 selected */ -#define RCC_CFGR_SDADCPRE_SHIFT (24) /* Bits 27-31: SDADC Prescaler */ -#define RCC_CFGR_SDADCPRE_MASK (31 << RCC_CFGR_SDADCPRE_SHIFT) -# define RCC_CFGR_SDADCPRE_DIV2 (0 << RCC_CFGR_SDADCPRE_SHIFT) /* 0xxxx: System clock divided by 2 */ -# define RCC_CFGR_SDADCPRE_DIV4 (17 << RCC_CFGR_SDADCPRE_SHIFT) /* 10001: System clock divided by 4 */ -# define RCC_CFGR_SDADCPRE_DIV6 (18 << RCC_CFGR_SDADCPRE_SHIFT) /* 10010: System clock divided by 6 */ -# define RCC_CFGR_SDADCPRE_DIV8 (19 << RCC_CFGR_SDADCPRE_SHIFT) /* 10011: System clock divided by 8 */ -# define RCC_CFGR_SDADCPRE_DIV10 (20 << RCC_CFGR_SDADCPRE_SHIFT) /* 10100: System clock divided by 10 */ -# define RCC_CFGR_SDADCPRE_DIV12 (21 << RCC_CFGR_SDADCPRE_SHIFT) /* 10101: System clock divided by 12 */ -# define RCC_CFGR_SDADCPRE_DIV14 (22 << RCC_CFGR_SDADCPRE_SHIFT) /* 10110: System clock divided by 14 */ -# define RCC_CFGR_SDADCPRE_DIV16 (23 << RCC_CFGR_SDADCPRE_SHIFT) /* 10111: System clock divided by 16 */ -# define RCC_CFGR_SDADCPRE_DIV20 (24 << RCC_CFGR_SDADCPRE_SHIFT) /* 11000: System clock divided by 20 */ -# define RCC_CFGR_SDADCPRE_DIV24 (25 << RCC_CFGR_SDADCPRE_SHIFT) /* 11001: System clock divided by 24 */ -# define RCC_CFGR_SDADCPRE_DIV28 (26 << RCC_CFGR_SDADCPRE_SHIFT) /* 11010: System clock divided by 28 */ -# define RCC_CFGR_SDADCPRE_DIV32 (27 << RCC_CFGR_SDADCPRE_SHIFT) /* 11011: System clock divided by 32 */ -# define RCC_CFGR_SDADCPRE_DIV36 (28 << RCC_CFGR_SDADCPRE_SHIFT) /* 11100: System clock divided by 36 */ -# define RCC_CFGR_SDADCPRE_DIV40 (29 << RCC_CFGR_SDADCPRE_SHIFT) /* 11101: System clock divided by 40 */ -# define RCC_CFGR_SDADCPRE_DIV44 (30 << RCC_CFGR_SDADCPRE_SHIFT) /* 11110: System clock divided by 44 */ -# define RCC_CFGR_SDADCPRE_DIV48 (31 << RCC_CFGR_SDADCPRE_SHIFT) /* 11111: System clock divided by 48 */ +#define RCC_CFGR_SDPRE_SHIFT (27) /* Bits 27-31: SDADC Prescaler */ +#define RCC_CFGR_SDPRE_MASK (0x1f << RCC_CFGR_SDPRE_SHIFT) +# define RCC_CFGR_SDPRE_DIV2 (0 << RCC_CFGR_SDPRE_SHIFT) /* 0xxxx: System clock divided by 2 */ +# define RCC_CFGR_SDPRE_DIV4 (17 << RCC_CFGR_SDPRE_SHIFT) /* 10001: System clock divided by 4 */ +# define RCC_CFGR_SDPRE_DIV6 (18 << RCC_CFGR_SDPRE_SHIFT) /* 10010: System clock divided by 6 */ +# define RCC_CFGR_SDPRE_DIV8 (19 << RCC_CFGR_SDPRE_SHIFT) /* 10011: System clock divided by 8 */ +# define RCC_CFGR_SDPRE_DIV10 (20 << RCC_CFGR_SDPRE_SHIFT) /* 10100: System clock divided by 10 */ +# define RCC_CFGR_SDPRE_DIV12 (21 << RCC_CFGR_SDPRE_SHIFT) /* 10101: System clock divided by 12 */ +# define RCC_CFGR_SDPRE_DIV14 (22 << RCC_CFGR_SDPRE_SHIFT) /* 10110: System clock divided by 14 */ +# define RCC_CFGR_SDPRE_DIV16 (23 << RCC_CFGR_SDPRE_SHIFT) /* 10111: System clock divided by 16 */ +# define RCC_CFGR_SDPRE_DIV20 (24 << RCC_CFGR_SDPRE_SHIFT) /* 11000: System clock divided by 20 */ +# define RCC_CFGR_SDPRE_DIV24 (25 << RCC_CFGR_SDPRE_SHIFT) /* 11001: System clock divided by 24 */ +# define RCC_CFGR_SDPRE_DIV28 (26 << RCC_CFGR_SDPRE_SHIFT) /* 11010: System clock divided by 28 */ +# define RCC_CFGR_SDPRE_DIV32 (27 << RCC_CFGR_SDPRE_SHIFT) /* 11011: System clock divided by 32 */ +# define RCC_CFGR_SDPRE_DIV36 (28 << RCC_CFGR_SDPRE_SHIFT) /* 11100: System clock divided by 36 */ +# define RCC_CFGR_SDPRE_DIV40 (29 << RCC_CFGR_SDPRE_SHIFT) /* 11101: System clock divided by 40 */ +# define RCC_CFGR_SDPRE_DIV44 (30 << RCC_CFGR_SDPRE_SHIFT) /* 11110: System clock divided by 44 */ +# define RCC_CFGR_SDPRE_DIV48 (31 << RCC_CFGR_SDPRE_SHIFT) /* 11111: System clock divided by 48 */ /* Clock interrupt register */ @@ -199,7 +205,7 @@ /* APB2 Peripheral reset register */ #define RCC_APB2RSTR_SYSCFGRST (1 << 0) /* Bit 0: SYSCFG, Comparators and operational amplifiers reset */ -#define RCC_APB2RSTR_ADC1RST (1 << 9) /* Bit 9: ADC1 reset */ +#define RCC_APB2RSTR_ADCRST (1 << 9) /* Bit 9: ADC reset */ #define RCC_APB2RSTR_SPI1RST (1 << 12) /* Bit 12: SPI 1 reset */ #define RCC_APB2RSTR_USART1RST (1 << 14) /* Bit 14: USART1 reset */ #define RCC_APB2RSTR_TIM15RST (1 << 16) /* Bit 16: TIM15 reset */ @@ -232,7 +238,7 @@ #define RCC_APB1RSTR_USBRST (1 << 23) /* Bit 23: USB reset */ #define RCC_APB1RSTR_CANRST (1 << 25) /* Bit 25: CAN reset */ #define RCC_APB1RSTR_CAN1RST (1 << 25) /* Bit 25: CAN reset */ -#define RCC_APB1RSTR_DAC2RST (1 << 26) /* Bit 26: DAC1 interface reset */ +#define RCC_APB1RSTR_DAC2RST (1 << 26) /* Bit 26: DAC2 interface reset */ #define RCC_APB1RSTR_PWRRST (1 << 28) /* Bit 28: Power interface reset */ #define RCC_APB1RSTR_DAC1RST (1 << 29) /* Bit 29: DAC1 interface reset */ #define RCC_APB1RSTR_CECRST (1 << 30) /* Bit 30: CEC reset */ diff --git a/arch/arm/src/stm32/chip/stm32f37xxx_sdadc.h b/arch/arm/src/stm32/chip/stm32f37xxx_sdadc.h new file mode 100644 index 00000000000..011ab4d58fd --- /dev/null +++ b/arch/arm/src/stm32/chip/stm32f37xxx_sdadc.h @@ -0,0 +1,304 @@ +/**************************************************************************************************** + * arch/arm/src/stm32/chip/stm32f37xxx_sdadc.h + * + * Copyright (C) 2009, 2011, 2013 Gregory Nutt. All rights reserved. + * Copyright (C) 2016 Studelec SA. All rights reserved. + * Authors: Gregory Nutt + * Marc Rechté + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_STM32_CHIP_STM32F37XXX_SDADC_H +#define __ARCH_ARM_SRC_STM32_CHIP_STM32F37XXX_SDADC_H + +/**************************************************************************************************** + * Included Files + ****************************************************************************************************/ + +#include + +#include "chip.h" + +/**************************************************************************************************** + * Pre-processor Definitions + ****************************************************************************************************/ + +/* Register Offsets *********************************************************************************/ + +#define STM32_SDADC_CR1_OFFSET 0x0000 /* SDADC control register 1 */ +#define STM32_SDADC_CR2_OFFSET 0x0004 /* SDADC control register 2 */ +#define STM32_SDADC_ISR_OFFSET 0x0008 /* SDADC interrupt and status register */ +#define STM32_SDADC_CLRISR_OFFSET 0x000c /* SDADC interrupt and status clear register */ +#define STM32_SDADC_JCHGR_OFFSET 0x0014 /* SDADC injected channel group selection register */ +#define STM32_SDADC_CONF0R_OFFSET 0x0020 /* SDADC configuration 0 register */ +#define STM32_SDADC_CONF1R_OFFSET 0x0024 /* SDADC configuration 1 register */ +#define STM32_SDADC_CONF2R_OFFSET 0x0028 /* SDADC configuration 2 register */ +#define STM32_SDADC_CONFCHR1_OFFSET 0x0040 /* SDADC channel configuration register 1 */ +#define STM32_SDADC_CONFCHR2_OFFSET 0x0044 /* SDADC channel configuration register 2 */ +#define STM32_SDADC_JDATAR_OFFSET 0x0060 /* SDADC data register for injected group */ +#define STM32_SDADC_RDATAR_OFFSET 0x0064 /* SDADC data register for the regular channel */ +#define STM32_SDADC_JDATA12R_OFFSET 0x0070 /* SDADC1 and SDADC2 injected data register */ +#define STM32_SDADC_RDATA12R_OFFSET 0x0074 /* SDADC1 and SDADC2 regular data register */ +#define STM32_SDADC_JDATA13R_OFFSET 0x0078 /* SDADC1 and SDADC3 injected data register */ +#define STM32_SDADC_RDATA13R_OFFSET 0x007c /* SDADC1 and SDADC3 regular data register */ + + +/* Register Addresses *******************************************************************************/ + +#define STM32_SDADC1_CR1 (STM32_SDADC1_BASE+STM32_SDADC_CR1_OFFSET) +#define STM32_SDADC1_CR2 (STM32_SDADC1_BASE+STM32_SDADC_CR2_OFFSET) +#define STM32_SDADC1_ISR (STM32_SDADC1_BASE+STM32_SDADC_ISR_OFFSET) +#define STM32_SDADC1_CLRISR (STM32_SDADC1_BASE+STM32_SDADC_CLRISR_OFFSET) +#define STM32_SDADC1_JCHGR (STM32_SDADC1_BASE+STM32_SDADC_JCHGR_OFFSET) +#define STM32_SDADC1_CONF0R (STM32_SDADC1_BASE+STM32_SDADC_CONF0R_OFFSET) +#define STM32_SDADC1_CONF1R (STM32_SDADC1_BASE+STM32_SDADC_CONF1R_OFFSET) +#define STM32_SDADC1_CONF2R (STM32_SDADC1_BASE+STM32_SDADC_CONF2R_OFFSET) +#define STM32_SDADC1_CONFCHR1 (STM32_SDADC1_BASE+STM32_SDADC_CONFCHR1_OFFSET) +#define STM32_SDADC1_CONFCHR2 (STM32_SDADC1_BASE+STM32_SDADC_CONFCHR2_OFFSET) +#define STM32_SDADC1_JDATAR (STM32_SDADC1_BASE+STM32_SDADC_JDATAR_OFFSET) +#define STM32_SDADC1_RDATAR (STM32_SDADC1_BASE+STM32_SDADC_RDATAR_OFFSET) +#define STM32_SDADC1_JDATA12R (STM32_SDADC1_BASE+STM32_SDADC_JDATA12R_OFFSET) +#define STM32_SDADC1_RDATA12R (STM32_SDADC1_BASE+STM32_SDADC_RDATA12R_OFFSET) +#define STM32_SDADC1_JDATA13R (STM32_SDADC1_BASE+STM32_SDADC_JDATA13R_OFFSET) +#define STM32_SDADC1_RDATA13R (STM32_SDADC1_BASE+STM32_SDADC_RDATA13R_OFFSET) + +#define STM32_SDADC2_CR1 (STM32_SDADC2_BASE+STM32_SDADC_CR1_OFFSET) +#define STM32_SDADC2_CR2 (STM32_SDADC2_BASE+STM32_SDADC_CR2_OFFSET) +#define STM32_SDADC2_ISR (STM32_SDADC2_BASE+STM32_SDADC_ISR_OFFSET) +#define STM32_SDADC2_CLRISR (STM32_SDADC2_BASE+STM32_SDADC_CLRISR_OFFSET) +#define STM32_SDADC2_JCHGR (STM32_SDADC2_BASE+STM32_SDADC_JCHGR_OFFSET) +#define STM32_SDADC2_CONF0R (STM32_SDADC2_BASE+STM32_SDADC_CONF0R_OFFSET) +#define STM32_SDADC2_CONF1R (STM32_SDADC2_BASE+STM32_SDADC_CONF1R_OFFSET) +#define STM32_SDADC2_CONF2R (STM32_SDADC2_BASE+STM32_SDADC_CONF2R_OFFSET) +#define STM32_SDADC2_CONFCHR1 (STM32_SDADC2_BASE+STM32_SDADC_CONFCHR1_OFFSET) +#define STM32_SDADC2_CONFCHR2 (STM32_SDADC2_BASE+STM32_SDADC_CONFCHR2_OFFSET) +#define STM32_SDADC2_JDATAR (STM32_SDADC2_BASE+STM32_SDADC_JDATAR_OFFSET) +#define STM32_SDADC2_RDATAR (STM32_SDADC2_BASE+STM32_SDADC_RDATAR_OFFSET) + +#define STM32_SDADC3_CR1 (STM32_SDADC3_BASE+STM32_SDADC_CR1_OFFSET) +#define STM32_SDADC3_CR2 (STM32_SDADC3_BASE+STM32_SDADC_CR2_OFFSET) +#define STM32_SDADC3_ISR (STM32_SDADC3_BASE+STM32_SDADC_ISR_OFFSET) +#define STM32_SDADC3_CLRISR (STM32_SDADC3_BASE+STM32_SDADC_CLRISR_OFFSET) +#define STM32_SDADC3_JCHGR (STM32_SDADC3_BASE+STM32_SDADC_JCHGR_OFFSET) +#define STM32_SDADC3_CONF0R (STM32_SDADC3_BASE+STM32_SDADC_CONF0R_OFFSET) +#define STM32_SDADC3_CONF1R (STM32_SDADC3_BASE+STM32_SDADC_CONF1R_OFFSET) +#define STM32_SDADC3_CONF2R (STM32_SDADC3_BASE+STM32_SDADC_CONF2R_OFFSET) +#define STM32_SDADC3_CONFCHR1 (STM32_SDADC3_BASE+STM32_SDADC_CONFCHR1_OFFSET) +#define STM32_SDADC3_CONFCHR2 (STM32_SDADC3_BASE+STM32_SDADC_CONFCHR2_OFFSET) +#define STM32_SDADC3_JDATAR (STM32_SDADC3_BASE+STM32_SDADC_JDATAR_OFFSET) +#define STM32_SDADC3_RDATAR (STM32_SDADC3_BASE+STM32_SDADC_RDATAR_OFFSET) + + +/* Register Bitfield Definitions ********************************************************************/ +/* SDADC control register 1 */ + +#define SDADC_CR1_EOCALIE (1 << 0) /* Bit 0: End of calibration interrupt enable */ +#define SDADC_CR1_JEOCIE (1 << 1) /* Bit 1: Injected end of conversion interrupt enable */ +#define SDADC_CR1_JOVRIE (1 << 2) /* Bit 2: Injected data overrun interrupt enable */ +#define SDADC_CR1_REOCIE (1 << 3) /* Bit 3: Regular end of conversion interrupt enable */ +#define SDADC_CR1_ROVRIE (1 << 4) /* Bit 4: Regular data overrun interrupt enable */ +#define SDADC_CR1_REFV_SHIFT (8) /* Bits 8-9: Reference voltage selection */ +#define SDADC_CR1_REFV_MASK (0x3 << SDADC_CR1_REFV_SHIFT) +# define SDADC_CR1_REFV_EXT (0 << SDADC_CR1_REFV_SHIFT) +# define SDADC_CR1_REFV_INT1p2 (1 << SDADC_CR1_REFV_SHIFT) +# define SDADC_CR1_REFV_INT1p8 (2 << SDADC_CR1_REFV_SHIFT) +# define SDADC_CR1_REFV_INT (3 << SDADC_CR1_REFV_SHIFT) +#define SDADC_CR1_SLOWCK (1 << 10) /* Bit 10: Slow clock mode enable */ +#define SDADC_CR1_SBI (1 << 11) /* Bit 11: Enter Standby mode when idle */ +#define SDADC_CR1_PDI (1 << 12) /* Bit 12: Enter power down mode when idle */ +#define SDADC_CR1_JSYNC (1 << 14) /* Bit 14: Launch a injected conversion synchronously with SDADC1 */ +#define SDADC_CR1_RSYNC (1 << 15) /* Bit 15: Launch regular conversion synchronously with SDADC1 */ +#define SDADC_CR1_JDMAEN (1 << 16) /* Bit 16: DMA channel enabled to read data for the injected channel group */ +#define SDADC_CR1_RDMAEN (1 << 17) /* Bit 17: DMA channel enabled to read data for the regular channel */ +#define SDADC_CR1_INIT (1 << 31) /* Bit 31: Initialization mode request */ + +/* SDADC control register 2 */ + +#define SDADC_CR2_ADON (1 << 0) /* Bit 0: SDADC enable */ +#define SDADC_CR2_CALIBCNT_SHIFT (1) /* Bit 1-2: Number of calibration sequences to be performed (number of valid configurations) */ +#define SDADC_CR2_CALIBCNT_MASK (0x3 << SDADC_CR2_CALIBCNT_SHIFT) +#define SDADC_CR2_STARTCALIB (1 << 4) /* Bit 4: Start calibration */ +#define SDADC_CR2_JCONT (1 << 5) /* Bit 5: Continuous mode selection for injected conversions */ +#define SDADC_CR2_JDS (1 << 6) /* Bit 6: Delay start of injected conversions */ +#define SDADC_CR2_JEXTSEL_SHIFT (8) /* Bit 8-10: Trigger signal selection for launching injected conversions */ +#define SDADC_CR2_JEXTSEL_MASK (0x7 << SDADC_CR2_JEXTSEL_SHIFT) +# define SDADC1_CR2_JEXTSEL_TIM13_CH1 (0 << SDADC_CR2_JEXTSEL_SHIFT) +# define SDADC1_CR2_JEXTSEL_TIM14_CH1 (1 << SDADC_CR2_JEXTSEL_SHIFT) +# define SDADC1_CR2_JEXTSEL_TIM15_CH2 (2 << SDADC_CR2_JEXTSEL_SHIFT) +# define SDADC1_CR2_JEXTSEL_TIM3_CH1 (3 << SDADC_CR2_JEXTSEL_SHIFT) +# define SDADC1_CR2_JEXTSEL_TIM4_CH1 (4 << SDADC_CR2_JEXTSEL_SHIFT) +# define SDADC1_CR2_JEXTSEL_TIM19_CH2 (5 << SDADC_CR2_JEXTSEL_SHIFT) +# define SDADC1_CR2_JEXTSEL_EXTI15 (6 << SDADC_CR2_JEXTSEL_SHIFT) +# define SDADC1_CR2_JEXTSEL_EXTI11 (7 << SDADC_CR2_JEXTSEL_SHIFT) +# define SDADC2_CR2_JEXTSEL_TIM17_CH1 (0 << SDADC_CR2_JEXTSEL_SHIFT) +# define SDADC2_CR2_JEXTSEL_TIM12_CH1 (1 << SDADC_CR2_JEXTSEL_SHIFT) +# define SDADC2_CR2_JEXTSEL_TIM2_CH3 (2 << SDADC_CR2_JEXTSEL_SHIFT) +# define SDADC2_CR2_JEXTSEL_TIM3_CH2 (3 << SDADC_CR2_JEXTSEL_SHIFT) +# define SDADC2_CR2_JEXTSEL_TIM4_CH2 (4 << SDADC_CR2_JEXTSEL_SHIFT) +# define SDADC2_CR2_JEXTSEL_TIM19_CH3 (5 << SDADC_CR2_JEXTSEL_SHIFT) +# define SDADC2_CR2_JEXTSEL_EXTI15 (6 << SDADC_CR2_JEXTSEL_SHIFT) +# define SDADC2_CR2_JEXTSEL_EXTI11 (7 << SDADC_CR2_JEXTSEL_SHIFT) +# define SDADC3_CR2_JEXTSEL_TIM16_CH1 (0 << SDADC_CR2_JEXTSEL_SHIFT) +# define SDADC3_CR2_JEXTSEL_TIM12_CH1 (1 << SDADC_CR2_JEXTSEL_SHIFT) +# define SDADC3_CR2_JEXTSEL_TIM2_CH4 (2 << SDADC_CR2_JEXTSEL_SHIFT) +# define SDADC3_CR2_JEXTSEL_TIM3_CH3 (3 << SDADC_CR2_JEXTSEL_SHIFT) +# define SDADC3_CR2_JEXTSEL_TIM4_CH3 (4 << SDADC_CR2_JEXTSEL_SHIFT) +# define SDADC3_CR2_JEXTSEL_TIM19_CH4 (5 << SDADC_CR2_JEXTSEL_SHIFT) +# define SDADC3_CR2_JEXTSEL_EXTI15 (6 << SDADC_CR2_JEXTSEL_SHIFT) +# define SDADC3_CR2_JEXTSEL_EXTI11 (7 << SDADC_CR2_JEXTSEL_SHIFT) +#define SDADC_CR2_JEXTEN_SHIFT (13) /* Bit 13-14: Trigger enable and trigger edge selection for injected conversions */ +#define SDADC_CR2_JEXTEN_MASK (0x3 << SDADC_CR2_JEXTEN_SHIFT) +# define SDADC_CR2_JEXTEN_NONE (0 << SDADC_CR2_JEXTEN_SHIFT) +# define SDADC_CR2_JEXTEN_RISING (1 << SDADC_CR2_JEXTEN_SHIFT) +# define SDADC_CR2_JEXTEN_FALLING (2 << SDADC_CR2_JEXTEN_SHIFT) +# define SDADC_CR2_JEXTEN_BOTH (3 << SDADC_CR2_JEXTEN_SHIFT) +#define SDADC_CR2_JSWSTART (1 << 15) /* Bit 15: Start a conversion of the injected group of channels */ +#define SDADC_CR2_RCH_SHIFT (16) /* Bit 16-19: Regular channel selection */ +#define SDADC_CR2_RCH_MASK (0xf << SDADC_CR2_RCH_SHIFT) +#define SDADC_CR2_RCONT (1 << 22) /* Bit 22: Continuous mode selection for regular conversions */ +#define SDADC_CR2_RSWSTART (1 << 23) /* Bit 23: Software start of a conversion on the regular channel */ +#define SDADC_CR2_FAST (1 << 24) /* Bit 24: Fast conversion mode selection */ + +/* SDADC interrupt and status register */ + +#define SDADC_ISR_EOCALF (1 << 0) /* Bit 0: End of calibration flag */ +#define SDADC_ISR_JEOCF (1 << 1) /* Bit 1: End of injected conversion flag */ +#define SDADC_ISR_JOVRF (1 << 2) /* Bit 2: Injected conversion overrun flag */ +#define SDADC_ISR_REOCF (1 << 3) /* Bit 3: End of regular conversion flag */ +#define SDADC_ISR_ROVRF (1 << 4) /* Bit 4: Regular conversion overrun flag */ +#define SDADC_ISR_CALIBIP (1 << 12) /* Bit 12: Calibration in progress status */ +#define SDADC_ISR_JCIP (1 << 13) /* Bit 13: Injected conversion in progress status */ +#define SDADC_ISR_RCIP (1 << 14) /* Bit 14: Regular conversion in progress status */ +#define SDADC_ISR_STABIP (1 << 15) /* Bit 15: Stabilization in progress status */ +#define SDADC_ISR_INITRDY (1 << 31) /* Bit 31: Initialization mode is ready */ + +/* SDADC interrupt and status clear register */ + +#define SDADC_CLRISR_CLREOCALF (1 << 0) /* Bit 0: Clear the end of calibration flag */ +#define SDADC_CLRISR_CLRJOVRF (1 << 2) /* Bit 2: Clear the injected conversion overrun flag */ +#define SDADC_CLRISR_CLRROVRF (1 << 4) /* Bit 4: Clear the regular conversion overrun flag */ + +/* SDADC injected channel group selection register */ + +#define SDADC_JCHGR_JCHG_SHIFT (0) /* Bit 0-8: Injected channel group selection */ +#define SDADC_JCHGR_JCHG_MASK (0x1ff << SDADC_JCHGR_JCHG_SHIFT) +#define SDADC_JCHGR_JCHG_CH(n) (1 << (n + SDADC_JCHGR_JCHG_SHIFT)) + +/* SDADC configuration 0-2 register */ + +#define SDADC_CONF0R 0 +#define SDADC_CONF1R 1 +#define SDADC_CONF2R 2 + +#define SDADC_CONFR_OFFSET_SHIFT (0) /* Bit 0-11: Twelve-bit calibration offset for configuration 0-2 */ +#define SDADC_CONFR_OFFSET_MASK (0xfff << SDADC_CONFR_OFFSET_SHIFT) +#define SDADC_CONFR_GAIN_SHIFT (20) /* Bit 20-22: Gain setting for configuration 0-2 */ +#define SDADC_CONFR_GAIN_MASK (0x7 << SDADC_CONFR_GAIN_SHIFT) +# define SDADC_CONFR_GAIN_1X (0 << SDADC_CONFR_GAIN_SHIFT) +# define SDADC_CONFR_GAIN_2X (1 << SDADC_CONFR_GAIN_SHIFT) +# define SDADC_CONFR_GAIN_4X (2 << SDADC_CONFR_GAIN_SHIFT) +# define SDADC_CONFR_GAIN_8X (3 << SDADC_CONFR_GAIN_SHIFT) +# define SDADC_CONFR_GAIN_16X (4 << SDADC_CONFR_GAIN_SHIFT) +# define SDADC_CONFR_GAIN_32X (5 << SDADC_CONFR_GAIN_SHIFT) +# define SDADC_CONFR_GAIN_0p5X (7 << SDADC_CONFR_GAIN_SHIFT) +#define SDADC_CONFR_SE_SHIFT (26) /* Bit 27-26: Single-ended mode for configuration 0-2 */ +#define SDADC_CONFR_SE_MASK (0x3 << SDADC_CONFR_SE_SHIFT) +# define SDADC_CONFR_SE_DIF (0 << SDADC_CONFR_SE_SHIFT) +# define SDADC_CONFR_SE_SE_OFFSET (1 << SDADC_CONFR_SE_SHIFT) +# define SDADC_CONFR_SE_SE_ZERO (3 << SDADC_CONFR_SE_SHIFT) +#define SDADC_CONFR_COMMON_SHIFT (30) /* Bit 30-31: Common mode for configuration 0-2 */ +#define SDADC_CONFR_COMMON_MASK (0x3 << SDADC_CONFR_COMMON_SHIFT) +# define SDADC_CONFR_COMMON_GND (0 << SDADC_CONFR_COMMON_SHIFT) +# define SDADC_CONFR_COMMON_VCM (1 << SDADC_CONFR_COMMON_SHIFT) +# define SDADC_CONFR_COMMON_VDD (2 << SDADC_CONFR_COMMON_SHIFT) + +/* SDADC channel configuration register 1 */ + +#define SDADC_CONFCHR1_CH_SHIFT(i) (2*i) /* Bit 0-1: Channel i configuration 0-7 */ +#define SDADC_CONFCHR1_CH_MASK(i) (0x3 << SDADC_CONFCHR1_CH_SHIFT(i)) + +/* SDADC channel configuration register 2 */ + +#define SDADC_CONFCHR2_CH8_SHIFT (0) /* Bit 0-1: Channel 8 configuration */ +#define SDADC_CONFCHR2_CH8_MASK (0x3 << SDADC_CONFCHR2_CH8_SHIFT) + +/* SDADC data register for injected group */ + +#define SDADC_JDATAR_JDATA_SHIFT (0) /* Bit 0-15: Injected group conversion data */ +#define SDADC_JDATAR_JDATA_MASK (0xffff << SDADC_JDATAR_JDATA_SHIFT) +#define SDADC_JDATAR_JDATACH_SHIFT (24) /* Bit 24-27: Injected channel most recently converted */ +#define SDADC_JDATAR_JDATACH_MASK (0xf << SDADC_JDATAR_JDATACH_SHIFT) + +/* SDADC data register for the regular channel */ + +#define SDADC_RDATAR_RDATA_SHIFT (0) /* Bit 0-15: Regular channel conversion data */ +#define SDADC_RDATAR_RDATA_MASK (0xffff << SDADC_RDATAR_RDATA_SHIFT) + +/* SDADC1 and SDADC2 injected data register */ + +#define SDADC_JDATA12R_JDATA1_SHIFT (0) /* Bit 0-15: Injected group conversion data for SDADC1 */ +#define SDADC_JDATA12R_JDATA1_MASK (0xffff << SDADC_JDATA12R_JDATA1_SHIFT) +#define SDADC_JDATA12R_JDATA2_SHIFT (16) /* Bit 16-31: Injected group conversion data for SDADC2 */ +#define SDADC_JDATA12R_JDATA2_MASK (0xffff << SDADC_JDATA12R_JDATA2_SHIFT) + +/* SDADC1 and SDADC2 regular data register */ + +#define SDADC_RDATA12R_RDATA1_SHIFT (0) /* Bit 0-15: Regular conversion data for SDADC1 */ +#define SDADC_RDATA12R_RDATA1_MASK (0xffff << SDADC_RDATA12R_RDATA1_SHIFT) +#define SDADC_RDATA12R_RDATA2_SHIFT (16) /* Bit 16-31: Regular conversion data for SDADC2 */ +#define SDADC_RDATA12R_RDATA2_MASK (0xffff << SDADC_RDATA12R_RDATA2_SHIFT) + +/* SDADC1 and SDADC3 injected data register */ + +#define SDADC_JDATA13R_JDATA1_SHIFT (0) /* Bit 0-15: Injected group conversion data for SDADC1 */ +#define SDADC_JDATA13R_JDATA1_MASK (0xffff << SDADC_JDATA13R_JDATA1_SHIFT) +#define SDADC_JDATA13R_JDATA3_SHIFT (16) /* Bit 16-31: Injected group conversion data for SDADC3 */ +#define SDADC_JDATA13R_JDATA3_MASK (0xffff << SDADC_JDATA13R_JDATA3_SHIFT) + +/* SDADC1 and SDADC3 regular data register */ + +#define SDADC_RDATA13R_RDATA1_SHIFT (0) /* Bit 0-15: Regular conversion data for SDADC1 */ +#define SDADC_RDATA13R_RDATA1_MASK (0xffff << SDADC_RDATA13R_RDATA1_SHIFT) +#define SDADC_RDATA13R_RDATA3_SHIFT (16) /* Bit 16-31: Regular conversion data for SDADC3 */ +#define SDADC_RDATA13R_RDATA3_MASK (0xffff << SDADC_RDATA13R_RDATA3_SHIFT) + +/**************************************************************************************************** + * Public Types + ****************************************************************************************************/ + +/**************************************************************************************************** + * Public Data + ****************************************************************************************************/ + +/**************************************************************************************************** + * Public Function Prototypes + ****************************************************************************************************/ + +#endif /* __ARCH_ARM_SRC_STM32_CHIP_STM32F37XXX_SDADC_H */ diff --git a/arch/arm/src/stm32/stm32.h b/arch/arm/src/stm32/stm32.h index af91ea4ea60..f2304e27350 100644 --- a/arch/arm/src/stm32/stm32.h +++ b/arch/arm/src/stm32/stm32.h @@ -61,6 +61,7 @@ #include "stm32_can.h" #include "stm32_dbgmcu.h" #include "stm32_dma.h" +#include "stm32_dac.h" #include "stm32_exti.h" #include "stm32_flash.h" #include "stm32_fsmc.h" diff --git a/arch/arm/src/stm32/stm32_adc.c b/arch/arm/src/stm32/stm32_adc.c index 2972ebaf9a6..acbb707d345 100644 --- a/arch/arm/src/stm32/stm32_adc.c +++ b/arch/arm/src/stm32/stm32_adc.c @@ -79,8 +79,8 @@ /* This implementation is for the STM32 F1, F2, F4 and STM32L15XX only */ #if defined(CONFIG_STM32_STM32F10XX) || defined(CONFIG_STM32_STM32F20XX) || \ - defined(CONFIG_STM32_STM32F30XX) || defined(CONFIG_STM32_STM32F40XX) || \ - defined(CONFIG_STM32_STM32L15XX) + defined(CONFIG_STM32_STM32F30XX) || defined(CONFIG_STM32_STM32F37XX) || \ + defined(CONFIG_STM32_STM32F40XX) || defined(CONFIG_STM32_STM32L15XX) /* At the moment there is no proper implementation for timers external * trigger in STM32L15XX May be added latter @@ -107,6 +107,9 @@ # define RCC_RSTR_ADC2RST RCC_AHBRSTR_ADC12RST # define RCC_RSTR_ADC3RST RCC_AHBRSTR_ADC34RST # define RCC_RSTR_ADC4RST RCC_AHBRSTR_ADC34RST +#elif defined(CONFIG_STM32_STM32F37XX) +# define STM32_RCC_RSTR STM32_RCC_APB2RSTR +# define RCC_RSTR_ADC1RST RCC_APB2RSTR_ADCRST #elif defined(CONFIG_STM32_STM32F20XX) || defined(CONFIG_STM32_STM32F40XX) # define STM32_RCC_RSTR STM32_RCC_APB2RSTR # define RCC_RSTR_ADC1RST RCC_APB2RSTR_ADCRST @@ -148,7 +151,7 @@ # define ADC_IER_AWD ADC_CR1_AWDIE # define ADC_ISR_JEOC ADC_SR_JEOC # define ADC_IER_JEOC ADC_CR1_JEOCIE -# ifdef CONFIG_STM32_STM32F10XX +# if defined(CONFIG_STM32_STM32F10XX) || defined(CONFIG_STM32_STM32F37XX) # define ADC_EXTREG_EXTEN_MASK ADC_CR2_EXTTRIG # define ADC_EXTREG_EXTEN_NONE 0 # define ADC_EXTREG_EXTEN_DEFAULT ADC_CR2_EXTTRIG @@ -180,7 +183,11 @@ #ifdef ADC_HAVE_DMA # define ADC_MAX_SAMPLES ADC_MAX_CHANNELS_DMA #else -# define ADC_MAX_SAMPLES ADC_MAX_CHANNELS_NODMA +# if defined(CONFIG_STM32_STM32F30XX) +# define ADC_MAX_SAMPLES ADC_MAX_CHANNELS_DMA /* Works without DMA should sampling frequency be reduced */ +# else +# define ADC_MAX_SAMPLES ADC_MAX_CHANNELS_NODMA +# endif #endif #if defined(CONFIG_STM32_STM32F20XX) || defined(CONFIG_STM32_STM32F40XX) @@ -219,7 +226,12 @@ (ADC_SMPR_DEFAULT << ADC_SMPR2_SMP8_SHIFT) | \ (ADC_SMPR_DEFAULT << ADC_SMPR2_SMP9_SHIFT)) #elif defined(CONFIG_STM32_STM32F30XX) -# define ADC_SMPR_DEFAULT ADC_SMPR_61p5 +# ifdef ADC_HAVE_DMA || (ADC_MAX_SAMPLES == 1) +# define ADC_SMPR_DEFAULT ADC_SMPR_61p5 +# else /* Slow down sampling frequency */ +# define ADC_SMPR_DEFAULT ADC_SMPR_601p5 +# endif + # define ADC_SMPR1_DEFAULT ((ADC_SMPR_DEFAULT << ADC_SMPR1_SMP1_SHIFT) | \ (ADC_SMPR_DEFAULT << ADC_SMPR1_SMP2_SHIFT) | \ (ADC_SMPR_DEFAULT << ADC_SMPR1_SMP3_SHIFT) | \ @@ -238,8 +250,13 @@ (ADC_SMPR_DEFAULT << ADC_SMPR2_SMP16_SHIFT) | \ (ADC_SMPR_DEFAULT << ADC_SMPR2_SMP17_SHIFT) | \ (ADC_SMPR_DEFAULT << ADC_SMPR2_SMP18_SHIFT)) -#elif defined(CONFIG_STM32_STM32F20XX) || defined(CONFIG_STM32_STM32F40XX) -# define ADC_SMPR_DEFAULT ADC_SMPR_112 +#elif defined(CONFIG_STM32_STM32F20XX) || defined(CONFIG_STM32_STM32F37XX) || \ + defined(CONFIG_STM32_STM32F40XX) +# if defined(CONFIG_STM32_STM32F37XX) +# define ADC_SMPR_DEFAULT ADC_SMPR_239p5 /* TODO choose 1p5? */ +# else +# define ADC_SMPR_DEFAULT ADC_SMPR_112 +# endif # define ADC_SMPR1_DEFAULT ((ADC_SMPR_DEFAULT << ADC_SMPR1_SMP10_SHIFT) | \ (ADC_SMPR_DEFAULT << ADC_SMPR1_SMP11_SHIFT) | \ (ADC_SMPR_DEFAULT << ADC_SMPR1_SMP12_SHIFT) | \ @@ -320,7 +337,8 @@ struct stm32_dev_s /* ADC Register access */ #if defined(CONFIG_STM32_STM32F20XX) || defined(CONFIG_STM32_STM32F30XX) || \ - defined(CONFIG_STM32_STM32F40XX) || defined(CONFIG_STM32_STM32L15XX) + defined(CONFIG_STM32_STM32F37XX) ||defined(CONFIG_STM32_STM32F40XX) || \ + defined(CONFIG_STM32_STM32L15XX) static void stm32_modifyreg32(unsigned int addr, uint32_t clrbits, uint32_t setbits); #endif @@ -587,7 +605,8 @@ static struct adc_dev_s g_adcdev4 = ****************************************************************************/ #if defined(CONFIG_STM32_STM32F20XX) || defined(CONFIG_STM32_STM32F30XX) || \ - defined(CONFIG_STM32_STM32F40XX) || defined(CONFIG_STM32_STM32L15XX) + defined(CONFIG_STM32_STM32F37XX) ||defined(CONFIG_STM32_STM32F40XX) || \ + defined(CONFIG_STM32_STM32L15XX) static void stm32_modifyreg32(unsigned int addr, uint32_t clrbits, uint32_t setbits) { @@ -1626,7 +1645,7 @@ static void adc_write_sample_time_registers(FAR struct adc_dev_s *dev) #endif /**************************************************************************** - * Name: adc_dmacovcallback + * Name: adc_dmaconvcallback * * Description: * Callback for DMA. Called from the DMA transfer complete interrupt after @@ -1850,7 +1869,7 @@ static void adc_reset(FAR struct adc_dev_s *dev) adc_modifyreg(priv, STM32_ADC_IER_OFFSET, clrbits, setbits); -#else +#else /* ifdef CONFIG_STM32_STM32F30XX */ /* Enable the analog watchdog */ @@ -1864,7 +1883,7 @@ static void adc_reset(FAR struct adc_dev_s *dev) clrbits |= ADC_CR1_DUALMOD_MASK; setbits |= ADC_CR1_IND; -#else +#elif (! defined(CONFIG_STM32_STM32F37XX)) /* Set the resolution of the conversion */ @@ -1880,10 +1899,16 @@ static void adc_reset(FAR struct adc_dev_s *dev) } #endif - /* Enable interrupt flags, but disable overrun interrupt */ + /* Enable interrupt flags, but disable overrun interrupt: TODO this is + * done later by upper half when opening device by adc_rxint(). + */ +#ifndef CONFIG_STM32_STM32F37XX clrbits |= ADC_IER_OVR; setbits |= ADC_IER_ALLINTS & ~ADC_IER_OVR; +#else + /* TODO NON DMA mode */ +#endif /* Set CR1 configuration */ @@ -1916,6 +1941,13 @@ static void adc_reset(FAR struct adc_dev_s *dev) clrbits |= ADC_EXTREG_EXTEN_MASK; setbits |= ADC_EXTREG_EXTEN_NONE; + /* Enable software trigger for regular channels */ + +#ifdef CONFIG_STM32_STM32F37XX + clrbits |= ADC_CR2_EXTSEL_MASK; + setbits |= ADC_CR2_EXTSEL_SWSTART | ADC_CR2_EXTTRIG; /* SW is considered as external trigger */ +#endif + #ifdef ADC_HAVE_DMA if (priv->hasdma) { @@ -2176,9 +2208,12 @@ static void adc_rxint(FAR struct adc_dev_s *dev, bool enable) if (enable) { - /* Enable the end-of-conversion ADC and analog watchdog interrupts */ + /* Enable the analog watchdog / overrun interrupts, and if no DMA, + * end-of-conversion ADC. + */ - adc_modifyreg(priv, STM32_ADC_IER_OFFSET, 0, ADC_IER_ALLINTS); + adc_modifyreg(priv, STM32_ADC_IER_OFFSET, 0, + priv->hasdma ? ADC_IER_AWD | ADC_ISR_OVR : ADC_IER_ALLINTS); } else { @@ -2766,8 +2801,10 @@ static int adc_interrupt(FAR struct adc_dev_s *dev) } } - regval &= ~pending; - adc_putreg(priv, STM32_ADC_ISR_OFFSET, regval); + /* by MR regval &= ~pending; */ + /* by MR adc_putreg(priv, STM32_ADC_ISR_OFFSET, regval); + + adc_putreg(priv, STM32_ADC_ISR_OFFSET, pending); */ return OK; } @@ -3039,8 +3076,8 @@ struct adc_dev_s *stm32_adcinitialize(int intf, FAR const uint8_t *chanlist, } #endif /* CONFIG_STM32_STM32F10XX || CONFIG_STM32_STM32F20XX || - * CONFIG_STM32_STM32F30XX || CONFIG_STM32_STM32F40XX || - * CONFIG_STM32_STM32L15XX + * CONFIG_STM32_STM32F30XX || CONFIG_STM32_STM32F47XX || + * CONFIG_STM32_STM32F40XX || CONFIG_STM32_STM32L15XX */ #endif /* CONFIG_STM32_ADC1 || CONFIG_STM32_ADC2 || * CONFIG_STM32_ADC3 || CONFIG_STM32_ADC4 diff --git a/arch/arm/src/stm32/stm32_adc.h b/arch/arm/src/stm32/stm32_adc.h index 25ad161b629..b2f4ee39189 100644 --- a/arch/arm/src/stm32/stm32_adc.h +++ b/arch/arm/src/stm32/stm32_adc.h @@ -48,6 +48,8 @@ #if defined(CONFIG_STM32_STM32F30XX) # include "chip/stm32f30xxx_adc.h" +#elif defined(CONFIG_STM32_STM32F37XX) +# include "chip/stm32f37xxx_adc.h" #else # include "chip/stm32_adc.h" #endif diff --git a/arch/arm/src/stm32/stm32_dac.c b/arch/arm/src/stm32/stm32_dac.c index 528faf1786c..fdcbaf050a9 100644 --- a/arch/arm/src/stm32/stm32_dac.c +++ b/arch/arm/src/stm32/stm32_dac.c @@ -348,7 +348,9 @@ struct stm32_chan_s uint8_t timer; /* Timer number 2-8 */ #endif uint8_t intf; /* DAC zero-based interface number (0 or 1) */ + uint32_t pin; /* Pin configuration */ uint32_t dro; /* Data output register */ + uint32_t cr; /* Control register */ uint32_t tsel; /* CR trigger select value */ #ifdef HAVE_DMA uint16_t dmachan; /* DMA channel needed by this DAC */ @@ -408,10 +410,20 @@ static const struct dac_ops_s g_dacops = }; #ifdef CONFIG_STM32_DAC1 +/* Channel 1 */ + static struct stm32_chan_s g_dac1priv = { .intf = 0, +#if STM32_NDAC < 2 + .pin = GPIO_DAC1_OUT, .dro = STM32_DAC_DHR12R1, + .cr = STM32_DAC_CR, +#else + .pin = GPIO_DAC1_OUT1, + .dro = STM32_DAC1_DHR12R1, + .cr = STM32_DAC1_CR, +#endif #ifdef CONFIG_STM32_DAC1_DMA .hasdma = 1, .dmachan = DAC1_DMA_CHAN, @@ -427,13 +439,21 @@ static struct dac_dev_s g_dac1dev = .ad_ops = &g_dacops, .ad_priv = &g_dac1priv, }; -#endif -#ifdef CONFIG_STM32_DAC2 +/* Channel 2 */ + static struct stm32_chan_s g_dac2priv = { .intf = 1, +#if STM32_NDAC < 2 + .pin = GPIO_DAC2_OUT, .dro = STM32_DAC_DHR12R2, + .cr = STM32_DAC_CR, +#else + .pin = GPIO_DAC1_OUT2, + .dro = STM32_DAC1_DHR12R2, + .cr = STM32_DAC1_CR, +#endif #ifdef CONFIG_STM32_DAC2_DMA .hasdma = 1, .dmachan = DAC2_DMA_CHAN, @@ -451,6 +471,24 @@ static struct dac_dev_s g_dac2dev = }; #endif +#ifdef CONFIG_STM32_DAC2 +/* Channel 1 */ + +static struct stm32_chan_s g_dac3priv = +{ + .intf = 2, + .pin = GPIO_DAC2_OUT1, + .dro = STM32_DAC2_DHR12R1, + .cr = STM32_DAC2_CR, +}; + +static struct dac_dev_s g_dac3dev = +{ + .ad_ops = &g_dacops, + .ad_priv = &g_dac3priv, +}; +#endif + static struct stm32_dac_s g_dacblock; /**************************************************************************** @@ -479,7 +517,7 @@ static inline void stm32_dac_modify_cr(FAR struct stm32_chan_s *chan, uint32_t shift; shift = chan->intf * 16; - modifyreg32(STM32_DAC_CR, clearbits << shift, setbits << shift); + modifyreg32(chan->cr, clearbits << shift, setbits << shift); } /**************************************************************************** @@ -738,16 +776,7 @@ static int dac_send(FAR struct dac_dev_s *dev, FAR struct dac_msg_s *msg) /* Non-DMA transfer */ putreg16(msg->am_data, chan->dro); -#ifdef CONFIG_STM32_DAC2 - if (chan->intf) - { - dac_txdone(&g_dac2dev); - } - else -#endif - { - dac_txdone(&g_dac1dev); - } + dac_txdone(dev); } /* Reset counters (generate an update) */ @@ -978,7 +1007,7 @@ static int dac_chaninit(FAR struct stm32_chan_s *chan) * should first be configured to analog (AIN)". */ - stm32_configgpio(chan->intf ? GPIO_DAC2_OUT : GPIO_DAC1_OUT); + stm32_configgpio(chan->pin); /* DAC channel configuration: * @@ -1041,7 +1070,7 @@ static int dac_chaninit(FAR struct stm32_chan_s *chan) * Name: dac_blockinit * * Description: - * All ioctl calls will be routed through this method. + * Initialize the DAC block. * * Input Parameters: * @@ -1055,7 +1084,7 @@ static int dac_blockinit(void) irqstate_t flags; uint32_t regval; - /* Has the DMA block already been initialized? */ + /* Has the DAC block already been initialized? */ if (g_dacblock.init) { @@ -1068,12 +1097,30 @@ static int dac_blockinit(void) flags = enter_critical_section(); regval = getreg32(STM32_RCC_APB1RSTR); +#if STM32_NDAC < 2 regval |= RCC_APB1RSTR_DACRST; +#else +#ifdef CONFIG_STM32_DAC1 + regval |= RCC_APB1RSTR_DAC1RST; +#endif +#ifdef CONFIG_STM32_DAC2 + regval |= RCC_APB1RSTR_DAC2RST; +#endif +#endif putreg32(regval, STM32_RCC_APB1RSTR); /* Take the DAC out of reset state */ +#if STM32_NDAC < 2 regval &= ~RCC_APB1RSTR_DACRST; +#else +#ifdef CONFIG_STM32_DAC1 + regval &= ~RCC_APB1RSTR_DAC1RST; +#endif +#ifdef CONFIG_STM32_DAC2 + regval &= ~RCC_APB1RSTR_DAC2RST; +#endif +#endif putreg32(regval, STM32_RCC_APB1RSTR); leave_critical_section(flags); @@ -1114,16 +1161,22 @@ FAR struct dac_dev_s *stm32_dacinitialize(int intf) #ifdef CONFIG_STM32_DAC1 if (intf == 1) { - ainfo("DAC1 Selected\n"); + ainfo("DAC1-1 Selected\n"); dev = &g_dac1dev; } else + if (intf == 2) + { + ainfo("DAC1-2 Selected\n"); + dev = &g_dac2dev; + } + else #endif #ifdef CONFIG_STM32_DAC2 - if (intf == 2) + if (intf == 3) { - ainfo("DAC2 Selected\n"); - dev = &g_dac2dev; + ainfo("DAC2-1 Selected\n"); + dev = &g_dac3dev; } else #endif diff --git a/arch/arm/src/stm32/stm32_i2c.h b/arch/arm/src/stm32/stm32_i2c.h index 05f57ee46fb..7274325f548 100644 --- a/arch/arm/src/stm32/stm32_i2c.h +++ b/arch/arm/src/stm32/stm32_i2c.h @@ -44,7 +44,7 @@ #include #include "chip.h" -#if defined(CONFIG_STM32_STM32F30XX) +#if defined(CONFIG_STM32_STM32F30XX) || defined(CONFIG_STM32_STM32F37XX) # include "chip/stm32f30xxx_i2c.h" #else # include "chip/stm32_i2c.h" diff --git a/arch/arm/src/stm32/stm32_pwr.c b/arch/arm/src/stm32/stm32_pwr.c index 5eda6c08ccc..13fbdb34706 100644 --- a/arch/arm/src/stm32/stm32_pwr.c +++ b/arch/arm/src/stm32/stm32_pwr.c @@ -76,6 +76,46 @@ static inline void stm32_pwr_modifyreg(uint8_t offset, uint16_t clearbits, uint1 * Public Functions ************************************************************************************/ +/************************************************************************************ + * Name: stm32_pwr_enablesdadc + * + * Description: + * Enables SDADC power + * + * Input Parameters: + * sdadc - SDADC number 1-3 + * + * Returned Value: + * None + * + ************************************************************************************/ + +#if defined(CONFIG_STM32_STM32F37XX) +void stm32_pwr_enablesdadc(uint8_t sdadc) +{ + uint32_t setbits = 0; + + switch (sdadc) + { + case 1: + setbits = PWR_CR_ENSD1; + break; + + case 2: + setbits = PWR_CR_ENSD2; + break; + + case 3: + setbits = PWR_CR_ENSD3; + break; + } + + stm32_pwr_modifyreg(STM32_PWR_CR_OFFSET, 0, setbits); + +} +#endif + + /************************************************************************************ * Name: stm32_pwr_enablebkp * diff --git a/arch/arm/src/stm32/stm32_pwr.h b/arch/arm/src/stm32/stm32_pwr.h index 344834c0678..700dd602945 100644 --- a/arch/arm/src/stm32/stm32_pwr.h +++ b/arch/arm/src/stm32/stm32_pwr.h @@ -66,6 +66,24 @@ extern "C" * Public Functions ************************************************************************************/ +/************************************************************************************ + * Name: stm32_pwr_enablesdadc + * + * Description: + * Enables SDADC power + * + * Input Parameters: + * sdadc - SDADC number 1-3 + * + * Returned Value: + * None + * + ************************************************************************************/ + +#if defined(CONFIG_STM32_STM32F37XX) +void stm32_pwr_enablesdadc(uint8_t sdadc); +#endif + /************************************************************************************ * Name: stm32_pwr_enablebkp * diff --git a/arch/arm/src/stm32/stm32_sdadc.c b/arch/arm/src/stm32/stm32_sdadc.c new file mode 100644 index 00000000000..a16cade9cd2 --- /dev/null +++ b/arch/arm/src/stm32/stm32_sdadc.c @@ -0,0 +1,1456 @@ +/**************************************************************************** + * arch/arm/src/stm32/stm32_sdadc.c + * + * Copyright (C) 2011, 2013, 2015-2016 Gregory Nutt. All rights reserved. + * Copyright (C) 2016 Studelec. All rights reserved. + * Authors: Gregory Nutt + * Marc Rechté + * + * derived from arch/arm/src/stm32/stm32_adc.c + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include "up_internal.h" +#include "up_arch.h" + +#include "chip.h" +#include "stm32.h" +#include "stm32_dma.h" +#include "stm32_pwr.h" +#include "stm32_sdadc.h" + +#ifdef CONFIG_STM32_SDADC + +/* Some SDADC peripheral must be enabled */ + +#if defined(CONFIG_STM32_SDADC1) || defined(CONFIG_STM32_SDADC2) || \ + defined(CONFIG_STM32_SDADC3) + +/* This implementation is for the STM32F37XX only */ + +#ifndef CONFIG_STM32_STM32F37XX +# error "This chip is not yet supported" +#endif + +/* TODO: At the moment there is no implementation + for timer and external triggers */ + +#if defined(SDADC_HAVE_TIMER) +# error "There is no proper implementation for TIMER TRIGGERS at the moment" +#endif + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ +/* RCC reset ****************************************************************/ + +#define STM32_RCC_RSTR STM32_RCC_APB2RSTR +#define RCC_RSTR_SDADC1RST RCC_APB2RSTR_SDADC1RST +#define RCC_RSTR_SDADC2RST RCC_APB2RSTR_SDADC2RST +#define RCC_RSTR_SDADC3RST RCC_APB2RSTR_SDADC3RST + +/* SDADC interrupts *********************************************************/ + +#define SDADC_ISR_ALLINTS (SDADC_ISR_JEOCF | SDADC_ISR_JOVRF) + +/* SDADC Channels/DMA *******************************************************/ + + +#define SDADC_DMA_CONTROL_WORD (DMA_CCR_MSIZE_16BITS | \ + DMA_CCR_PSIZE_16BITS | \ + DMA_CCR_MINC | \ + DMA_CCR_CIRC) + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/* This structure describes the state of one SDADC block */ + +struct stm32_dev_s +{ + FAR const struct adc_callback_s *cb; + uint8_t irq; /* Interrupt generated by this SDADC block */ + uint8_t nchannels; /* Number of channels */ + uint8_t cchannels; /* Number of configured channels */ + uint8_t intf; /* SDADC interface number */ + uint8_t current; /* Current SDADC channel being converted */ + uint8_t refv; /* Reference voltage selection */ +#ifdef SDADC_HAVE_DMA + uint8_t dmachan; /* DMA channel needed by this SDADC */ + bool hasdma; /* True: This channel supports DMA */ +#endif +#ifdef SDADC_HAVE_TIMER + uint8_t trigger; /* Timer trigger selection: see SDADCx_JEXTSEL_TIMxx */ +#endif + xcpt_t isr; /* Interrupt handler for this SDADC block */ + uint32_t base; /* Base address of registers unique to this SDADC + * block */ +#ifdef SDADC_HAVE_TIMER + uint32_t tbase; /* Base address of timer used by this SDADC block */ + uint32_t jextsel /* JEXTSEL value used by this SDADC block */ + uint32_t pclck; /* The PCLK frequency that drives this timer */ + uint32_t freq; /* The desired frequency of conversions */ +#endif +#ifdef SDADC_HAVE_DMA + DMA_HANDLE dma; /* Allocated DMA channel */ + + /* DMA transfer buffer */ + + int16_t dmabuffer[SDADC_MAX_SAMPLES]; +#endif + + /* List of selected SDADC injected channels to sample */ + + uint8_t chanlist[SDADC_MAX_SAMPLES]; +}; + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +/* ADC Register access */ + +static uint32_t sdadc_getreg(FAR struct stm32_dev_s *priv, int offset); +static void sdadc_putreg(FAR struct stm32_dev_s *priv, int offset, + uint32_t value); +static void sdadc_modifyreg(FAR struct stm32_dev_s *priv, int offset, + uint32_t clrbits, uint32_t setbits); +#ifdef ADC_HAVE_TIMER +static uint16_t tim_getreg(FAR struct stm32_dev_s *priv, int offset); +static void tim_putreg(FAR struct stm32_dev_s *priv, int offset, + uint16_t value); +static void tim_modifyreg(FAR struct stm32_dev_s *priv, int offset, + uint16_t clrbits, uint16_t setbits); +static void tim_dumpregs(FAR struct stm32_dev_s *priv, + FAR const char *msg); +#endif + +static void sdadc_rccreset(FAR struct stm32_dev_s *priv, bool reset); + +/* ADC Interrupt Handler */ + +static int sdadc_interrupt(FAR struct adc_dev_s *dev); +#if defined(CONFIG_STM32_SDADC1) +static int sdadc1_interrupt(int irq, FAR void *context); +#endif +#if defined(CONFIG_STM32_SDADC2) +static int sdadc2_interrupt(int irq, FAR void *context); +#endif +#if defined(CONFIG_STM32_SDADC3) +static int sdadc3_interrupt(int irq, FAR void *context); +#endif + +/* ADC Driver Methods */ + +static int sdadc_bind(FAR struct adc_dev_s *dev, + FAR const struct adc_callback_s *callback); +static void sdadc_reset(FAR struct adc_dev_s *dev); +static int sdadc_setup(FAR struct adc_dev_s *dev); +static void sdadc_shutdown(FAR struct adc_dev_s *dev); +static void sdadc_rxint(FAR struct adc_dev_s *dev, bool enable); +static int sdadc_ioctl(FAR struct adc_dev_s *dev, int cmd, + unsigned long arg); +static void sdadc_enable(FAR struct stm32_dev_s *priv, bool enable); + +static int sdadc_set_ch(FAR struct adc_dev_s *dev, uint8_t ch); + +#ifdef ADC_HAVE_TIMER +static void sdadc_timstart(FAR struct stm32_dev_s *priv, bool enable); +static int sdadc_timinit(FAR struct stm32_dev_s *priv); +#endif + +#ifdef ADC_HAVE_DMA +static void sdadc_dmaconvcallback(DMA_HANDLE handle, uint8_t isr, + FAR void *arg); +#endif + +static void sdadc_startconv(FAR struct stm32_dev_s *priv, bool enable); + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/* SDADC interface operations */ + +static const struct adc_ops_s g_sdadcops = +{ + .ao_bind = sdadc_bind, + .ao_reset = sdadc_reset, + .ao_setup = sdadc_setup, + .ao_shutdown = sdadc_shutdown, + .ao_rxint = sdadc_rxint, + .ao_ioctl = sdadc_ioctl, +}; + +/* SDADC1 state */ + +#ifdef CONFIG_STM32_SDADC1 +static struct stm32_dev_s g_sdadcpriv1 = +{ + .irq = STM32_IRQ_SDADC1, + .isr = sdadc1_interrupt, + .intf = 1, + .base = STM32_SDADC1_BASE, + .refv = SDADC1_REFV, +#ifdef SDADC1_HAVE_TIMER + .trigger = CONFIG_STM32_SDADC1_TIMTRIG, + .tbase = SDADC1_TIMER_BASE, + .extsel = SDADC1_EXTSEL_VALUE, + .pclck = SDADC1_TIMER_PCLK_FREQUENCY, + .freq = CONFIG_STM32_SDADC1_SAMPLE_FREQUENCY, +#endif +#ifdef SDADC1_HAVE_DMA + .dmachan = DMACHAN_SDADC1, + .hasdma = true, +#endif +}; + +static struct adc_dev_s g_sdadcdev1 = +{ + .ad_ops = &g_sdadcops, + .ad_priv = &g_sdadcpriv1, +}; +#endif + +/* SDADC2 state */ + +#ifdef CONFIG_STM32_SDADC2 +static struct stm32_dev_s g_sdadcpriv2 = +{ + .irq = STM32_IRQ_SDADC2, + .isr = sdadc2_interrupt, + .intf = 2, + .base = STM32_SDADC2_BASE, + .refv = SDADC2_REFV, +#ifdef SDADC2_HAVE_TIMER + .trigger = CONFIG_STM32_SDADC2_TIMTRIG, + .tbase = SDADC2_TIMER_BASE, + .extsel = SDADC2_EXTSEL_VALUE, + .pclck = SDADC2_TIMER_PCLK_FREQUENCY, + .freq = CONFIG_STM32_SDADC2_SAMPLE_FREQUENCY, +#endif +#ifdef SDADC2_HAVE_DMA + .dmachan = DMACHAN_SDADC2, + .hasdma = true, +#endif +}; + +static struct adc_dev_s g_sdadcdev2 = +{ + .ad_ops = &g_sdadcops, + .ad_priv = &g_sdadcpriv2, +}; +#endif + +/* SDADC3 state */ + +#ifdef CONFIG_STM32_SDADC3 +static struct stm32_dev_s g_sdadcpriv3 = +{ + .irq = STM32_IRQ_SDADC3, + .isr = sdadc3_interrupt, + .intf = 3, + .base = STM32_SDADC3_BASE, + .refv = SDADC3_REFV, +#ifdef SDADC3_HAVE_TIMER + .trigger = CONFIG_STM32_SDADC3_TIMTRIG, + .tbase = SDADC3_TIMER_BASE, + .extsel = SDADC3_EXTSEL_VALUE, + .pclck = SDADC3_TIMER_PCLK_FREQUENCY, + .freq = CONFIG_STM32_SDADC3_SAMPLE_FREQUENCY, +#endif +#ifdef SDADC3_HAVE_DMA + .dmachan = DMACHAN_SDADC3, + .hasdma = true, +#endif +}; + +static struct adc_dev_s g_sdadcdev3 = +{ + .ad_ops = &g_sdadcops, + .ad_priv = &g_sdadcpriv3, +}; +#endif + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: sdadc_getreg + * + * Description: + * Read the value of an SDADC register. + * + * Input Parameters: + * priv - A reference to the SDADC block state + * offset - The offset to the register to read + * + * Returned Value: + * The current contents of the specified register + * + ****************************************************************************/ + +static uint32_t sdadc_getreg(FAR struct stm32_dev_s *priv, int offset) +{ + return getreg32(priv->base + offset); +} + +/**************************************************************************** + * Name: sdadc_putreg + * + * Description: + * Write a value to an SDADC register. + * + * Input Parameters: + * priv - A reference to the SDADC block state + * offset - The offset to the register to write to + * value - The value to write to the register + * + * Returned Value: + * None + * + ****************************************************************************/ + +static void sdadc_putreg(FAR struct stm32_dev_s *priv, int offset, + uint32_t value) +{ + putreg32(value, priv->base + offset); +} + +/**************************************************************************** + * Name: sdadc_modifyreg + * + * Description: + * Modify the value of an SDADC register (not atomic). + * + * Input Parameters: + * priv - A reference to the SDADC block state + * offset - The offset to the register to modify + * clrbits - The bits to clear + * setbits - The bits to set + * + * Returned Value: + * None + * + ****************************************************************************/ + +static void sdadc_modifyreg(FAR struct stm32_dev_s *priv, int offset, + uint32_t clrbits, uint32_t setbits) +{ + sdadc_putreg(priv, offset, (sdadc_getreg(priv, offset) & ~clrbits) | setbits); +} + +/**************************************************************************** + * Name: tim_getreg + * + * Description: + * Read the value of an SDADC timer register. + * + * Input Parameters: + * priv - A reference to the SDADC block state + * offset - The offset to the register to read + * + * Returned Value: + * The current contents of the specified register + * + ****************************************************************************/ + +#ifdef SDADC_HAVE_TIMER +static uint16_t tim_getreg(FAR struct stm32_dev_s *priv, int offset) +{ + return getreg16(priv->tbase + offset); +} +#endif + +/**************************************************************************** + * Name: tim_putreg + * + * Description: + * Write a value to an SDADC timer register. + * + * Input Parameters: + * priv - A reference to the SDADC block state + * offset - The offset to the register to write to + * value - The value to write to the register + * + * Returned Value: + * None + * + ****************************************************************************/ + +#ifdef SDADC_HAVE_TIMER +static void tim_putreg(FAR struct stm32_dev_s *priv, int offset, + uint16_t value) +{ + putreg16(value, priv->tbase + offset); +} +#endif + +/**************************************************************************** + * Name: tim_modifyreg + * + * Description: + * Modify the value of an SDADC timer register (not atomic). + * + * Input Parameters: + * priv - A reference to the SDADC block state + * offset - The offset to the register to modify + * clrbits - The bits to clear + * setbits - The bits to set + * + * Returned Value: + * None + * + ****************************************************************************/ + +#ifdef SDADC_HAVE_TIMER +static void tim_modifyreg(FAR struct stm32_dev_s *priv, int offset, + uint16_t clrbits, uint16_t setbits) +{ + tim_putreg(priv, offset, (tim_getreg(priv, offset) & ~clrbits) | setbits); +} +#endif + +/**************************************************************************** + * Name: tim_dumpregs + * + * Description: + * Dump all timer registers. + * + * Input parameters: + * priv - A reference to the SDADC block state + * + * Returned Value: + * None + * + ****************************************************************************/ + +#ifdef SDADC_HAVE_TIMER +static void tim_dumpregs(FAR struct stm32_dev_s *priv, FAR const char *msg) +{ + ainfo("%s:\n", msg); + + /* TODO */ +} +#endif + +/**************************************************************************** + * Name: sdadc_timstart + * + * Description: + * Start (or stop) the timer counter + * + * Input Parameters: + * priv - A reference to the SDADC block state + * enable - True: Start conversion + * + * Returned Value: + * + ****************************************************************************/ + +#ifdef SDADC_HAVE_TIMER +static void sdadc_timstart(FAR struct stm32_dev_s *priv, bool enable) +{ + ainfo("enable: %d\n", enable ? 1 : 0); + + if (enable) + { + /* Start the counter */ + + tim_modifyreg(priv, STM32_GTIM_CR1_OFFSET, 0, GTIM_CR1_CEN); + } + else + { + /* Disable the counter */ + + tim_modifyreg(priv, STM32_GTIM_CR1_OFFSET, GTIM_CR1_CEN, 0); + } +} +#endif + +/**************************************************************************** + * Name: sdadc_timinit + * + * Description: + * Initialize the timer that drivers the SDADC sampling for this channel + * using the pre-calculated timer divider definitions. + * + * Input Parameters: + * priv - A reference to the SDADC block state + * + * Returned Value: + * Zero on success; a negated errno value on failure. + * + ****************************************************************************/ + +#ifdef SDADC_HAVE_TIMER +static int sdadc_timinit(FAR struct stm32_dev_s *priv) +{ + /* TODO */ + + aerr("ERROR: not implemented"); + return ERROR; +} +#endif + +/**************************************************************************** + * Name: sdadc_startconv + * + * Description: + * Start (or stop) the SDADC conversion process + * + * Input Parameters: + * priv - A reference to the SDADC block state + * enable - True: Start conversion + * + * Returned Value: + * + ****************************************************************************/ + +static void sdadc_startconv(FAR struct stm32_dev_s *priv, bool enable) +{ + ainfo("enable: %d\n", enable ? 1 : 0); + + if (enable) + { + /* Start the conversion of injected channels */ + + sdadc_modifyreg(priv, STM32_SDADC_CR2_OFFSET, 0, SDADC_CR2_JSWSTART); + } + else + { + /* Wait for a possible conversion to stop */ + + while ((sdadc_getreg(priv, STM32_SDADC_ISR_OFFSET) & SDADC_ISR_JCIP) != 0); + } +} + +/**************************************************************************** + * Name: sdadc_rccreset + * + * Description: + * (De)Initializes the SDADC block registers to their default + * reset values. + * + * Input Parameters: + * priv - A reference to the SDADC block state + * reset - true: to put in reset state, false: to revert to normal state + * + * Returned Value: + * + ****************************************************************************/ + +static void sdadc_rccreset(FAR struct stm32_dev_s *priv, bool reset) +{ + uint32_t adcbit; + + /* Pick the appropriate bit in the APB2 reset register. + */ + + switch (priv->intf) + { +#ifdef CONFIG_STM32_SDADC1 + case 1: + adcbit = RCC_RSTR_SDADC1RST; + break; +#endif +#ifdef CONFIG_STM32_SDADC2 + case 2: + adcbit = RCC_RSTR_SDADC2RST; + break; +#endif +#ifdef CONFIG_STM32_SDADC3 + case 3: + adcbit = RCC_RSTR_SDADC3RST; + break; +#endif + default: + return; + } + + /* Set or clear the selected bit in the APB2 reset register. + * modifyreg32() disables interrupts. Disabling interrupts is necessary + * because the APB2RSTR register is used by several different drivers. + */ + + if (reset) + { + /* Enable SDADC reset state */ + + modifyreg32(STM32_RCC_RSTR, 0, adcbit); + } + else + { + /* Release SDADC from reset state */ + + modifyreg32(STM32_RCC_RSTR, adcbit, 0); + } +} + +/**************************************************************************** + * Name: sdadc_power_down_idle + * + * Description : Enables or disables power down during the idle phase. + * + * Input Parameters: + * priv - A reference to the SDADC block state + * pdi_high - true: The SDADC is powered down when waiting for a start event + * false: The SDADC is powered up when waiting for a start event + * + * Returned Value: + * None. + * + ****************************************************************************/ + +#if 0 +static void sdadc_power_down_idle(FAR struct stm32_dev_s *priv, bool pdi_high) +{ + uint32_t regval; + + ainfo("PDI: %d\n", pdi_high ? 1 : 0); + + regval = sdadc_getreg(priv, STM32_SDADC_CR2_OFFSET); + + if ((regval & SDADC_CR2_ADON) == 0) + { + regval = sdadc_getreg(priv, STM32_SDADC_CR1_OFFSET); + if (pdi_high) + { + regval |= SDADC_CR1_PDI; + } + else + { + regval &= ~SDADC_CR1_PDI; + } + + sdadc_putreg(priv, STM32_SDADC_CR1_OFFSET, regval); + } +} +#endif + +/**************************************************************************** + * Name: sdadc_enable + * + * Description : Enables or disables the specified SDADC peripheral. + * Does not start conversion unless the SDADC is + * triggered by timer + * + * Input Parameters: + * priv - A reference to the SDADC block state + * enable - true: enable SDADC conversion + * false: disable SDADC conversion + * + * Returned Value: + * + ****************************************************************************/ + +static void sdadc_enable(FAR struct stm32_dev_s *priv, bool enable) +{ + uint32_t regval; + + ainfo("enable: %d\n", enable ? 1 : 0); + + regval = sdadc_getreg(priv, STM32_SDADC_CR2_OFFSET); + + if (enable) + { + /* Enable the SDADC */ + + sdadc_putreg(priv, STM32_SDADC_CR2_OFFSET, regval | SDADC_CR2_ADON); + + /* Wait for the SDADC to be stabilized */ + + while (sdadc_getreg(priv, STM32_SDADC_ISR_OFFSET) & SDADC_ISR_STABIP); + } + else if ((regval & SDADC_CR2_ADON) != 0) + { + /* Ongoing conversions will be stopped implicitly */ + + /* Disable the SDADC */ + + sdadc_putreg(priv, STM32_SDADC_CR2_OFFSET, regval & ~SDADC_CR2_ADON); + + } +} + +/**************************************************************************** + * Name: sdadc_dmaconvcallback + * + * Description: + * Callback for DMA. Called from the DMA transfer complete interrupt after + * all channels have been converted and transferred with DMA. + * + * Input Parameters: + * handle - handle to DMA + * isr - + * arg - SDADC device + * + * Returned Value: + * + ****************************************************************************/ + +#ifdef SDADC_HAVE_DMA +static void sdadc_dmaconvcallback(DMA_HANDLE handle, uint8_t isr, FAR void *arg) +{ + FAR struct adc_dev_s *dev = (FAR struct adc_dev_s *)arg; + FAR struct stm32_dev_s *priv = (FAR struct stm32_dev_s *)dev->ad_priv; + int i; + + /* Verify that the upper-half driver has bound its callback functions */ + + if (priv->cb != NULL) + { + DEBUGASSERT(priv->cb->au_receive != NULL); + + for (i = 0; i < priv->nchannels; i++) + { + priv->cb->au_receive(dev, priv->chanlist[priv->current], + priv->dmabuffer[priv->current]); + priv->current++; + if (priv->current >= priv->nchannels) + { + /* Restart the conversion sequence from the beginning */ + + priv->current = 0; + } + } + } +} +#endif + +/**************************************************************************** + * Name: sdadc_bind + * + * Description: + * Bind the upper-half driver callbacks to the lower-half implementation. + * This must be called early in order to receive SDADC event notifications. + * + ****************************************************************************/ + +static int sdadc_bind(FAR struct adc_dev_s *dev, + FAR const struct adc_callback_s *callback) +{ + FAR struct stm32_dev_s *priv = (FAR struct stm32_dev_s *)dev->ad_priv; + + DEBUGASSERT(priv != NULL); + priv->cb = callback; + return OK; +} + +/**************************************************************************** + * Name: sdadc_reset + * + * Description: + * Reset the SDADC device. + * This is firstly called whenever the SDADC device is registered by + * sdadc_register() + * Does mostly the SDAC register setting. + * Leave the device in power down mode. + * Note that SDACx clock is already enable (for all SDADC) by the + * rcc_enableapb2() + * + * Input Parameters: + * dev - pointer to the sdadc device structure + * + * Returned Value: + * + ****************************************************************************/ + +static void sdadc_reset(FAR struct adc_dev_s *dev) +{ + FAR struct stm32_dev_s *priv = (FAR struct stm32_dev_s *)dev->ad_priv; + irqstate_t flags; + uint32_t setbits = 0; + + ainfo("intf: %d\n", priv->intf); + + /* TODO: why critical ? */ + + flags = enter_critical_section(); + + /* Enable SDADC reset state */ + + sdadc_rccreset(priv, true); + + /* Enable power */ + + stm32_pwr_enablesdadc(priv->intf); + + /* Release SDADC from reset state */ + + sdadc_rccreset(priv, false); + + /* Enable the SDADC (and wait it stabilizes) */ + + sdadc_enable(priv, true); + + /* Put SDADC in in initialization mode */ + + sdadc_putreg(priv, STM32_SDADC_CR1_OFFSET, SDADC_CR1_INIT); + + /* Wait for the SDADC to be ready */ + + while ((sdadc_getreg(priv, STM32_SDADC_ISR_OFFSET) & SDADC_ISR_INITRDY) == 0); + + /* Load configurations */ + + sdadc_putreg(priv, STM32_SDADC_CONF0R_OFFSET, SDADC_CONF0R_DEFAULT); + sdadc_putreg(priv, STM32_SDADC_CONF1R_OFFSET, SDADC_CONF1R_DEFAULT); + sdadc_putreg(priv, STM32_SDADC_CONF2R_OFFSET, SDADC_CONF2R_DEFAULT); + + sdadc_putreg(priv, STM32_SDADC_CONFCHR1_OFFSET, SDADC_CONFCHR1_DEFAULT); + sdadc_putreg(priv, STM32_SDADC_CONFCHR2_OFFSET, SDADC_CONFCHR2_DEFAULT); + + /* Configuration of the injected channels group */ + + sdadc_set_ch(dev, 0); + + /* CR1 ********************************************************************/ + + /* Enable interrupt / dma flags, is done later by upper half when opening + * device by calling sdadc_rxint() + */ + + setbits = SDADC_CR1_INIT; /* remains in init mode while configuring */ + + /* Reference voltage */ + + setbits |= priv->refv; + + /* Set CR1 configuration */ + + sdadc_putreg(priv, STM32_SDADC_CR1_OFFSET, setbits); + + /* CR2 ********************************************************************/ + + setbits = SDADC_CR2_ADON; // leave it ON ! + + /* TODO: JEXTEN / JEXTSEL */ + + /* Number of calibrations is for 3 configurations */ + + setbits |= (2 << SDADC_CR2_CALIBCNT_SHIFT); + + /* Set CR2 configuration */ + + sdadc_putreg(priv, STM32_SDADC_CR2_OFFSET, setbits); + + /* Release INIT mode ******************************************************/ + + sdadc_modifyreg(priv, STM32_SDADC_CR1_OFFSET, SDADC_CR1_INIT, 0); + + /* Calibrate the SDADC */ + + sdadc_modifyreg(priv, STM32_SDADC_CR2_OFFSET, 0, SDADC_CR2_STARTCALIB); + + /* Wait for the calibration to complete (may take up to 5ms) */ + + while ((sdadc_getreg(priv, STM32_SDADC_ISR_OFFSET) & SDADC_ISR_EOCALF) == 0); + + /* Clear this flag */ + + sdadc_modifyreg(priv, STM32_SDADC_CLRISR_OFFSET, SDADC_CLRISR_CLREOCALF, 0); + +#ifdef SDADC_HAVE_TIMER + if (priv->tbase != 0) + { + ret = sdadc_timinit(priv); + if (ret < 0) + { + aerr("ERROR: sdadc_timinit failed: %d\n", ret); + } + } +#endif + + /* Put the device in low power mode until it is actually used by + * application code. + */ + + sdadc_enable(priv, false); + + leave_critical_section(flags); + + ainfo("CR1: 0x%08x CR2: 0x%08x\n", + sdadc_getreg(priv, STM32_SDADC_CR1_OFFSET), + sdadc_getreg(priv, STM32_SDADC_CR2_OFFSET)); + + ainfo("CONF0R: 0x%08x CONF1R: 0x%08x CONF3R: 0x%08x\n", + sdadc_getreg(priv, STM32_SDADC_CONF0R_OFFSET), + sdadc_getreg(priv, STM32_SDADC_CONF1R_OFFSET), + sdadc_getreg(priv, STM32_SDADC_CONF2R_OFFSET)); + + ainfo("CONFCHR1: 0x%08x CONFCHR2: 0x%08x JCHGR: 0x%08x\n", + sdadc_getreg(priv, STM32_SDADC_CONFCHR1_OFFSET), + sdadc_getreg(priv, STM32_SDADC_CONFCHR2_OFFSET), + sdadc_getreg(priv, STM32_SDADC_JCHGR_OFFSET)); +} + +/**************************************************************************** + * Name: sdadc_setup + * + * Description: + * Configure the ADC. This method is called the first time that the SDADC + * device is opened. + * This is called by the upper half driver sdadc_open(). + * This will occur when the port is first + * opened in the application code (/dev/sdadcN). + * It would be called again after closing all references to this file and + * reopening it. + * This function wakes up the device and setup the DMA / IRQ + * + * Input Parameters: + * dev - pointer to the sdadc device structure + * + * Returned Value: + * + ****************************************************************************/ + +static int sdadc_setup(FAR struct adc_dev_s *dev) +{ + FAR struct stm32_dev_s *priv = (FAR struct stm32_dev_s *)dev->ad_priv; + int ret; + + /* Wakes up the device */ + + sdadc_enable(priv, true); + + /* Setup DMA or interrupt control. Note that either DMA or interrupt is + * setup not both. + */ + +#ifdef SDADC_HAVE_DMA + if (priv->hasdma) + { + /* Setup DMA */ + /* Stop and free DMA if it was started before */ + + if (priv->dma != NULL) + { + stm32_dmastop(priv->dma); + stm32_dmafree(priv->dma); + } + + priv->dma = stm32_dmachannel(priv->dmachan); + + stm32_dmasetup(priv->dma, + priv->base + STM32_SDADC_JDATAR_OFFSET, + (uint32_t)priv->dmabuffer, + priv->nchannels, + SDADC_DMA_CONTROL_WORD); + + stm32_dmastart(priv->dma, sdadc_dmaconvcallback, dev, false); + } + else + { + /* Attach the SDADC interrupt */ + + ret = irq_attach(priv->irq, priv->isr); + if (ret < 0) + { + ainfo("irq_attach failed: %d\n", ret); + return ret; + } + } +#else + /* Attach the SDADC interrupt */ + + ret = irq_attach(priv->irq, priv->isr); + if (ret < 0) + { + ainfo("irq_attach failed: %d\n", ret); + return ret; + } +#endif + + return OK; +} + +/**************************************************************************** + * Name: sdadc_shutdown + * + * Description: + * Disable the ADC. This method is called when the last instance + * of the SDADC device is closed by the user application. + * This method reverses the operation the setup method. + * + * Input Parameters: + * dev - pointer to the sdadc device structure + * + * Returned Value: + * + ****************************************************************************/ + +static void sdadc_shutdown(FAR struct adc_dev_s *dev) +{ + FAR struct stm32_dev_s *priv = (FAR struct stm32_dev_s *)dev->ad_priv; + + /* Put the device in low power mode */ + + sdadc_enable(priv, false); + + /* Disable intrerrupt / dma */ + + sdadc_rxint(dev, false); + +#ifdef SDADC_HAVE_DMA + if (priv->hasdma) + { + /* Stop and free DMA if it was started before */ + + if (priv->dma != NULL) + { + stm32_dmastop(priv->dma); + stm32_dmafree(priv->dma); + } + } + else + { + /* Disable ADC interrupts and detach the SDADC interrupt handler */ + + up_disable_irq(priv->irq); + irq_detach(priv->irq); + } +#else + /* Disable ADC interrupts and detach the SDADC interrupt handler */ + + up_disable_irq(priv->irq); + irq_detach(priv->irq); +#endif +} + +/**************************************************************************** + * Name: sdadc_rxint + * + * Description: + * Call to enable or disable RX interrupts. + * + * Input Parameters: + * + * Returned Value: + * + ****************************************************************************/ + +static void sdadc_rxint(FAR struct adc_dev_s *dev, bool enable) +{ + FAR struct stm32_dev_s *priv = (FAR struct stm32_dev_s *)dev->ad_priv; + uint32_t setbits; + + ainfo("intf: %d enable: %d\n", priv->intf, enable ? 1 : 0); + + /* DMA mode */ + +#ifdef SDADC_HAVE_DMA + if (priv->hasdma) + { + setbits = SDADC_CR1_JDMAEN; // DMA enabled for injected channels group + } + else + { + /* Interrupt enable for injected channel group overrun + and end of conversion */ + setbits = SDADC_CR1_JOVRIE | SDADC_CR1_JEOCIE; + } +#else + setbits = SDADC_CR1_JOVRIE | SDADC_CR1_JEOCIE; +#endif + + if (enable) + { + /* Enable */ + + sdadc_modifyreg(priv, STM32_SDADC_CR1_OFFSET, 0, setbits); + } + else + { + /* Disable all ADC interrupts and DMA */ + + sdadc_modifyreg(priv, STM32_SDADC_CR1_OFFSET, + SDADC_CR1_JOVRIE | SDADC_CR1_JEOCIE | SDADC_CR1_JDMAEN, + 0); + } +} + +/**************************************************************************** + * Name: sdadc_set_ch + * + * Description: + * Sets the SDADC injected channel group. + * + * Input Parameters: + * dev - pointer to device structure used by the driver + * ch - ADC channel number + 1. 0 reserved for all configured channels + * + * Returned Value: + * int - errno + * + ****************************************************************************/ + +static int sdadc_set_ch(FAR struct adc_dev_s *dev, uint8_t ch) +{ + FAR struct stm32_dev_s *priv = (FAR struct stm32_dev_s *)dev->ad_priv; + uint32_t bits = 0; + int i; + + if (ch == 0) + { + priv->current = 0; + priv->nchannels = priv->cchannels; + } + else + { + for (i = 0; i < priv->cchannels && priv->chanlist[i] != ch - 1; i++); + + if (i >= priv->cchannels) + { + return -ENODEV; + } + + priv->current = i; + priv->nchannels = 1; + } + + for (i = 0; i < priv->nchannels; i++) + { + bits |= (uint32_t)(1 << priv->chanlist[i]); + } + + sdadc_putreg(priv, STM32_SDADC_JCHGR_OFFSET, bits); + + return OK; +} + +/**************************************************************************** + * Name: sdadc_ioctl + * + * Description: + * All ioctl calls will be routed through this method. + * + * Input Parameters: + * dev - pointer to device structure used by the driver + * cmd - command + * arg - arguments passed with command + * + * Returned Value: + * + ****************************************************************************/ + +static int sdadc_ioctl(FAR struct adc_dev_s *dev, int cmd, unsigned long arg) +{ + FAR struct stm32_dev_s *priv = (FAR struct stm32_dev_s *)dev->ad_priv; + int ret = OK; + + switch (cmd) + { + case ANIOC_TRIGGER: + sdadc_startconv(priv, true); + break; + + default: + aerr("ERROR: Unknown cmd: %d\n", cmd); + ret = -ENOTTY; + break; + } + + return ret; +} + +/**************************************************************************** + * Name: sdadc_interrupt + * + * Description: + * Common SDADC interrupt handler. + * + * Input Parameters: + * + * Returned Value: + * + ****************************************************************************/ + +static int sdadc_interrupt(FAR struct adc_dev_s *dev) +{ + FAR struct stm32_dev_s *priv = (FAR struct stm32_dev_s *)dev->ad_priv; + uint32_t regval; + uint32_t pending; + int32_t data; + uint8_t chan; + + regval = sdadc_getreg(priv, STM32_SDADC_ISR_OFFSET); + pending = regval & SDADC_ISR_ALLINTS; + if (pending == 0) + { + return OK; + } + + /* JOVRF: overrun flag */ + + if ((regval & SDADC_ISR_JOVRF) != 0) + { + awarn("WARNING: Overrun has occurred!\n"); + } + + /* JEOCF: End of conversion */ + + if ((regval & SDADC_ISR_JEOCF) != 0) + { + /* Read the converted value and clear JEOCF bit + * (It is cleared by reading the SDADC_JDATAR) */ + + data = sdadc_getreg(priv, STM32_SDADC_JDATAR_OFFSET) & SDADC_JDATAR_JDATA_MASK; + chan = sdadc_getreg(priv, STM32_SDADC_JDATAR_OFFSET) & SDADC_JDATAR_JDATACH_MASK; + + DEBUGASSERT(priv->chanlist[priv->current] == chan); + + /* Verify that the upper-half driver has bound its callback functions */ + + if (priv->cb != NULL) + { + /* Give the SDADC data to the ADC driver. The ADC receive() method + * accepts 3 parameters: + * + * 1) The first is the ADC device instance for this SDADC block. + * 2) The second is the channel number for the data, and + * 3) The third is the converted data for the channel. + */ + + DEBUGASSERT(priv->cb->au_receive != NULL); + priv->cb->au_receive(dev, chan, data); + } + + /* Set the channel number of the next channel that will complete + * conversion. + */ + + priv->current++; + + if (priv->current >= priv->nchannels) + { + /* Restart the conversion sequence from the beginning */ + + priv->current = 0; + } + + /* do no clear this interrupt (cleared by reading data) */ + + pending &= ~SDADC_ISR_JEOCF; + } + + /* Clears interrupt flags, if any */ + + if (pending) + { + sdadc_putreg(priv, STM32_SDADC_CLRISR_OFFSET, pending); + } + + return OK; +} + +/**************************************************************************** + * Name: adc1_interrupt + * + * Description: + * ADC interrupt handler SDADC1 + * + * Input Parameters: + * irq - The IRQ number that generated the interrupt. + * context - Architecture specific register save information. + * + * Returned Value: + * + ****************************************************************************/ + +#if defined(CONFIG_STM32_SDADC1) +static int sdadc1_interrupt(int irq, FAR void *context) +{ + sdadc_interrupt(&g_sdadcdev1); + + return OK; +} +#endif + +/**************************************************************************** + * Name: adc2_interrupt + * + * Description: + * ADC interrupt handler SDADC2 + * + * Input Parameters: + * irq - The IRQ number that generated the interrupt. + * context - Architecture specific register save information. + * + * Returned Value: + * + ****************************************************************************/ + +#if defined(CONFIG_STM32_SDADC2) +static int sdadc2_interrupt(int irq, FAR void *context) +{ + sdadc_interrupt(&g_sdadcdev2); + + return OK; +} +#endif + +/**************************************************************************** + * Name: adc3_interrupt + * + * Description: + * ADC interrupt handler SDADC3 + * + * Input Parameters: + * irq - The IRQ number that generated the interrupt. + * context - Architecture specific register save information. + * + * Returned Value: + * + ****************************************************************************/ + +#if defined(CONFIG_STM32_SDADC3) +static int sdadc3_interrupt(int irq, FAR void *context) +{ + sdadc_interrupt(&g_sdadcdev3); + + return OK; +} +#endif + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: stm32_sdadcinitialize + * + * Description: + * Initialize one SDADC block + * + * The logic is, save and initialize the channel list in the private driver + * structure and return the corresponding adc device structure. + * + * Each SDADC will convert the channels indicated each + * time a conversion is triggered either by sofware, timer or external event. + * Channels are numbered from 0 - 8 and must be given in order (contrarily + * to what says ST RM0313 doc !!!). + * + * Input Parameters: + * intf - Could be {1,2,3} for SDADC1, SDADC2, or SDADC3 + * chanlist - The list of channels eg. { 0, 3, 7, 8 } + * cchannels - Number of channels + * + * Returned Value: + * Valid ADC device structure reference on succcess; a NULL on failure + * + ****************************************************************************/ + +struct adc_dev_s *stm32_sdadcinitialize(int intf, FAR const uint8_t *chanlist, + int cchannels) +{ + FAR struct adc_dev_s *dev; + FAR struct stm32_dev_s *priv; + int i; + + ainfo("intf: %d cchannels: %d\n", intf, cchannels); + + switch (intf) + { +#ifdef CONFIG_STM32_SDADC1 + case 1: + ainfo("SDADC1 selected\n"); + dev = &g_sdadcdev1; + break; +#endif +#ifdef CONFIG_STM32_SDADC2 + case 2: + ainfo("SDADC2 selected\n"); + dev = &g_sdadcdev2; + break; +#endif +#ifdef CONFIG_STM32_SDADC3 + case 3: + ainfo("SDADC3 selected\n"); + dev = &g_sdadcdev3; + break; +#endif + default: + aerr("ERROR: No SDADC interface defined\n"); + return NULL; + } + + /* Check channel list in order */ + + DEBUGASSERT((cchannels <= SDADC_MAX_SAMPLES) && (cchannels > 0)); + for (i = 0; i < cchannels - 1; i ++) + { + if (chanlist[i] >= chanlist[i+1]) + { + aerr("ERROR: SDADC channel list must be given in order\n"); + return NULL; + } + } + + /* Configure the selected SDADC */ + + priv = (FAR struct stm32_dev_s *)dev->ad_priv; + + priv->cb = NULL; + priv->cchannels = cchannels; + + memcpy(priv->chanlist, chanlist, cchannels); + + return dev; +} + +#endif /* CONFIG_STM32_SDADC1 || CONFIG_STM32_SDADC2 || + * CONFIG_STM32_SDADC3 */ +#endif /* CONFIG_STM32_SDADC */ diff --git a/arch/arm/src/stm32/stm32_sdadc.h b/arch/arm/src/stm32/stm32_sdadc.h new file mode 100644 index 00000000000..b2f7ffedd9a --- /dev/null +++ b/arch/arm/src/stm32/stm32_sdadc.h @@ -0,0 +1,426 @@ +/************************************************************************************ + * arch/arm/src/stm32/stm32_sdadc.h + * + * Copyright (C) 2009, 2011, 2015 Gregory Nutt. All rights reserved. + * Copyright (C) 2016 Studelec. All rights reserved. + * Authors: Gregory Nutt + * Marc Rechté + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_STM32_STM32_SDADC_H +#define __ARCH_ARM_SRC_STM32_STM32_SDADC_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +#include "chip.h" + +#if defined(CONFIG_STM32_STM32F37XX) +# include "chip/stm32f37xxx_sdadc.h" +#else +/* No generic chip/stm32_sdadc.h yet */ + +# error "This chip is not yet supported" +#endif + +#include + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ +/* Configuration ********************************************************************/ +/* Timer devices may be used for different purposes. One special purpose is to + * control periodic SDADC sampling. If CONFIG_STM32_TIMn is defined then + * CONFIG_STM32_TIMn_SDADC must also be defined to indicate that timer "n" is intended + * to be used for that purpose. + */ + +/* For the STM32 F37XX line, timers 2-4, 12-17 an 19 may be used. */ + +/* TODO cf. stm32_adc.h */ + +/* Up to 3 SDADC interfaces are supported */ + +#if STM32_NSDADC < 3 +# undef CONFIG_STM32_SDADC3 +#endif + +#if STM32_NSDADC < 2 +# undef CONFIG_STM32_SDADC2 +#endif + +#if STM32_NSDADC < 1 +# undef CONFIG_STM32_SDADC1 +#endif + +#if defined(CONFIG_STM32_SDADC1) || defined(CONFIG_STM32_SDADC2) || \ + defined(CONFIG_STM32_SDADC3) + +/* DMA support */ + +#if defined(CONFIG_STM32_SDADC1_DMA) || defined(CONFIG_STM32_SDADC2_DMA) || \ + defined(CONFIG_STM32_SDADC3_DMA) +# define SDADC_HAVE_DMA 1 +#endif + +#ifdef CONFIG_STM32_SDADC1_DMA +# define SDADC1_HAVE_DMA 1 +#else +# undef SDADC1_HAVE_DMA +#endif + +#ifdef CONFIG_STM32_SDADC2_DMA +# define SDADC2_HAVE_DMA 1 +#else +# undef SDADC2_HAVE_DMA +#endif + +#ifdef CONFIG_STM32_SDADC3_DMA +# define SDADC3_HAVE_DMA 1 +#else +# undef SDADC3_HAVE_DMA +#endif + +/* SDADC Channels/DMA ****************************************************** + * The maximum number of channels that can be sampled at each scan. + * If DMA support is not enabled, then only a single channel + * ought to be sampled. + * Otherwise, unless sampling frequency is reduced, + * data overruns would occur. + */ + +#define SDADC_MAX_CHANNELS_DMA 9 +#define SDADC_MAX_CHANNELS_NODMA 1 + +#ifndef SDADC_MAX_SAMPLES +#ifdef SDADC_HAVE_DMA +# define SDADC_MAX_SAMPLES SDADC_MAX_CHANNELS_DMA +#else +# define SDADC_MAX_SAMPLES SDADC_MAX_CHANNELS_NODMA +#endif +#endif + +/* Timer configuration: If a timer trigger is specified, then get + * information about the timer. + */ + +#if defined(CONFIG_STM32_TIM3_SDADC1) +# define SDADC1_HAVE_TIMER 1 +# define SDADC1_TIMER_BASE STM32_TIM3_BASE +# define SDADC1_TIMER_PCLK_FREQUENCY STM32_APB1_TIM3_CLKIN +#elif defined(CONFIG_STM32_TIM4_SDADC1) +# define SDADC1_HAVE_TIMER 1 +# define SDADC1_TIMER_BASE STM32_TIM4_BASE +# define SDADC1_TIMER_PCLK_FREQUENCY STM32_APB1_TIM4_CLKIN +#elif defined(CONFIG_STM32_TIM13_SDADC1) +# define SDADC1_HAVE_TIMER 1 +# define SDADC1_TIMER_BASE STM32_TIM13_BASE +# define SDADC1_TIMER_PCLK_FREQUENCY STM32_APB1_TIM13_CLKIN +#elif defined(CONFIG_STM32_TIM14_SDADC1) +# define SDADC1_HAVE_TIMER 1 +# define SDADC1_TIMER_BASE STM32_TIM14_BASE +# define SDADC1_TIMER_PCLK_FREQUENCY STM32_APB1_TIM14_CLKIN +#elif defined(CONFIG_STM32_TIM15_SDADC1) +# define SDADC1_HAVE_TIMER 1 +# define SDADC1_TIMER_BASE STM32_TIM15_BASE +# define SDADC1_TIMER_PCLK_FREQUENCY STM32_APB2_TIM15_CLKIN +#elif defined(CONFIG_STM32_TIM19_SDADC1) +# define SDADC1_HAVE_TIMER 1 +# define SDADC1_TIMER_BASE STM32_TIM19_BASE +# define SDADC1_TIMER_PCLK_FREQUENCY STM32_APB1_TIM19_CLKIN +#else +# undef SDADC1_HAVE_TIMER +#endif + +#ifdef SDADC1_HAVE_TIMER +# ifndef CONFIG_STM32_SDADC1_SAMPLE_FREQUENCY +# error "CONFIG_STM32_SDADC1_SAMPLE_FREQUENCY not defined" +# endif +# ifndef CONFIG_STM32_SDADC1_TIMTRIG +# error "CONFIG_STM32_SDADC1_TIMTRIG not defined" +# warning "Values 0:TIM13_CH1 1:TIM14_CH1 2:TIM15_CH2 3:TIM3_CH1 4:TIM4_CH1 5:TIM19_CH2" +# endif +#endif + +#if defined(CONFIG_STM32_TIM2_SDADC2) +# define SDADC2_HAVE_TIMER 1 +# define SDADC2_TIMER_BASE STM32_TIM2_BASE +# define SDADC2_TIMER_PCLK_FREQUENCY STM32_APB1_TIM2_CLKIN +#elif defined(CONFIG_STM32_TIM3_SDADC2) +# define SDADC2_HAVE_TIMER 1 +# define SDADC2_TIMER_BASE STM32_TIM3_BASE +# define SDADC2_TIMER_PCLK_FREQUENCY STM32_APB1_TIM3_CLKIN +#elif defined(CONFIG_STM32_TIM4_SDADC2) +# define SDADC2_HAVE_TIMER 1 +# define SDADC2_TIMER_BASE STM32_TIM4_BASE +# define SDADC2_TIMER_PCLK_FREQUENCY STM32_APB1_TIM4_CLKIN +#elif defined(CONFIG_STM32_TIM12_SDADC2) +# define SDADC2_HAVE_TIMER 1 +# define SDADC2_TIMER_BASE STM32_TIM12_BASE +# define SDADC2_TIMER_PCLK_FREQUENCY STM32_APB1_TIM12_CLKIN +#elif defined(CONFIG_STM32_TIM17_SDADC2) +# define SDADC2_HAVE_TIMER 1 +# define SDADC2_TIMER_BASE STM32_TIM17_BASE +# define SDADC2_TIMER_PCLK_FREQUENCY STM32_APB2_TIM17_CLKIN +#elif defined(CONFIG_STM32_TIM19_SDADC2) +# define SDADC2_HAVE_TIMER 1 +# define SDADC2_TIMER_BASE STM32_TIM19_BASE +# define SDADC2_TIMER_PCLK_FREQUENCY STM32_APB1_TIM19_CLKIN +#else +# undef SDADC2_HAVE_TIMER +#endif + +#ifdef SDADC2_HAVE_TIMER +# ifndef CONFIG_STM32_SDADC2_SAMPLE_FREQUENCY +# error "CONFIG_STM32_SDADC2_SAMPLE_FREQUENCY not defined" +# endif +# ifndef CONFIG_STM32_SDADC2_TIMTRIG +# error "CONFIG_STM32_SDADC2_TIMTRIG not defined" +# warning "Values 0:TIM17_CH1 1:TIM12_CH1 2:TIM2_CH3 3:TIM3_CH2 4:TIM4_CH2 5:TIM19_CH3" +# endif +#endif + +#if defined(CONFIG_STM32_TIM2_SDADC3) +# define SDADC3_HAVE_TIMER 1 +# define SDADC3_TIMER_BASE STM32_TIM2_BASE +# define SDADC3_TIMER_PCLK_FREQUENCY STM32_APB1_TIM2_CLKIN +#elif defined(CONFIG_STM32_TIM3_SDADC3) +# define SDADC3_HAVE_TIMER 1 +# define SDADC3_TIMER_BASE STM32_TIM3_BASE +# define SDADC3_TIMER_PCLK_FREQUENCY STM32_APB1_TIM3_CLKIN +#elif defined(CONFIG_STM32_TIM4_SDADC3) +# define SDADC3_HAVE_TIMER 1 +# define SDADC3_TIMER_BASE STM32_TIM4_BASE +# define SDADC3_TIMER_PCLK_FREQUENCY STM32_APB1_TIM4_CLKIN +#elif defined(CONFIG_STM32_TIM12_SDADC3) +# define SDADC3_HAVE_TIMER 1 +# define SDADC3_TIMER_BASE STM32_TIM12_BASE +# define SDADC3_TIMER_PCLK_FREQUENCY STM32_APB1_TIM12_CLKIN +#elif defined(CONFIG_STM32_TIM16_SDADC3) +# define SDADC3_HAVE_TIMER 1 +# define SDADC3_TIMER_BASE STM32_TIM16_BASE +# define SDADC3_TIMER_PCLK_FREQUENCY STM32_APB2_TIM16_CLKIN +#elif defined(CONFIG_STM32_TIM19_SDADC3) +# define SDADC3_HAVE_TIMER 1 +# define SDADC3_TIMER_BASE STM32_TIM19_BASE +# define SDADC3_TIMER_PCLK_FREQUENCY STM32_APB1_TIM19_CLKIN +#else +# undef SDADC3_HAVE_TIMER +#endif + +#ifdef SDADC3_HAVE_TIMER +# ifndef CONFIG_STM32_SDADC3_SAMPLE_FREQUENCY +# error "CONFIG_STM32_SDADC3_SAMPLE_FREQUENCY not defined" +# endif +# ifndef CONFIG_STM32_SDADC3_TIMTRIG +# error "CONFIG_STM32_SDADC3_TIMTRIG not defined" +# warning "Values 0:TIM16_CH1 1:TIM12_CH2 2:TIM2_CH4 3:TIM3_CH3 4:TIM4_CH3 5:TIM19_CH4" +# endif +#endif + +#if defined(SDADC1_HAVE_TIMER) || defined(SDADC2_HAVE_TIMER) || \ + defined(SDADC3_HAVE_TIMER) +# define SDADC_HAVE_TIMER 1 +# if defined(CONFIG_STM32_STM32F37XX) && !defined(CONFIG_STM32_FORCEPOWER) +# warning "CONFIG_STM32_FORCEPOWER must be defined to enable the timer(s)" +# endif +#else +# undef SDADC_HAVE_TIMER +#endif + +/* NOTE: The following assumes that all possible combinations of timers and + * values are support JEXTSEL. That is not so and it varies from one STM32 + * to another. But this (wrong) assumptions keeps the logic as simple as + * possible. If unsupported combination is used, an error will show up + * later during compilation although it may be difficult to track it back + * to this simplification. + * + * STM32L37XX-family has 3 SDADC onboard + */ + +#ifdef CONFIG_STM32_STM32F37XX +# define SDADC1_JEXTSEL_TIM13_CH1 SDADC1_CR2_JEXTSEL_TIM13_CH1 +# define SDADC1_JEXTSEL_TIM14_CH1 SDADC1_CR2_JEXTSEL_TIM14_CH1 +# define SDADC1_JEXTSEL_TIM15_CH2 SDADC1_CR2_JEXTSEL_TIM15_CH2 +# define SDADC1_JEXTSEL_TIM3_CH1 SDADC1_CR2_JEXTSEL_TIM3_CH1 +# define SDADC1_JEXTSEL_TIM4_CH1 SDADC1_CR2_JEXTSEL_TIM4_CH1 +# define SDADC1_JEXTSEL_TIM19_CH2 SDADC1_CR2_JEXTSEL_TIM19_CH2 +# define SDADC1_JEXTSEL_EXTI15 SDADC1_CR2_JEXTSEL_EXTI15 +# define SDADC1_JEXTSEL_EXTI11 SDADC1_CR2_JEXTSEL_EXTI11 +# define SDADC2_JEXTSEL_TIM17_CH1 SDADC2_CR2_JEXTSEL_TIM17_CH1 +# define SDADC2_JEXTSEL_TIM12_CH1 SDADC2_CR2_JEXTSEL_TIM12_CH1 +# define SDADC2_JEXTSEL_TIM2_CH3 SDADC2_CR2_JEXTSEL_TIM2_CH3 +# define SDADC2_JEXTSEL_TIM3_CH2 SDADC2_CR2_JEXTSEL_TIM3_CH2 +# define SDADC2_JEXTSEL_TIM4_CH2 SDADC2_CR2_JEXTSEL_TIM4_CH2 +# define SDADC2_JEXTSEL_TIM19_CH3 SDADC2_CR2_JEXTSEL_TIM19_CH3 +# define SDADC2_JEXTSEL_EXTI15 SDADC2_CR2_JEXTSEL_EXTI15 +# define SDADC2_JEXTSEL_EXTI11 SDADC2_CR2_JEXTSEL_EXTI11 +# define SDADC3_JEXTSEL_TIM16_CH1 SDADC3_CR2_JEXTSEL_TIM16_CH1 +# define SDADC3_JEXTSEL_TIM12_CH1 SDADC3_CR2_JEXTSEL_TIM12_CH1 +# define SDADC3_JEXTSEL_TIM2_CH4 SDADC3_CR2_JEXTSEL_TIM2_CH4 +# define SDADC3_JEXTSEL_TIM3_CH3 SDADC3_CR2_JEXTSEL_TIM3_CH3 +# define SDADC3_JEXTSEL_TIM4_CH3 SDADC3_CR2_JEXTSEL_TIM4_CH3 +# define SDADC3_JEXTSEL_TIM19_CH4 SDADC3_CR2_JEXTSEL_TIM19_CH4 +# define SDADC3_JEXTSEL_EXTI15 SDADC3_CR2_JEXTSEL_EXTI15 +# define SDADC3_JEXTSEL_EXTI11 SDADC3_CR2_JEXTSEL_EXTI11 +#endif + +#if defined(CONFIG_STM32_TIM3_SDADC1) +# define SDADC1_JEXTSEL_VALUE 3 +#elif defined(CONFIG_STM32_TIM4_SDADC1) +# define SDADC1_JEXTSEL_VALUE 4 +#elif defined(CONFIG_STM32_TIM13_SDADC1) +# define SDADC1_JEXTSEL_VALUE 0 +#elif defined(CONFIG_STM32_TIM14_SDADC1) +# define SDADC1_JEXTSEL_VALUE 1 +#elif defined(CONFIG_STM32_TIM15_SDADC1) +# define SDADC1_JEXTSEL_VALUE 2 +#elif defined(CONFIG_STM32_TIM19_SDADC1) +# define SDADC1_JEXTSEL_VALUE 5 +#else +# undef SDADC1_JEXTSEL_VALUE +#endif + +#if defined(CONFIG_STM32_TIM2_SDADC2) +# define SDADC2_JEXTSEL_VALUE 2 +#elif defined(CONFIG_STM32_TIM3_SDADC2) +# define SDADC2_JEXTSEL_VALUE 3 +#elif defined(CONFIG_STM32_TIM4_SDADC2) +# define SDADC2_JEXTSEL_VALUE 4 +#elif defined(CONFIG_STM32_TIM12_SDADC2) +# define SDADC2_JEXTSEL_VALUE 1 +#elif defined(CONFIG_STM32_TIM17_SDADC2) +# define SDADC2_JEXTSEL_VALUE 0 +#elif defined(CONFIG_STM32_TIM19_SDADC2) +# define SDADC2_JEXTSEL_VALUE 5 +#else +# undef SDADC2_JEXTSEL_VALUE +#endif + +#if defined(CONFIG_STM32_TIM2_SDADC3) +# define SDADC3_JEXTSEL_VALUE 2 +#elif defined(CONFIG_STM32_TIM3_SDADC3) +# define SDADC3_JEXTSEL_VALUE 3 +#elif defined(CONFIG_STM32_TIM4_SDADC3) +# define SDADC3_JEXTSEL_VALUE 4 +#elif defined(CONFIG_STM32_TIM12_SDADC3) +# define SDADC3_JEXTSEL_VALUE 1 +#elif defined(CONFIG_STM32_TIM16_SDADC3) +# define SDADC3_JEXTSEL_VALUE 0 +#elif defined(CONFIG_STM32_TIM19_SDADC3) +# define SDADC3_JEXTSEL_VALUE 5 +#else +# undef SDADC3_JEXTSEL_VALUE +#endif + +/* SDADC Configurations ******************************************************** + * Up to 3 configuration profiles may be defined in order to define: + * - calibration method + * - SE/differential mode + * - input gain + * Each of the 9 SDADC channels is assigned to a configuration profile + */ +#ifndef SDADC_CONF0R_DEFAULT +# define SDADC_CONF0R_DEFAULT (SDADC_CONFR_GAIN_1X | SDADC_CONFR_SE_SE_OFFSET | SDADC_CONFR_COMMON_GND) +#endif +#ifndef SDADC_CONF1R_DEFAULT +# define SDADC_CONF1R_DEFAULT (SDADC_CONFR_GAIN_2X | SDADC_CONFR_SE_SE_OFFSET | SDADC_CONFR_COMMON_GND) +#endif +#ifndef SDADC_CONF2R_DEFAULT +# define SDADC_CONF2R_DEFAULT (SDADC_CONFR_GAIN_4X | SDADC_CONFR_SE_SE_OFFSET | SDADC_CONFR_COMMON_GND) +#endif +#ifndef SDADC_CONFCHR1_DEFAULT +# define SDADC_CONFCHR1_DEFAULT ((SDADC_CONF0R << SDADC_CONFCHR1_CH_SHIFT(0)) | \ + (SDADC_CONF0R << SDADC_CONFCHR1_CH_SHIFT(1)) | \ + (SDADC_CONF0R << SDADC_CONFCHR1_CH_SHIFT(2)) | \ + (SDADC_CONF0R << SDADC_CONFCHR1_CH_SHIFT(3)) | \ + (SDADC_CONF0R << SDADC_CONFCHR1_CH_SHIFT(4)) | \ + (SDADC_CONF0R << SDADC_CONFCHR1_CH_SHIFT(5)) | \ + (SDADC_CONF0R << SDADC_CONFCHR1_CH_SHIFT(6)) | \ + (SDADC_CONF0R << SDADC_CONFCHR1_CH_SHIFT(7))) +#endif +#ifndef SDADC_CONFCHR2_DEFAULT +# define SDADC_CONFCHR2_DEFAULT (SDADC_CONF0R << SDADC_CONFCHR2_CH8_SHIFT) +#endif + +/* SDADC Reference voltage selection ************************************************/ + +#ifndef SDADC_REFV_DEFAULT +# define SDADC_REFV_DEFAULT SDADC_CR1_REFV_EXT +#endif +#ifndef SDADC1_REFV +# define SDADC1_REFV SDADC_REFV_DEFAULT +#endif +#ifndef SDADC2_REFV +# define SDADC2_REFV SDADC_REFV_DEFAULT +#endif +#ifndef SDADC3_REFV +# define SDADC3_REFV SDADC_REFV_DEFAULT +#endif + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Public Function Prototypes + ************************************************************************************/ + +#ifndef __ASSEMBLY__ +#ifdef __cplusplus +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/**************************************************************************** + * Name: stm32_sdadcinitialize + * + ****************************************************************************/ + +struct adc_dev_s *stm32_sdadcinitialize(int intf, FAR const uint8_t *chanlist, + int nchannels); + +#undef EXTERN +#ifdef __cplusplus +} +#endif +#endif /* __ASSEMBLY__ */ + +#endif /* CONFIG_STM32_SDADC1 || CONFIG_STM32_SDADC2 || + * CONFIG_STM32_SDADC3 + */ +#endif /* __ARCH_ARM_SRC_STM32_STM32_SDADC_H */ diff --git a/arch/arm/src/stm32/stm32f30xxx_i2c.c b/arch/arm/src/stm32/stm32f30xxx_i2c.c index 141b0deb75c..27b1c924889 100644 --- a/arch/arm/src/stm32/stm32f30xxx_i2c.c +++ b/arch/arm/src/stm32/stm32f30xxx_i2c.c @@ -101,7 +101,7 @@ #if defined(CONFIG_STM32_I2C1) || defined(CONFIG_STM32_I2C2) || defined(CONFIG_STM32_I2C3) /* This implementation is for the STM32 F1, F2, and F4 only */ -#if defined(CONFIG_STM32_STM32F30XX) +#if defined(CONFIG_STM32_STM32F30XX) || defined(CONFIG_STM32_STM32F37XX) /************************************************************************************ * Pre-processor Definitions @@ -1949,7 +1949,7 @@ out: FAR struct i2c_master_s *stm32_i2cbus_initialize(int port) { struct stm32_i2c_priv_s * priv = NULL; /* private data of device with multiple instances */ - irqtate_t flags; + irqstate_t flags; #if STM32_PCLK1_FREQUENCY < 4000000 # warning STM32_I2C_INIT: Peripheral clock must be at least 4 MHz to support 400 kHz operation. diff --git a/arch/arm/src/stm32/stm32f37xxx_rcc.c b/arch/arm/src/stm32/stm32f37xxx_rcc.c index 02fa9fd930d..6b83ee316c9 100644 --- a/arch/arm/src/stm32/stm32f37xxx_rcc.c +++ b/arch/arm/src/stm32/stm32f37xxx_rcc.c @@ -80,7 +80,7 @@ static inline void rcc_reset(void) regval |= RCC_CR_HSION; putreg32(regval, STM32_RCC_CR); - regval = getreg32(STM32_RCC_CFGR); /* Reset SW, HPRE, PPRE1, PPRE2, USBPRE, and MCO bits */ + regval = getreg32(STM32_RCC_CFGR); /* Reset SW, HPRE, PPRE1, PPRE2, ADCPRE, USBPRE, MCO, SDADC bits */ regval &= ~(RCC_CFGR_SW_MASK | RCC_CFGR_HPRE_MASK | RCC_CFGR_PPRE1_MASK | RCC_CFGR_PPRE2_MASK | RCC_CFGR_USBPRE | RCC_CFGR_MCO_MASK); putreg32(regval, STM32_RCC_CFGR); @@ -107,6 +107,7 @@ static inline void rcc_reset(void) putreg32(0, STM32_RCC_CIR); /* Disable all interrupts */ } + /**************************************************************************** * Name: rcc_enableahb * @@ -169,7 +170,7 @@ static inline void rcc_enableapb1(void) #ifdef CONFIG_STM32_USB /* USB clock divider. This bit must be valid before enabling the USB - * clock in the RCC_APB1ENR register. This bit can’t be reset if the USB + * clock in the RCC_APB1ENR register. This bit can't be reset if the USB * clock is enabled. */ @@ -356,6 +357,28 @@ static inline void rcc_enableapb2(void) { uint32_t regval; +#if defined(CONFIG_STM32_SDADC) || defined(CONFIG_STM32_ADC) + /* Adjust clock of selected peripherals */ + + regval = getreg32(STM32_RCC_CFGR); + +#ifdef CONFIG_STM32_ADC + /* ADC clock divider */ + + regval &= ~RCC_CFGR_ADCPRE_MASK; + regval |= STM32_RCC_ADCPRE; +#endif + +#ifdef CONFIG_STM32_SDADC + /* SDADC clock divider */ + + regval &= ~RCC_CFGR_SDPRE_MASK; + regval |= STM32_RCC_SDPRE; +#endif + + putreg32(regval, STM32_RCC_CFGR); +#endif + /* Set the appropriate bits in the APB2ENR register to enabled the * selected APB2 peripherals. */ @@ -368,6 +391,12 @@ static inline void rcc_enableapb2(void) regval |= RCC_APB2ENR_SYSCFGEN; #endif +#ifdef CONFIG_STM32_ADC1 + /* ADC clock enable */ + + regval |= RCC_APB2ENR_ADC1EN; +#endif + #ifdef CONFIG_STM32_SPI1 /* SPI 1 clock enable */ @@ -412,6 +441,24 @@ static inline void rcc_enableapb2(void) #endif #endif +#ifdef CONFIG_STM32_SDADC1 + /* SDCADC1 clock enable */ + + regval |= RCC_APB2ENR_SDADC1EN; +#endif + +#ifdef CONFIG_STM32_SDADC2 + /* SDCADC2 clock enable */ + + regval |= RCC_APB2ENR_SDADC2EN; +#endif + +#ifdef CONFIG_STM32_SDADC3 + /* SDCADC3 clock enable */ + + regval |= RCC_APB2ENR_SDADC3EN; +#endif + putreg32(regval, STM32_RCC_APB2ENR); } @@ -469,13 +516,13 @@ static void stm32_stdclockconfig(void) /* If this is a value-line part and we are using the HSE as the PLL */ -# if (STM32_CFGR_PLLXTPRE >> 17) != (STM32_CFGR2_PREDIV1 & 1) -# error STM32_CFGR_PLLXTPRE must match the LSB of STM32_CFGR2_PREDIV1 +# if (STM32_CFGR_PLLXTPRE >> 17) != (STM32_CFGR2_PREDIV & 1) +# error STM32_CFGR_PLLXTPRE must match the LSB of STM32_CFGR2_PREDIV # endif /* Set the HSE prescaler */ - regval = STM32_CFGR2_PREDIV1; + regval = STM32_CFGR2_PREDIV; putreg32(regval, STM32_RCC_CFGR2); # endif diff --git a/configs/nucleo-f303re/src/Makefile b/configs/nucleo-f303re/src/Makefile index 7d81b2cbe1b..a4906030e79 100644 --- a/configs/nucleo-f303re/src/Makefile +++ b/configs/nucleo-f303re/src/Makefile @@ -62,6 +62,10 @@ ifeq ($(CONFIG_CAN),y) CSRCS += stm32_can.c endif +ifeq ($(CONFIG_DAC),y) +CSRCS += stm32_dac.c +endif + ifeq ($(CONFIG_PWM),y) CSRCS += stm32_pwm.c endif diff --git a/configs/nucleo-f303re/src/nucleo-f303re.h b/configs/nucleo-f303re/src/nucleo-f303re.h index 526bc7ee9a5..8d9d21d2273 100644 --- a/configs/nucleo-f303re/src/nucleo-f303re.h +++ b/configs/nucleo-f303re/src/nucleo-f303re.h @@ -69,6 +69,8 @@ #define GPIO_LED1 (GPIO_OUTPUT|GPIO_PUSHPULL|GPIO_SPEED_50MHz|\ GPIO_OUTPUT_CLEAR|GPIO_PORTA|GPIO_PIN5) +#define LED_DRIVER_PATH "/dev/userleds" + /* Button definitions *******************************************************/ /* The Nucleo F303RE supports two buttons; only one button is controllable * by software: @@ -153,4 +155,16 @@ void weak_function stm32_spidev_initialize(void); int stm32_timer_driver_setup(FAR const char *devpath, int timer); #endif +/**************************************************************************** + * Name: stm32_dac_setup + * + * Description: + * Configure DAC peripheral for the board. + * + ****************************************************************************/ + +#ifdef CONFIG_DAC +int stm32_dac_setup(void); +#endif + #endif /* __CONFIGS_NUCLEO_F303RE_SRC_NUCLEO_F303RE_H */ diff --git a/configs/nucleo-f303re/src/stm32_adc.c b/configs/nucleo-f303re/src/stm32_adc.c index 10871a82da6..2c2e0bed280 100644 --- a/configs/nucleo-f303re/src/stm32_adc.c +++ b/configs/nucleo-f303re/src/stm32_adc.c @@ -58,37 +58,66 @@ * Pre-processor Definitions ****************************************************************************/ +#if (defined(CONFIG_STM32_ADC1) && defined(CONFIG_STM32_ADC2)) || \ + (defined(CONFIG_STM32_ADC3) && defined(CONFIG_STM32_ADC4)) +# error "will not work with this combination of ADCs" +#endif + /* Configuration ************************************************************/ -#if defined(CONFIG_STM32_ADC1) && !defined(CONFIG_STM32_ADC2) && \ - !defined(CONFIG_STM32_ADC3) && !defined(CONFIG_STM32_ADC4) -# define ADC_PORT 1 -#elif defined(CONFIG_STM32_ADC2) && !defined(CONFIG_STM32_ADC1) && \ - !defined(CONFIG_STM32_ADC3) && !defined(CONFIG_STM32_ADC4) -# define ADC_PORT 2 -#elif defined(CONFIG_STM32_ADC3) && !defined(CONFIG_STM32_ADC1) && \ - !defined(CONFIG_STM32_ADC2) && !defined(CONFIG_STM32_ADC4) -# define ADC_PORT 3 -#elif defined(CONFIG_STM32_ADC4) && !defined(CONFIG_STM32_ADC1) && \ - !defined(CONFIG_STM32_ADC2) && !defined(CONFIG_STM32_ADC3) -# define ADC_PORT 4 -#else -# error "Choose only one of ADC1, ADC2, ADC3, ADC4" +/* 1 or 2 ADC devices (DEV1, DEV2) */ + +#if defined(CONFIG_STM32_ADC1) +# define DEV1_PORT 1 +#endif + +#if defined(CONFIG_STM32_ADC2) +# if defined(DEV1_PORT) +# define DEV2_PORT 2 +# else +# define DEV1_PORT 2 +# endif +#endif + +#if defined(CONFIG_STM32_ADC3) +# if defined(DEV2_PORT) +# error "Choose maximum two of ADC1, ADC2, ADC3, ADC4" +# else +# if defined(DEV1_PORT) +# define DEV2_PORT 3 +# else +# define DEV1_PORT 3 +# endif +# endif +#endif + +#if defined(CONFIG_STM32_ADC4) +# if defined(DEV2_PORT) +# error "Choose maximum two of ADC1, ADC2, ADC3, ADC4" +# else +# if defined(DEV1_PORT) +# define DEV2_PORT 4 +# else +# define DEV1_PORT 4 +# endif +# endif #endif /* The number of ADC channels in the conversion list */ +/* TODO DMA */ -#if defined(CONFIG_STM32_ADC1) && defined(ADC1_HAVE_DMA) -# define ADC_NCHANNELS 4 -#elif defined(CONFIG_STM32_ADC2) && defined(ADC2_HAVE_DMA) -# define ADC_NCHANNELS 3 -#elif defined(CONFIG_STM32_ADC3) && defined(ADC3_HAVE_DMA) -# define ADC_NCHANNELS 1 -#elif defined(CONFIG_STM32_ADC4) && defined(ADC4_HAVE_DMA) -# define ADC_NCHANNELS 1 +#if defined(ADC1_HAVE_DMA) +# error "ADC1 with DMA support is not fully implemented" #else -# define ADC_NCHANNELS 1 +# define ADC1_NCHANNELS 4 #endif +#if defined(ADC2_HAVE_DMA) +# error "ADC2 with DMA support is not fully implemented" +#else +# define ADC2_NCHANNELS 3 +#endif +#define ADC3_NCHANNELS 3 +#define ADC4_NCHANNELS 1 /**************************************************************************** * Private Function Prototypes @@ -98,88 +127,187 @@ * Private Data ****************************************************************************/ -#if defined(CONFIG_STM32_ADC1) +/* DEV 1 */ -/* Identifying number of each ADC channel */ +#if DEV1_PORT == 1 -static const uint8_t g_chanlist[ADC_NCHANNELS] = +#define DEV1_NCHANNELS ADC1_NCHANNELS + +/* Identifying number of each ADC channel (even if NCHANNELS is less ) */ + +static const uint8_t g_chanlist1[4] = { 1, -#ifdef ADC1_HAVE_DMA 2, 6, 7, -#endif }; /* Configurations of pins used by each ADC channel */ -static const uint32_t g_pinlist[ADC_NCHANNELS] = +static const uint32_t g_pinlist1[4] = { GPIO_ADC1_IN1, -#ifdef ADC1_HAVE_DMA GPIO_ADC1_IN2, GPIO_ADC1_IN6, - GPIO_ADC1_IN7, -#endif + GPIO_ADC1_IN7 }; -#elif defined(CONFIG_STM32_ADC2) +#elif DEV1_PORT == 2 + +#define DEV1_NCHANNELS ADC2_NCHANNELS /* Identifying number of each ADC channel */ -static const uint8_t g_chanlist[ADC_NCHANNELS] = +static const uint8_t g_chanlist1[3] = { 1, -#ifdef ADC2_HAVE_DMA - 6, - 7, -#endif + 3, + 4 }; /* Configurations of pins used by each ADC channel */ -static const uint32_t g_pinlist[ADC_NCHANNELS] = +static const uint32_t g_pinlist1[3] = { GPIO_ADC2_IN1, -#ifdef ADC2_HAVE_DMA - GPIO_ADC2_IN6, - GPIO_ADC2_IN7, + GPIO_ADC2_IN3, + GPIO_ADC2_IN4 +}; + +#elif DEV1_PORT == 3 + +#define DEV1_NCHANNELS ADC3_NCHANNELS + +/* Identifying number of each ADC channel */ + +static const uint8_t g_chanlist1[3] = +{ + 1, + 5, + 12 +}; + +/* Configurations of pins used by each ADC channel */ + +static const uint32_t g_pinlist1[3] = +{ + GPIO_ADC3_IN1, + GPIO_ADC3_IN5, + GPIO_ADC3_IN12 +}; + +#elif DEV1_PORT == 4 + +#define DEV1_NCHANNELS ADC4_NCHANNELS + +/* Identifying number of each ADC channel */ + +static const uint8_t g_chanlist1[1] = +{ + 3 +}; + +/* Configurations of pins used by each ADC channel */ + +static const uint32_t g_pinlist1[1] = +{ + GPIO_ADC4_IN3 +}; + #endif -}; -#elif defined(CONFIG_STM32_ADC3) +#ifdef DEV2_PORT -/* Identifying number of each ADC channel */ +/* DEV 2 */ -static const uint8_t g_chanlist[ADC_NCHANNELS] = +#if DEV2_PORT == 1 + +#define DEV2_NCHANNELS ADC1_NCHANNELS + +/* Identifying number of each ADC channel (even if NCHANNELS is less ) */ + +static const uint8_t g_chanlist2[4] = { - 12, + 1, + 2, + 6, + 7 }; /* Configurations of pins used by each ADC channel */ -static const uint32_t g_pinlist[ADC_NCHANNELS] = +static const uint32_t g_pinlist2[4] = { - GPIO_ADC3_IN12, + GPIO_ADC1_IN1, + GPIO_ADC1_IN2, + GPIO_ADC1_IN6, + GPIO_ADC1_IN7 }; -#elif defined(CONFIG_STM32_ADC4) +#elif DEV2_PORT == 2 + +#define DEV2_NCHANNELS ADC2_NCHANNELS /* Identifying number of each ADC channel */ -static const uint8_t g_chanlist[ADC_NCHANNELS] = +static const uint8_t g_chanlist2[3] = { + 1, 3, + 4 }; /* Configurations of pins used by each ADC channel */ -static const uint32_t g_pinlist[ADC_NCHANNELS] = +static const uint32_t g_pinlist2[3] = { - GPIO_ADC4_IN3, + GPIO_ADC2_IN1, + GPIO_ADC2_IN3, + GPIO_ADC2_IN4 }; +#elif DEV2_PORT == 3 + +#define DEV2_NCHANNELS ADC3_NCHANNELS + +/* Identifying number of each ADC channel */ + +static const uint8_t g_chanlist2[3] = +{ + 1, + 5, + 12 +}; + +/* Configurations of pins used by each ADC channel */ + +static const uint32_t g_pinlist2[3] = +{ + GPIO_ADC3_IN1, + GPIO_ADC3_IN5, + GPIO_ADC3_IN12 +}; + +#elif DEV2_PORT == 4 + +#define DEV2_NCHANNELS ADC4_NCHANNELS + +/* Identifying number of each ADC channel */ + +static const uint8_t g_chanlist2[1] = +{ + 3 +}; + +/* Configurations of pins used by each ADC channel */ + +static const uint32_t g_pinlist2[1] = +{ + GPIO_ADC4_IN3 +}; + +#endif #endif /**************************************************************************** @@ -208,21 +336,22 @@ int board_adc_setup(void) /* Check if we have already initialized */ - if (!initialized) - { + if (!initialized) { + + /* DEV1 */ /* Configure the pins as analog inputs for the selected channels */ - for (i = 0; i < ADC_NCHANNELS; i++) + for (i = 0; i < DEV1_NCHANNELS; i++) { - stm32_configgpio(g_pinlist[i]); + stm32_configgpio(g_pinlist1[i]); } /* Call stm32_adcinitialize() to get an instance of the ADC interface */ - adc = stm32_adcinitialize(ADC_PORT, g_chanlist, ADC_NCHANNELS); + adc = stm32_adcinitialize(DEV1_PORT, g_chanlist1, DEV1_NCHANNELS); if (adc == NULL) { - aerr("ERROR: Failed to get ADC interface\n"); + aerr("ERROR: Failed to get ADC interface 1\n"); return -ENODEV; } @@ -231,10 +360,39 @@ int board_adc_setup(void) ret = adc_register("/dev/adc0", adc); if (ret < 0) { - aerr("ERROR: adc_register failed: %d\n", ret); + aerr("ERROR: adc_register /dev/adc0 failed: %d\n", ret); return ret; } +#ifdef DEV2_PORT + + /* DEV2 */ + /* Configure the pins as analog inputs for the selected channels */ + + for (i = 0; i < DEV2_NCHANNELS; i++) + { + stm32_configgpio(g_pinlist2[i]); + } + + /* Call stm32_adcinitialize() to get an instance of the ADC interface */ + + adc = stm32_adcinitialize(DEV2_PORT, g_chanlist2, DEV2_NCHANNELS); + if (adc == NULL) + { + aerr("ERROR: Failed to get ADC interface 2\n"); + return -ENODEV; + } + + /* Register the ADC driver at "/dev/adc1" */ + + ret = adc_register("/dev/adc1", adc); + if (ret < 0) + { + aerr("ERROR: adc_register /dev/adc1 failed: %d\n", ret); + return ret; + } +#endif + /* Now we are initialized */ initialized = true; diff --git a/configs/nucleo-f303re/src/stm32_appinitialize.c b/configs/nucleo-f303re/src/stm32_appinitialize.c index d79c7d50412..3ce7e293bd0 100644 --- a/configs/nucleo-f303re/src/stm32_appinitialize.c +++ b/configs/nucleo-f303re/src/stm32_appinitialize.c @@ -42,8 +42,12 @@ #include #include +#include #include +#include + +#include "nucleo-f303re.h" /**************************************************************************** * Pre-processor Definitions @@ -80,5 +84,31 @@ int board_app_initialize(uintptr_t arg) { + int ret; + +#if !defined(CONFIG_ARCH_LEDS) && defined(CONFIG_USERLED_LOWER) + /* Register the LED driver */ + + ret = userled_lower_initialize(LED_DRIVER_PATH); + if (ret < 0) + { + syslog(LOG_ERR, "ERROR: userled_lower_initialize() failed: %d\n", ret); + return ret; + } +#endif + + /* Contrairement à l'ADC, il n'y a pas de BOARDIOC_DAC_SETUP spécifique. Il + * faut le faire ici + */ + +#if defined(CONFIG_DAC) + ret = board_dac_setup(); + if (ret < 0) + { + syslog(LOG_ERR, "ERROR: board_dac_setup() failed: %d\n", ret); + return ret; + } +#endif + return OK; }