diff --git a/arch/arm/src/stm32/Kconfig b/arch/arm/src/stm32/Kconfig index 068c7195cc2..33739acb222 100644 --- a/arch/arm/src/stm32/Kconfig +++ b/arch/arm/src/stm32/Kconfig @@ -5802,20 +5802,36 @@ menuconfig STM32_HRTIM_ADC if STM32_HRTIM_ADC -config STM32_HRTIM_ADC_TRG1 - bool "HRTIM ADC Trigger 1" +config STM32_HRTIM_ADC1_TRG1 + bool "HRTIM ADC1 Trigger 1" default n -config STM32_HRTIM_ADC_TRG2 - bool "HRTIM ADC Trigger 2" +config STM32_HRTIM_ADC1_TRG2 + bool "HRTIM ADC1 Trigger 2" default n -config STM32_HRTIM_ADC_TRG3 - bool "HRTIM ADC Trigger 3" +config STM32_HRTIM_ADC1_TRG3 + bool "HRTIM ADC1 Trigger 3" default n -config STM32_HRTIM_ADC_TRG4 - bool "HRTIM ADC Trigger 4" +config STM32_HRTIM_ADC1_TRG4 + bool "HRTIM ADC1 Trigger 4" + default n + +config STM32_HRTIM_ADC2_TRG1 + bool "HRTIM ADC2 Trigger 1" + default n + +config STM32_HRTIM_ADC2_TRG2 + bool "HRTIM ADC2 Trigger 2" + default n + +config STM32_HRTIM_ADC2_TRG3 + bool "HRTIM ADC2 Trigger 3" + default n + +config STM32_HRTIM_ADC2_TRG4 + bool "HRTIM ADC2 Trigger 4" default n endif # STM32_HRTIM_ADC @@ -6298,6 +6314,14 @@ config STM32_ADC_NO_STARTUP_CONV ---help--- Do not start conversion when opening ADC device. +config STM32_ADC_NOIRQ + bool "Do not use default ADC interrupts" + depends on STM32_STM32F33XX + default n + ---help--- + Do not use default ADC interrupts handlers. + Only for STM32_STM32F33XX at this moment. + config STM32_ADC1_DMA bool "ADC1 DMA" depends on STM32_ADC1 && STM32_HAVE_ADC1_DMA diff --git a/arch/arm/src/stm32/chip/stm32f33xxx_adc.h b/arch/arm/src/stm32/chip/stm32f33xxx_adc.h index c645c7f869d..ec84f5c9f8d 100644 --- a/arch/arm/src/stm32/chip/stm32f33xxx_adc.h +++ b/arch/arm/src/stm32/chip/stm32f33xxx_adc.h @@ -192,10 +192,10 @@ #define ADC_CFGR_DMACFG (1 << 1) /* Bit 1: Direct memory access configuration */ #define ADC_CFGR_RES_SHIFT (3) /* Bits 3-4: Data resolution */ #define ADC_CFGR_RES_MASK (3 << ADC_CFGR_RES_SHIFT) -# define ADC_CFGR_RES_12BIT (0 << ADC_CFGR_RES_SHIFT) /* 15 ADCCLK clyes */ -# define ADC_CFGR_RES_10BIT (1 << ADC_CFGR_RES_SHIFT) /* 13 ADCCLK clyes */ -# define ADC_CFGR_RES_8BIT (2 << ADC_CFGR_RES_SHIFT) /* 11 ADCCLK clyes */ -# define ADC_CFGR_RES_6BIT (3 << ADC_CFGR_RES_SHIFT) /* 9 ADCCLK clyes */ +# define ADC_CFGR_RES_12BIT (0 << ADC_CFGR_RES_SHIFT) /* 15 ADCCLK cycles */ +# define ADC_CFGR_RES_10BIT (1 << ADC_CFGR_RES_SHIFT) /* 13 ADCCLK cycles */ +# define ADC_CFGR_RES_8BIT (2 << ADC_CFGR_RES_SHIFT) /* 11 ADCCLK cycles */ +# define ADC_CFGR_RES_6BIT (3 << ADC_CFGR_RES_SHIFT) /* 9 ADCCLK cycles */ #define ADC_CFGR_ALIGN (1 << 5) /* Bit 5: Data Alignment */ #define ADC_CFGR_EXTSEL_SHIFT (6) /* Bits 6-9: External Event Select for regular group */ #define ADC_CFGR_EXTSEL_MASK (15 << ADC_CFGR_EXTSEL_SHIFT) diff --git a/arch/arm/src/stm32/stm32.h b/arch/arm/src/stm32/stm32.h index 11c8f5b29e3..56225ee211d 100644 --- a/arch/arm/src/stm32/stm32.h +++ b/arch/arm/src/stm32/stm32.h @@ -67,7 +67,6 @@ #include "stm32_flash.h" #include "stm32_fsmc.h" #include "stm32_gpio.h" -#include "stm32_hrtim.h" #include "stm32_i2c.h" #include "stm32_ltdc.h" #include "stm32_opamp.h" diff --git a/arch/arm/src/stm32/stm32_adc.h b/arch/arm/src/stm32/stm32_adc.h index 87a1861c78f..eebba26746f 100644 --- a/arch/arm/src/stm32/stm32_adc.h +++ b/arch/arm/src/stm32/stm32_adc.h @@ -1908,6 +1908,66 @@ struct adc_sample_time_s #endif +#ifdef CONFIG_STM32_STM32F33XX + +/* At this moment only for STM32F33XX family */ + +/* ADC resolution can be reduced in order to perform faster conversion */ + +enum stm32_adc_resoluton_e +{ + ADC_RESOLUTION_12BIT = 0, /* 12 bit, 15 ADCCLK cycles */ + ADC_RESOLUTION_10BIT = 1, /* 10 bit, 12 ADCCLK cycles */ + ADC_RESOLUTION_8BIT = 2, /* 8 bit, 10 ADCCLK cycles */ + ADC_RESOLUTION_6BIT = 3 /* 6 bit, 8 ADCCLK cycles */ +}; + +#ifdef CONFIG_STM32_ADC_NOIRQ + +/* This structure provides the publicly visable representation of the + * "lower-half" ADC driver structure. + */ + +struct stm32_adc_dev_s +{ + /* Publicly visible portion of the "lower-half" ADC driver structure */ + + FAR const struct stm32_adc_ops_s *ops; + + /* Require cast-compatibility with private "lower-half" ADC strucutre */ +}; + +struct stm32_adc_ops_s +{ + + /* Acknowledge interrupts */ + + void (*int_ack)(FAR struct stm32_adc_dev_s *dev, uint32_t source); + + /* Get pending interrupts */ + + uint32_t (*int_get)(FAR struct stm32_adc_dev_s *dev); + + /* Enable interrupts */ + + void (*int_en)(FAR struct stm32_adc_dev_s *dev, uint32_t source); + + /* Get current ADC data register */ + + uint32_t (*val_get)(FAR struct stm32_adc_dev_s *dev); + + /* Register buffer for ADC DMA transfer */ + + int (*regbuf_reg)(FAR struct stm32_adc_dev_s *dev, uint16_t *buffer, uint8_t len); + + /* Get current ADC injected data register */ + + uint32_t (*inj_get)(FAR struct stm32_adc_dev_s *dev, uint8_t chan); +}; + +#endif /* CONFIG_STM32_ADC_NOIRQ */ +#endif /* CONFIG_STM32_STM32F33XX */ + /************************************************************************************ * Public Function Prototypes ************************************************************************************/ diff --git a/arch/arm/src/stm32/stm32_dma.h b/arch/arm/src/stm32/stm32_dma.h index 5a84034889b..965fd6f30fe 100644 --- a/arch/arm/src/stm32/stm32_dma.h +++ b/arch/arm/src/stm32/stm32_dma.h @@ -327,6 +327,38 @@ void stm32_dmadump(DMA_HANDLE handle, const struct stm32_dmaregs_s *regs, # define stm32_dmadump(handle,regs,msg) #endif +#ifdef CONFIG_STM32_STM32F33XX + +/* At this moment only for STM32F33XX family */ + +/* High performance, zero latency DMA interrupts need some additional + * interfaces. + */ + +#ifdef CONFIG_ARCH_HIPRI_INTERRUPT + +/**************************************************************************** + * Name: stm32_dma_intack + * + * Description: + * Public visible interface to acknowledge interrupts on DMA channel + * + ****************************************************************************/ + +void stm32_dma_intack(unsigned int chndx, uint32_t isr); + +/**************************************************************************** + * Name: stm32_dma_intget + * + * Description: + * Public visible interface to get pending interrupts from DMA channel + * + ****************************************************************************/ + +uint32_t stm32_dma_intget(unsigned int chndx); +#endif /* CONFIG_ARCH_HIPRI_INTERRUPT */ +#endif /* CONFIG_STM32_STM32F33XX */ + #undef EXTERN #if defined(__cplusplus) } diff --git a/arch/arm/src/stm32/stm32_hrtim.c b/arch/arm/src/stm32/stm32_hrtim.c index 921d5490089..1bf084a2778 100644 --- a/arch/arm/src/stm32/stm32_hrtim.c +++ b/arch/arm/src/stm32/stm32_hrtim.c @@ -185,6 +185,26 @@ # error HRTIM ADC Triggering not supported yet #endif +#if defined(CONFIG_STM32_HRTIM_ADC1_TRG1) || defined(CONFIG_STM32_HRTIM_ADC1_TRG2) || \ + defined(CONFIG_STM32_HRTIM_ADC1_TRG3) || defined(CONFIG_STM32_HRTIM_ADC1_TRG4) || \ + defined(CONFIG_STM32_HRTIM_ADC2_TRG1) || defined(CONFIG_STM32_HRTIM_ADC2_TRG2) || \ + defined(CONFIG_STM32_HRTIM_ADC2_TRG3) || defined(CONFIG_STM32_HRTIM_ADC2_TRG4) +# define HRTIM_HAVE_ADC +#endif + +#if defined(CONFIG_STM32_HRTIM_ADC1_TRG1) || defined(CONFIG_STM32_HRTIM_ADC2_TRG1) +# define HRTIM_HAVE_ADC_TRG1 +#endif +#if defined(CONFIG_STM32_HRTIM_ADC1_TRG2) || defined(CONFIG_STM32_HRTIM_ADC2_TRG2) +# define HRTIM_HAVE_ADC_TRG2 +#endif +#if defined(CONFIG_STM32_HRTIM_ADC1_TRG3) || defined(CONFIG_STM32_HRTIM_ADC2_TRG3) +# define HRTIM_HAVE_ADC_TRG3 +#endif +#if defined(CONFIG_STM32_HRTIM_ADC1_TRG4) || defined(CONFIG_STM32_HRTIM_ADC2_TRG4) +# define HRTIM_HAVE_ADC_TRG4 +#endif + #ifdef CONFIG_STM32_HRTIM_INTERRUPTS # error HRTIM Interrupts not supported yet #endif @@ -497,21 +517,21 @@ struct stm32_hrtim_eev_s }; #endif -#ifdef CONFIG_STM32_HRTIM_ADC +#ifdef HRTIM_HAVE_ADC /* Structure describes HRTIM ADC triggering configuration */ struct stm32_hrtim_adc_s { -#ifdef CONFIG_STM32_HRTIM_ADC_TRG1 +#ifdef HRTIM_HAVE_ADC_TRG1 uint32_t trg1; #endif -#ifdef CONFIG_STM32_HRTIM_ADC_TRG2 +#ifdef HRTIM_HAVE_ADC_TRG2 uint32_t trg2; #endif -#ifdef CONFIG_STM32_HRTIM_ADC_TRG3 +#ifdef HRTIM_HAVE_ADC_TRG3 uint32_t trg3; #endif -#ifdef CONFIG_STM32_HRTIM_ADC_TRG4 +#ifdef HRTIM_HAVE_ADC_TRG4 uint32_t trg4; #endif }; @@ -555,7 +575,7 @@ struct stm32_hrtim_s #ifdef CONFIG_STM32_HRTIM_EVENTS struct stm32_hrtim_eev_s *eev; /* External Events configuration */ #endif -#ifdef CONFIG_STM32_HRTIM_ADC +#ifdef HRTIM_HAVE_ADC struct stm32_hrtim_adc_s *adc; /* ADC triggering configuration */ #endif #ifdef CONFIG_STM32_HRTIM_BURST @@ -630,7 +650,7 @@ static int hrtim_outputs_config(FAR struct stm32_hrtim_s *priv); static int hrtim_outputs_enable(FAR struct hrtim_dev_s *dev, uint16_t outputs, bool state); #endif -#ifdef CONFIG_STM32_HRTIM_ADC +#ifdef HRTIM_HAVE_ADC static int hrtim_adc_config(FAR struct stm32_hrtim_s *priv); #endif #ifdef CONFIG_STM32_HRTIM_DAC @@ -1386,19 +1406,19 @@ struct stm32_hrtim_eev_s g_eev = /* ADC triggering data */ -#ifdef CONFIG_STM32_HRTIM_ADC +#ifdef HRTIM_HAVE_ADC struct stm32_hrtim_adc_s g_adc = { -#ifdef CONFIG_STM32_HRTIM_ADC_TRG1 +#ifdef HRTIM_HAVE_ADC_TRG1 .trg1 = HRTIM_ADC_TRG1, #endif -#ifdef CONFIG_STM32_HRTIM_ADC_TRG2 +#ifdef HRTIM_HAVE_ADC_TRG2 .trg2 = HRTIM_ADC_TRG2, #endif -#ifdef CONFIG_STM32_HRTIM_ADC_TRG3 +#ifdef HRTIM_HAVE_ADC_TRG3 .trg3 = HRTIM_ADC_TRG3, #endif -#ifdef CONFIG_STM32_HRTIM_ADC_TRG4 +#ifdef HRTIM_HAVE_ADC_TRG4 .trg4 = HRTIM_ADC_TRG4 #endif }; @@ -1442,7 +1462,7 @@ static struct stm32_hrtim_s g_hrtim1priv = #ifdef CONFIG_STM32_HRTIM_EVENTS .eev = &g_eev, #endif -#ifdef CONFIG_STM32_HRTIM_ADC +#ifdef HRTIM_HAVE_ADC .adc = &g_adc, #endif #ifdef CONFIG_STM32_HRTIM_BURST @@ -2841,30 +2861,30 @@ static int hrtim_outputs_enable(FAR struct hrtim_dev_s *dev, * ****************************************************************************/ -#ifdef CONFIG_STM32_HRTIM_ADC +#ifdef HRTIM_HAVE_ADC static int hrtim_adc_config(FAR struct stm32_hrtim_s *priv) { /* Configure ADC Trigger 1 */ -#ifdef CONFIG_STM32_HRTIM_ADC_TRG1 +#ifdef HRTIM_HAVE_ADC_TRG1 hrtim_cmn_putreg(priv, STM32_HRTIM_CMN_ADC1R_OFFSET, priv->adc->trg1); #endif /* Configure ADC Trigger 2 */ -#ifdef CONFIG_STM32_HRTIM_ADC_TRG2 +#ifdef HRTIM_HAVE_ADC_TRG2 hrtim_cmn_putreg(priv, STM32_HRTIM_CMN_ADC2R_OFFSET, priv->adc->trg2); #endif /* Configure ADC Trigger 3 */ -#ifdef CONFIG_STM32_HRTIM_ADC_TRG3 +#ifdef HRTIM_HAVE_ADC_TRG3 hrtim_cmn_putreg(priv, STM32_HRTIM_CMN_ADC3R_OFFSET, priv->adc->trg3); #endif /* Configure ADC Trigger 4 */ -#ifdef CONFIG_STM32_HRTIM_ADC_TRG4 +#ifdef HRTIM_HAVE_ADC_TRG4 hrtim_cmn_putreg(priv, STM32_HRTIM_CMN_ADC4R_OFFSET, priv->adc->trg4); #endif @@ -4592,7 +4612,7 @@ static int stm32_hrtimconfig(FAR struct stm32_hrtim_s *priv) /* Configure ADC triggers */ -#ifdef CONFIG_STM32_HRTIM_ADC +#ifdef HRTIM_HAVE_ADC ret = hrtim_adc_config(priv); if (ret != OK) { diff --git a/arch/arm/src/stm32/stm32_hrtim.h b/arch/arm/src/stm32/stm32_hrtim.h index b8790ce16c1..b25073cfd1e 100644 --- a/arch/arm/src/stm32/stm32_hrtim.h +++ b/arch/arm/src/stm32/stm32_hrtim.h @@ -50,6 +50,7 @@ #if defined(CONFIG_STM32_STM32F33XX) # include "chip/stm32f33xxx_hrtim.h" +# include "chip/stm32f33xxx_rcc.h" #else # error #endif @@ -645,88 +646,88 @@ enum stm32_hrtim_chopper_freq_e enum stm32_hrtim_adc_trq13_e { - HRTIM_ADCTRG13_MC1 = (1 << 0), - HRTIM_ADCTRG13_MC2 = (1 << 1), - HRTIM_ADCTRG13_MC3 = (1 << 2), - HRTIM_ADCTRG13_MC4 = (1 << 3), - HRTIM_ADCTRG13_MPER = (1 << 4), + HRTIM_ADCTRG13_MC1 = (1 << 0), /* Trigger on Master Compare 1 */ + HRTIM_ADCTRG13_MC2 = (1 << 1), /* Trigger on Master Compare 2 */ + HRTIM_ADCTRG13_MC3 = (1 << 2), /* Trigger on Master Compare 3 */ + HRTIM_ADCTRG13_MC4 = (1 << 3), /* Trigger on Master Compare 4 */ + HRTIM_ADCTRG13_MPER = (1 << 4), /* Trigger on Master Period */ - HRTIM_ADCTRG13_EEV1 = (1 << 5), - HRTIM_ADCTRG13_EEV2 = (1 << 6), - HRTIM_ADCTRG13_EEV3 = (1 << 7), - HRTIM_ADCTRG13_EEV4 = (1 << 8), - HRTIM_ADCTRG13_EEV5 = (1 << 9), + HRTIM_ADCTRG13_EEV1 = (1 << 5), /* Trigger on External Event 1 */ + HRTIM_ADCTRG13_EEV2 = (1 << 6), /* Trigger on External Event 2 */ + HRTIM_ADCTRG13_EEV3 = (1 << 7), /* Trigger on External Event 3 */ + HRTIM_ADCTRG13_EEV4 = (1 << 8), /* Trigger on External Event 4 */ + HRTIM_ADCTRG13_EEV5 = (1 << 9), /* Trigger on External Event 5 */ - HRTIM_ADCTRG13_AC2 = (1 << 10), - HRTIM_ADCTRG13_AC3 = (1 << 11), - HRTIM_ADCTRG13_AC4 = (1 << 12), - HRTIM_ADCTRG13_APER = (1 << 13), - HRTIM_ADCTRG13_ARST = (1 << 14), + HRTIM_ADCTRG13_AC2 = (1 << 10), /* Trigger on Timer A Compare 2 */ + HRTIM_ADCTRG13_AC3 = (1 << 11), /* Trigger on Timer A Compare 3 */ + HRTIM_ADCTRG13_AC4 = (1 << 12), /* Trigger on Timer A Compare 4 */ + HRTIM_ADCTRG13_APER = (1 << 13), /* Trigger on Timer A Period */ + HRTIM_ADCTRG13_ARST = (1 << 14), /* Trigger on Timer A Reset */ - HRTIM_ADCTRG13_BC2 = (1 << 15), - HRTIM_ADCTRG13_BC3 = (1 << 16), - HRTIM_ADCTRG13_BC4 = (1 << 17), - HRTIM_ADCTRG13_BPER = (1 << 18), - HRTIM_ADCTRG13_BRST = (1 << 19), + HRTIM_ADCTRG13_BC2 = (1 << 15), /* Trigger on Timer B Compare 2 */ + HRTIM_ADCTRG13_BC3 = (1 << 16), /* Trigger on Timer B Compare 3 */ + HRTIM_ADCTRG13_BC4 = (1 << 17), /* Trigger on Timer B Compare 4 */ + HRTIM_ADCTRG13_BPER = (1 << 18), /* Trigger on Timer B Period */ + HRTIM_ADCTRG13_BRST = (1 << 19), /* Trigger on Timer B Reset */ - HRTIM_ADCTRG13_CC2 = (1 << 20), - HRTIM_ADCTRG13_CC3 = (1 << 21), - HRTIM_ADCTRG13_CC4 = (1 << 22), - HRTIM_ADCTRG13_CPER = (1 << 23), + HRTIM_ADCTRG13_CC2 = (1 << 20), /* Trigger on Timer C Compare 2 */ + HRTIM_ADCTRG13_CC3 = (1 << 21), /* Trigger on Timer C Compare 3 */ + HRTIM_ADCTRG13_CC4 = (1 << 22), /* Trigger on Timer C Compare 4 */ + HRTIM_ADCTRG13_CPER = (1 << 23), /* Trigger on Timer C Period */ - HRTIM_ADCTRG13_DC2 = (1 << 24), - HRTIM_ADCTRG13_DC3 = (1 << 25), - HRTIM_ADCTRG13_DC4 = (1 << 26), - HRTIM_ADCTRG13_DPER = (1 << 27), + HRTIM_ADCTRG13_DC2 = (1 << 24), /* Trigger on Timer D Compare 2 */ + HRTIM_ADCTRG13_DC3 = (1 << 25), /* Trigger on Timer D Compare 3 */ + HRTIM_ADCTRG13_DC4 = (1 << 26), /* Trigger on Timer D Compare 4 */ + HRTIM_ADCTRG13_DPER = (1 << 27), /* Trigger on Timer D Period */ - HRTIM_ADCTRG13_EC2 = (1 << 28), - HRTIM_ADCTRG13_EC3 = (1 << 29), - HRTIM_ADCTRG13_EC4 = (1 << 30), - HRTIM_ADCTRG13_ERST = (1 << 31), + HRTIM_ADCTRG13_EC2 = (1 << 28), /* Trigger on Timer E Compare 2 */ + HRTIM_ADCTRG13_EC3 = (1 << 29), /* Trigger on Timer E Compare 3 */ + HRTIM_ADCTRG13_EC4 = (1 << 30), /* Trigger on Timer E Compare 4 */ + HRTIM_ADCTRG13_EPER = (1 << 31), /* Trigger on Timer E Period */ }; /* HRTIM ADC Trigger 2/4 */ enum stm32_hrtim_adc_trq24_e { - HRTIM_ADCTRG24_MC1 = (1 << 0), - HRTIM_ADCTRG24_MC2 = (1 << 1), - HRTIM_ADCTRG24_MC3 = (1 << 2), - HRTIM_ADCTRG24_MC4 = (1 << 3), - HRTIM_ADCTRG24_MPER = (1 << 4), + HRTIM_ADCTRG24_MC1 = (1 << 0), /* Trigger on Master Compare 1 */ + HRTIM_ADCTRG24_MC2 = (1 << 1), /* Trigger on Master Compare 2 */ + HRTIM_ADCTRG24_MC3 = (1 << 2), /* Trigger on Master Compare 3 */ + HRTIM_ADCTRG24_MC4 = (1 << 3), /* Trigger on Master Compare 4 */ + HRTIM_ADCTRG24_MPER = (1 << 4), /* Trigger on Master Period */ - HRTIM_ADCTRG24_EEV6 = (1 << 5), - HRTIM_ADCTRG24_EEV7 = (1 << 6), - HRTIM_ADCTRG24_EEV8 = (1 << 7), - HRTIM_ADCTRG24_EEV9 = (1 << 8), - HRTIM_ADCTRG24_EEV10 = (1 << 9), + HRTIM_ADCTRG24_EEV6 = (1 << 5), /* Trigger on External Event 6 */ + HRTIM_ADCTRG24_EEV7 = (1 << 6), /* Trigger on External Event 7 */ + HRTIM_ADCTRG24_EEV8 = (1 << 7), /* Trigger on External Event 8 */ + HRTIM_ADCTRG24_EEV9 = (1 << 8), /* Trigger on External Event 9 */ + HRTIM_ADCTRG24_EEV10 = (1 << 9), /* Trigger on External Event 10 */ - HRTIM_ADCTRG24_AC2 = (1 << 10), - HRTIM_ADCTRG24_AC3 = (1 << 11), - HRTIM_ADCTRG24_AC4 = (1 << 12), - HRTIM_ADCTRG24_APER = (1 << 13), + HRTIM_ADCTRG24_AC2 = (1 << 10), /* Trigger on Timer A Compare 2 */ + HRTIM_ADCTRG24_AC3 = (1 << 11), /* Trigger on Timer A Compare 3 */ + HRTIM_ADCTRG24_AC4 = (1 << 12), /* Trigger on Timer A Compare 4 */ + HRTIM_ADCTRG24_APER = (1 << 13), /* Trigger on Timer A Period */ - HRTIM_ADCTRG24_BC2 = (1 << 14), - HRTIM_ADCTRG24_BC3 = (1 << 15), - HRTIM_ADCTRG24_BC4 = (1 << 16), - HRTIM_ADCTRG24_BPER = (1 << 17), + HRTIM_ADCTRG24_BC2 = (1 << 14), /* Trigger on Timer B Compare 2 */ + HRTIM_ADCTRG24_BC3 = (1 << 15), /* Trigger on Timer B Compare 3 */ + HRTIM_ADCTRG24_BC4 = (1 << 16), /* Trigger on Timer B Compare 4 */ + HRTIM_ADCTRG24_BPER = (1 << 17), /* Trigger on Timer B Period */ - HRTIM_ADCTRG24_CC2 = (1 << 18), - HRTIM_ADCTRG24_CC3 = (1 << 19), - HRTIM_ADCTRG24_CC4 = (1 << 20), - HRTIM_ADCTRG24_CPER = (1 << 21), - HRTIM_ADCTRG24_CRST = (1 << 22), + HRTIM_ADCTRG24_CC2 = (1 << 18), /* Trigger on Timer C Compare 2 */ + HRTIM_ADCTRG24_CC3 = (1 << 19), /* Trigger on Timer C Compare 3 */ + HRTIM_ADCTRG24_CC4 = (1 << 20), /* Trigger on Timer C Compare 4 */ + HRTIM_ADCTRG24_CPER = (1 << 21), /* Trigger on Timer C Period */ + HRTIM_ADCTRG24_CRST = (1 << 22), /* Trigger on Timer C Reset */ - HRTIM_ADCTRG24_DC2 = (1 << 23), - HRTIM_ADCTRG24_DC3 = (1 << 24), - HRTIM_ADCTRG24_DC4 = (1 << 25), - HRTIM_ADCTRG24_DPER = (1 << 26), - HRTIM_ADCTRG24_DRST = (1 << 27), + HRTIM_ADCTRG24_DC2 = (1 << 23), /* Trigger on Timer D Compare 2 */ + HRTIM_ADCTRG24_DC3 = (1 << 24), /* Trigger on Timer D Compare 3 */ + HRTIM_ADCTRG24_DC4 = (1 << 25), /* Trigger on Timer D Compare 4 */ + HRTIM_ADCTRG24_DPER = (1 << 26), /* Trigger on Timer D Period */ + HRTIM_ADCTRG24_DRST = (1 << 27), /* Trigger on Timer D Reset */ - HRTIM_ADCTRG24_EC2 = (1 << 28), - HRTIM_ADCTRG24_EC3 = (1 << 29), - HRTIM_ADCTRG24_EC4 = (1 << 30), - HRTIM_ADCTRG24_ERST = (1 << 31), + HRTIM_ADCTRG24_EC2 = (1 << 28), /* Trigger on Timer E Compare 2 */ + HRTIM_ADCTRG24_EC3 = (1 << 29), /* Trigger on Timer E Compare 3 */ + HRTIM_ADCTRG24_EC4 = (1 << 30), /* Trigger on Timer E Compare 4 */ + HRTIM_ADCTRG24_ERST = (1 << 31), /* Trigger on Timer E Reset */ }; /* HRTIM DAC synchronization events */ diff --git a/arch/arm/src/stm32/stm32f33xxx_adc.c b/arch/arm/src/stm32/stm32f33xxx_adc.c index 252827e5e63..ba0461fe250 100644 --- a/arch/arm/src/stm32/stm32f33xxx_adc.c +++ b/arch/arm/src/stm32/stm32f33xxx_adc.c @@ -99,6 +99,10 @@ # error "ADC HRTIM Triggering support only with DMA" #endif +#if defined(CONFIG_STM32_ADC1_INJECTED) || defined(CONFIG_STM32_ADC2_INJECTED) +# define ADC_HAVE_INJECTED 1 +#endif + #ifdef ADC_HAVE_INJECTED # error "ADC injected trigger not implemented yet" #endif @@ -317,7 +321,7 @@ /* Last bit of the extsel fields indicate if external trigger is in use */ -#define HAVE_EXTSEL_MASK (1<<8) +#define HAVE_EXTSEL_MASK (1<<31) #if defined(ADC1_HAVE_TIMER) || defined(ADC1_HAVE_HRTIM) || defined(ADC1_HAVE_EXTI) # define ADC1_HAVE_EXTSEL 1 @@ -339,6 +343,24 @@ # define ADC_HAVE_JEXTSEL #endif +/* Default ADC resolution */ + +#ifndef ADC1_RESOLUTION +# define ADC1_RESOLUTION ADC_RESOLUTION_12BIT +#endif +#ifndef ADC2_RESOLUTION +# define ADC2_RESOLUTION ADC_RESOLUTION_12BIT +#endif + +/* Default ADC DMA configuration */ + +#ifndef ADC1_DMA_CFG +# define ADC1_DMA_CFG ADC_CFGR_DMACFG +#endif +#ifndef ADC2_DMA_CFG +# define ADC2_DMA_CFG ADC_CFGR_DMACFG +#endif + /**************************************************************************** * Private Types ****************************************************************************/ @@ -347,17 +369,21 @@ struct stm32_dev_s { +#ifdef CONFIG_STM32_ADC_NOIRQ + FAR const struct stm32_adc_ops_s *ops; /* Publicly visible portion */ +#else FAR const struct adc_callback_s *cb; -#ifndef CONFIG_STM32_ADC_NOIRQ uint8_t irq; /* Interrupt generated by this ADC block */ #endif uint8_t nchannels; /* Number of channels */ uint8_t cr_channels; /* Number of configured regular channels */ uint8_t cj_channels; /* Number of configured injected channels */ uint8_t intf; /* ADC interface number */ + uint8_t resolution; /* ADC resolution*/ uint8_t current; /* Current ADC channel being converted */ #ifdef ADC_HAVE_DMA uint8_t dmachan; /* DMA channel needed by this ADC */ + uint8_t dmacfg; /* DMA channel configuration */ bool hasdma; /* True: This channel supports DMA */ #endif #ifdef ADC_HAVE_TIMER @@ -388,12 +414,6 @@ struct stm32_dev_s /* DMA transfer buffer for regular channels */ uint16_t r_dmabuffer[ADC_REG_MAX_SAMPLES]; - -# ifdef ADC_HAVE_INJECTED - /* DMA transfer buffer for injected channels */ - - uint16_t j_dmabuffer[ADC_INJ_MAX_SAMPLES]; -# endif #endif /* List of selected ADC regular channels to sample */ @@ -434,8 +454,10 @@ static void adc_rccreset(FAR struct stm32_dev_s *priv, bool reset); /* ADC Interrupt Handler */ +#ifndef CONFIG_STM32_ADC_NOIRQ static int adc_interrupt(FAR struct adc_dev_s *dev); static int adc12_interrupt(int irq, FAR void *context, FAR void *arg); +#endif /* ADC Driver Methods */ @@ -457,12 +479,28 @@ static void adc_timstart(FAR struct stm32_dev_s *priv, bool enable); static int adc_timinit(FAR struct stm32_dev_s *priv); #endif -#ifdef ADC_HAVE_DMA +#if defined(ADC_HAVE_DMA) && !defined(CONFIG_STM32_ADC_NOIRQ) static void adc_dmaconvcallback(DMA_HANDLE handle, uint8_t isr, FAR void *arg); #endif static void adc_startconv(FAR struct stm32_dev_s *priv, bool enable); +#ifdef ADC_HAVE_INJECTED +static void adc_inj_startconv(FAR struct stm32_dev_s *priv, bool enable); +#endif + +#ifdef CONFIG_STM32_ADC_NOIRQ +static void adc_intack(FAR struct stm32_adc_dev_s *dev, uint32_t source); +static void adc_inten(FAR struct stm32_adc_dev_s *dev, uint32_t source); +static uint32_t adc_intget(FAR struct stm32_adc_dev_s *dev); +static uint32_t adc_regget(FAR struct stm32_adc_dev_s *dev); +# ifdef ADC_HAVE_DMA +static int adc_regbufregister(FAR struct stm32_adc_dev_s *dev, uint16_t *buffer, uint8_t len); +# endif +# ifdef ADC_HAVE_INJECTED +static uint32_t adc_injget(FAR struct stm32_adc_dev_s *dev, uint8_t chan); +# endif +#endif /**************************************************************************** * Private Data @@ -480,16 +518,37 @@ static const struct adc_ops_s g_adcops = .ao_ioctl = adc_ioctl, }; +/* Publicly visible ADC lower-half operations */ + +#ifdef CONFIG_STM32_ADC_NOIRQ +static const struct stm32_adc_ops_s g_adc_lowerops = +{ + .int_ack = adc_intack, + .int_get = adc_intget, + .int_en = adc_inten, + .val_get = adc_regget, +#ifdef ADC_HAVE_DMA + .regbuf_reg = adc_regbufregister, +#endif +#ifdef ADC_HAVE_INJECTED + .inj_get = adc_injget, +#endif +}; +#endif + /* ADC1 state */ #ifdef CONFIG_STM32_ADC1 static struct stm32_dev_s g_adcpriv1 = { -#ifndef CONFIG_STM32_ADC_NOIRQ +#ifdef CONFIG_STM32_ADC_NOIRQ + .ops = &g_adc_lowerops, +#else .irq = STM32_IRQ_ADC12, .isr = adc12_interrupt, #endif .intf = 1, + .resolution = ADC1_RESOLUTION, .base = STM32_ADC1_BASE, .smp1 = ADC1_SMPR1, .smp2 = ADC1_SMPR2, @@ -507,6 +566,7 @@ static struct stm32_dev_s g_adcpriv1 = #endif #ifdef ADC1_HAVE_DMA .dmachan = ADC1_DMA_CHAN, + .dmacfg = ADC1_DMA_CFG, .hasdma = true, #endif }; @@ -523,11 +583,14 @@ static struct adc_dev_s g_adcdev1 = #ifdef CONFIG_STM32_ADC2 static struct stm32_dev_s g_adcpriv2 = { -#ifndef CONFIG_STM32_ADC_NOIRQ +#ifdef CONFIG_STM32_ADC_NOIRQ + .ops = &g_adc_lowerops, +#else .irq = STM32_IRQ_ADC12, .isr = adc12_interrupt, #endif .intf = 2, + .resolution = ADC2_RESOLUTION, .base = STM32_ADC2_BASE, .smp1 = ADC2_SMPR1, .smp2 = ADC2_SMPR2, @@ -545,6 +608,7 @@ static struct stm32_dev_s g_adcpriv2 = #endif #ifdef ADC2_HAVE_DMA .dmachan = ADC2_DMA_CHAN, + .dmacfg = ADC2_DMA_CFG, .hasdma = true, #endif }; @@ -1133,7 +1197,7 @@ static void adc_startconv(FAR struct stm32_dev_s *priv, bool enable) { uint32_t regval; - ainfo("enable: %d\n", enable ? 1 : 0); + ainfo("regular enable: %d\n", enable ? 1 : 0); if (enable) { @@ -1160,6 +1224,53 @@ static void adc_startconv(FAR struct stm32_dev_s *priv, bool enable) } } +/**************************************************************************** + * Name: adc_inj_startconv + * + * Description: + * Start (or stop) the ADC conversion process + * + * Input Parameters: + * priv - A reference to the ADC block status + * enable - True: Start conversion + * + * Returned Value: + * + ****************************************************************************/ + +#ifdef ADC_HAVE_INJECTED +static void adc_inj_startconv(FAR struct stm32_dev_s *priv, bool enable) +{ + uint32_t regval; + + ainfo("injected enable: %d\n", enable ? 1 : 0); + + if (enable) + { + /* Start the conversion of regular channels */ + + adc_modifyreg(priv, STM32_ADC_CR_OFFSET, 0, ADC_CR_JADSTART); + } + else + { + regval = adc_getreg(priv, STM32_ADC_CR_OFFSET); + + /* Is a conversion ongoing? */ + + if ((regval & ADC_CR_JADSTART) != 0) + { + /* Stop the conversion */ + + adc_putreg(priv, STM32_ADC_CR_OFFSET, regval | ADC_CR_JADSTP); + + /* Wait for the conversion to stop */ + + while ((adc_getreg(priv, STM32_ADC_CR_OFFSET) & ADC_CR_JADSTP) != 0); + } + } +} +#endif + /**************************************************************************** * Name: adc_rccreset * @@ -1287,7 +1398,7 @@ static void adc_enable(FAR struct stm32_dev_s *priv, bool enable) * ****************************************************************************/ -#ifdef ADC_HAVE_DMA +#if defined(ADC_HAVE_DMA) && !defined(CONFIG_STM32_ADC_NOIRQ) static void adc_dmaconvcallback(DMA_HANDLE handle, uint8_t isr, FAR void *arg) { FAR struct adc_dev_s *dev = (FAR struct adc_dev_s *)arg; @@ -1333,10 +1444,13 @@ static void adc_dmaconvcallback(DMA_HANDLE handle, uint8_t isr, FAR void *arg) static int adc_bind(FAR struct adc_dev_s *dev, FAR const struct adc_callback_s *callback) { +#ifndef CONFIG_STM32_ADC_NOIRQ FAR struct stm32_dev_s *priv = (FAR struct stm32_dev_s *)dev->ad_priv; DEBUGASSERT(priv != NULL); priv->cb = callback; +#endif + return OK; } @@ -1424,15 +1538,17 @@ static void adc_reset(FAR struct adc_dev_s *dev) /* Set the resolution of the conversion */ clrbits |= ADC_CFGR_RES_MASK; - setbits |= ADC_CFGR_RES_12BIT; + setbits |= priv->resolution << ADC_CFGR_RES_SHIFT; #ifdef ADC_HAVE_DMA if (priv->hasdma) { - /* Set DMA one shot mode. TODO: it must be configurable */ + /* Set DMA mode */ clrbits |= ADC_CFGR_DMACFG; + setbits |= priv->dmacfg; + /* Enable DMA */ setbits |= ADC_CFGR_DMAEN; @@ -1498,6 +1614,7 @@ static void adc_reset(FAR struct adc_dev_s *dev) priv->dma = stm32_dmachannel(priv->dmachan); +#ifndef CONFIG_STM32_ADC_NOIRQ stm32_dmasetup(priv->dma, priv->base + STM32_ADC_DR_OFFSET, (uint32_t)priv->r_dmabuffer, @@ -1505,6 +1622,7 @@ static void adc_reset(FAR struct adc_dev_s *dev) ADC_DMA_CONTROL_WORD); stm32_dmastart(priv->dma, adc_dmaconvcallback, dev, false); +#endif } #endif @@ -1605,7 +1723,7 @@ static int adc_setup(FAR struct adc_dev_s *dev) #ifndef CONFIG_STM32_ADC_NOIRQ FAR struct stm32_dev_s *priv = (FAR struct stm32_dev_s *)dev->ad_priv; #endif - int ret; + int ret = OK; /* Attach the ADC interrupt */ @@ -1930,6 +2048,102 @@ static int adc12_interrupt(int irq, FAR void *context, FAR void *arg) } #endif +#ifdef CONFIG_STM32_ADC_NOIRQ + +/**************************************************************************** + * Name: adc_intack + ****************************************************************************/ + +static void adc_intack(FAR struct stm32_adc_dev_s *dev, uint32_t source) +{ + FAR struct stm32_dev_s *priv = (FAR struct stm32_dev_s *)dev; + + /* Clear pending interrupts */ + + adc_putreg(priv, STM32_ADC_ISR_OFFSET, source); +} + +/**************************************************************************** + * Name: adc_inten + ****************************************************************************/ + +static void adc_inten(FAR struct stm32_adc_dev_s *dev, uint32_t source) +{ + FAR struct stm32_dev_s *priv = (FAR struct stm32_dev_s *)dev; + + /* Enable interrupts */ + + adc_modifyreg(priv, STM32_ADC_IER_OFFSET, 0, source); +} + +/**************************************************************************** + * Name: adc_ackget + ****************************************************************************/ + +static uint32_t adc_intget(FAR struct stm32_adc_dev_s *dev) +{ + FAR struct stm32_dev_s *priv = (FAR struct stm32_dev_s *)dev; + uint32_t regval; + uint32_t pending; + + regval = adc_getreg(priv, STM32_ADC_ISR_OFFSET); + pending = regval & ADC_ISR_ALLINTS; + + return pending; +} + + +/**************************************************************************** + * Name: adc_regget + ****************************************************************************/ + +static uint32_t adc_regget(FAR struct stm32_adc_dev_s *dev) +{ + FAR struct stm32_dev_s *priv = (FAR struct stm32_dev_s *)dev; + + return adc_getreg(priv, STM32_ADC_DR_OFFSET) & ADC_DR_RDATA_MASK; +} + +/**************************************************************************** + * Name: adc_regbufregister + ****************************************************************************/ + +static int adc_regbufregister(FAR struct stm32_adc_dev_s *dev, uint16_t *buffer, uint8_t len) +{ + FAR struct stm32_dev_s *priv = (FAR struct stm32_dev_s *)dev; + + stm32_dmasetup(priv->dma, + priv->base + STM32_ADC_DR_OFFSET, + (uint32_t)buffer, + len, + ADC_DMA_CONTROL_WORD); + + /* No DMA callback */ + + stm32_dmastart(priv->dma, NULL, dev, false); + + return OK; +} + +/**************************************************************************** + * Name: adc_inj_get + ****************************************************************************/ + +#ifdef ADC_HAVE_INJECTED +static uint32_t adc_injget(FAR struct stm32_adc_dev_s *dev, uint8_t chan) +{ + FAR struct stm32_dev_s *priv = (FAR struct stm32_dev_s *)dev; + + if (chan > priv->cj_channels) + { + return 0; + } + + return adc_getreg(priv, STM32_ADC_JDR1_OFFSET+4*(chan-1)) & ADC_JDR_JDATA_MASK; +} +#endif +#endif + /**************************************************************************** * Public Functions ****************************************************************************/ @@ -1960,19 +2174,18 @@ static int adc12_interrupt(int irq, FAR void *context, FAR void *arg) * ****************************************************************************/ -struct adc_dev_s *stm32_adcinitialize(int intf, FAR const uint8_t *r_chanlist, - int cr_channels) +#ifndef ADC_HAVE_INJECTED +struct adc_dev_s *stm32_adcinitialize(int intf, + FAR const uint8_t *r_chanlist, int cr_channels) +#else + struct adc_dev_s *stm32_adcinitialize(int intf, + FAR const uint8_t *r_chanlist, int cr_channels, + FAR const uint8_t *j_chanlist, int cj_channels) +#endif { FAR struct adc_dev_s *dev; FAR struct stm32_dev_s *priv; -#ifdef ADC_HAVE_INJECTED - ainfo("intf: %d cr_channels: %d, cj_channels: %d\n", - intf, cr_channels, cj_channels); -#else - ainfo("intf: %d cr_channels: %d\n", intf, cr_channels); -#endif - switch (intf) { #ifdef CONFIG_STM32_ADC1 @@ -1996,18 +2209,33 @@ struct adc_dev_s *stm32_adcinitialize(int intf, FAR const uint8_t *r_chanlist, priv = (FAR struct stm32_dev_s *)dev->ad_priv; - DEBUGASSERT(cchannels <= ADC_MAX_SAMPLES); + DEBUGASSERT(cr_channels <= ADC_REG_MAX_SAMPLES); - priv->cb = NULL; + /* Configure regular channels */ priv->cr_channels = cr_channels; memcpy(priv->r_chanlist, r_chanlist, cr_channels); #ifdef ADC_HAVE_INJECTED + /* Configur injected channels */ + + DEBUGASSERT(cj_channels <= ADC_INJ_MAX_SAMPLES); + priv->cj_channels = cj_channels; memcpy(priv->j_chanlist, j_chanlist, cj_channels); #endif +#ifndef CONFIG_STM32_ADC_NOIRQ + priv->cb = NULL; +#endif + +#ifdef ADC_HAVE_INJECTED + ainfo("intf: %d cr_channels: %d, cj_channels: %d\n", + intf, cr_channels, priv->cj_channels); +#else + ainfo("intf: %d cr_channels: %d\n", intf, cr_channels); +#endif + return dev; } diff --git a/arch/arm/src/stm32/stm32f33xxx_dma.c b/arch/arm/src/stm32/stm32f33xxx_dma.c index e23a64414f5..af091e2fec6 100644 --- a/arch/arm/src/stm32/stm32f33xxx_dma.c +++ b/arch/arm/src/stm32/stm32f33xxx_dma.c @@ -698,4 +698,34 @@ void stm32_dmadump(DMA_HANDLE handle, const struct stm32_dmaregs_s *regs, } #endif +/**************************************************************************** + * Name: stm32_dma_intack + * + * Description: + * Public visible interface to acknowledge interrupts on DMA channel + * + ****************************************************************************/ + +void stm32_dma_intack(unsigned int chndx, uint32_t isr) +{ + struct stm32_dma_s *dmach = &g_dma[chndx]; + + dmabase_putreg(dmach, STM32_DMA_IFCR_OFFSET, isr); +} + +/**************************************************************************** + * Name: stm32_dma_intget + * + * Description: + * Public visible interface to get pending interrupts from DMA channel + * + ****************************************************************************/ + +uint32_t stm32_dma_intget(unsigned int chndx) +{ + struct stm32_dma_s *dmach = &g_dma[chndx]; + + return dmabase_getreg(dmach, STM32_DMA_ISR_OFFSET) & DMA_ISR_CHAN_MASK(dmach->chan); +} + #endif /* CONFIG_STM32_DMA1 && CONFIG_STM32_STM32F33XX */ diff --git a/configs/nucleo-f334r8/Kconfig b/configs/nucleo-f334r8/Kconfig index e9018b63a38..d158d1397a7 100644 --- a/configs/nucleo-f334r8/Kconfig +++ b/configs/nucleo-f334r8/Kconfig @@ -5,4 +5,8 @@ if ARCH_BOARD_NUCLEO_F334R8 +config NUCLEOF334R8_HIGHPRI + bool "High priority interrupt test" + default n + endif diff --git a/configs/nucleo-f334r8/include/board.h b/configs/nucleo-f334r8/include/board.h index 0a12bef6e26..13be4556a98 100644 --- a/configs/nucleo-f334r8/include/board.h +++ b/configs/nucleo-f334r8/include/board.h @@ -249,13 +249,27 @@ #define OPAMP2_VMSEL OPAMP2_VMSEL_PC5 #define OPAMP2_VPSEL OPAMP2_VPSEL_PB14 +/* Configuration specific to high priority interrupts example: + * - HRTIM Timer A trigger for ADC if DMA transfer + * - ADC DMA transfer on DMA1_CH1 + */ + +#ifdef CONFIG_NUCLEOF334R8_HIGHPRI + /* HRTIM */ +#define HRTIM_TIMA_PRESCALER HRTIM_PRESCALER_128 +#define HRTIM_TIMA_MODE HRTIM_MODE_CONT + +#define HRTIM_ADC_TRG1 HRTIM_ADCTRG13_APER + /* DMA channels *************************************************************/ /* ADC */ #define ADC1_DMA_CHAN DMACHAN_ADC1 /* DMA1_CH1 */ -#define ADC2_DMA_CHAN DMACHAN_ADC2_1 /* DMA1_CH2 */ + +#endif /* CONFIG_NUCLEOF334R8_HIGHPRI */ + /**************************************************************************** * Public Data diff --git a/configs/nucleo-f334r8/src/Makefile b/configs/nucleo-f334r8/src/Makefile index c2e188da400..938cdb9c928 100644 --- a/configs/nucleo-f334r8/src/Makefile +++ b/configs/nucleo-f334r8/src/Makefile @@ -88,4 +88,8 @@ ifeq ($(CONFIG_OPAMP),y) CSRCS += stm32_opamp.c endif +ifeq ($(CONFIG_NUCLEOF334R8_HIGHPRI),y) +CSRCS += stm32_highpri.c +endif + include $(TOPDIR)/configs/Board.mk diff --git a/configs/nucleo-f334r8/src/nucleo-f334r8.h b/configs/nucleo-f334r8/src/nucleo-f334r8.h index 6d7d41d330b..4b2929f8aac 100644 --- a/configs/nucleo-f334r8/src/nucleo-f334r8.h +++ b/configs/nucleo-f334r8/src/nucleo-f334r8.h @@ -214,4 +214,16 @@ int stm32_comp_setup(void); int stm32_opamp_setup(void); #endif +/**************************************************************************** + * Name: stm32_hrtim_setup + * + * Description: + * Initialize HRTIM peripheral for the board. + * + ****************************************************************************/ + +#ifdef CONFIG_HRTIM +int stm32_hrtim_setup(void); +#endif + #endif /* __CONFIGS_NUCLEO_F334R8_SRC_NUCLEO_F334R8_H */ diff --git a/configs/nucleo-f334r8/src/stm32_appinit.c b/configs/nucleo-f334r8/src/stm32_appinit.c index 7f84f6deb2d..cffca5ceeb2 100644 --- a/configs/nucleo-f334r8/src/stm32_appinit.c +++ b/configs/nucleo-f334r8/src/stm32_appinit.c @@ -96,6 +96,7 @@ int board_app_initialize(uintptr_t arg) { int ret; +#ifndef CONFIG_NUCLEOF334R8_HIGHPRI #ifdef HAVE_LEDS /* Register the LED driver */ @@ -145,6 +146,7 @@ int board_app_initialize(uintptr_t arg) { syslog(LOG_ERR, "ERROR: stm32_opamp_setup failed: %d\n", ret); } +#endif #endif UNUSED(ret); diff --git a/configs/nucleo-f334r8/src/stm32_highpri.c b/configs/nucleo-f334r8/src/stm32_highpri.c new file mode 100644 index 00000000000..003058f3be5 --- /dev/null +++ b/configs/nucleo-f334r8/src/stm32_highpri.c @@ -0,0 +1,394 @@ +/**************************************************************************** + * configs/nucleo-f334r8/src/stm32_highpri.c + * + * Copyright (C) 2017 Gregory Nutt. All rights reserved. + * Author: Mateusz Szafoni + * + * 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 "up_internal.h" +#include "ram_vectors.h" +#include "stm32_tim.h" + +#include +#include + +#include "stm32_hrtim.h" +#include "stm32_adc.h" +#include "stm32_dma.h" + +#ifdef CONFIG_NUCLEOF334R8_HIGHPRI + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ +/* Configuration ************************************************************/ + +#ifndef CONFIG_ARCH_CHIP_STM32F334R8 +# warning This only have been verified with CONFIG_ARCH_CHIP_STM32F334R8 +#endif + +#ifndef CONFIG_ARCH_HIPRI_INTERRUPT +# error CONFIG_ARCH_HIPRI_INTERRUPT is required +#endif + +#ifndef CONFIG_ARCH_RAMVECTORS +# error CONFIG_ARCH_RAMVECTORS is required +#endif + +#ifndef CONFIG_ARCH_IRQPRIO +# error CONFIG_ARCH_IRQPRIO is required +#endif + +#ifndef CONFIG_ARCH_FPU +# warning Set CONFIG_ARCH_FPU for hardware FPU support +#endif + +#ifdef CONFIG_STM32_ADC1_DMA +# if !defined(CONFIG_STM32_HRTIM1) || !defined(CONFIG_STM32_HRTIM_TIMA) +# error "Needs HRTIM TIMA to trigger ADC" +# endif +#endif + +#ifndef CONFIG_STM32_ADC1_DMA +# define ADC1_NCHANNELS 1 +#else +# define ADC1_NCHANNELS 3 +#endif + +#define DEV1_PORT 1 +#define DEV1_NCHANNELS ADC1_NCHANNELS +#define ADC_REF_VOLTAGE 3.3 +#define ADC_VAL_MAX 4095 + +#define HRTIM_CMP_SET(hrtim, tim, index, cmp) \ + hrtim->hd_ops->cmp_update(hrtim, tim, index, cmp) +#define HRTIM_PER_SET(hrtim, tim, per) \ + hrtim->hd_ops->per_update(hrtim, tim, per) + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/* High priority example private data */ + +struct highpri_s +{ + FAR struct stm32_adc_dev_s *adc; +#ifdef CONFIG_STM32_ADC1_DMA + FAR struct hrtim_dev_s *hrtim; +#endif + volatile uint32_t cntr; + volatile uint8_t current; + uint16_t val[DEV1_NCHANNELS]; + float volt[DEV1_NCHANNELS]; +}; + +/* ADC channel list */ + +static const uint8_t g_chanlist1[DEV1_NCHANNELS] = +{ + 1, +#ifdef CONFIG_STM32_ADC1_DMA + 2, + 11 +#endif +}; + +/* Configurations of pins used by ADC channel */ + +static const uint32_t g_pinlist1[DEV1_NCHANNELS] = +{ + GPIO_ADC1_IN1, /* PA0/A0 */ + +#ifdef CONFIG_STM32_ADC1_DMA + GPIO_ADC1_IN2, /* PA1/A1 */ + GPIO_ADC1_IN11, /* PB0/A3 */ +#endif +}; + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +static struct highpri_s g_highpri; + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: adc12_handler + * + * Description: + * This is the handler for the high speed ADC interrupt. + * + ****************************************************************************/ + +#ifndef CONFIG_STM32_ADC1_DMA +void adc12_handler(void) +{ + FAR struct stm32_adc_dev_s *adc = g_highpri.adc; + float ref = ADC_REF_VOLTAGE; + float bit = ADC_VAL_MAX; + uint32_t pending; + + g_highpri.cntr += 1; + + pending = adc->ops->int_get(adc); + + if (pending & ADC_INT_EOC) + { + g_highpri.val[g_highpri.current] = adc->ops->val_get(adc); + + /* Do some floating point operations */ + + g_highpri.volt[g_highpri.current] = (float)g_highpri.val[g_highpri.current] * ref / bit; + + if (g_highpri.current >= DEV1_NCHANNELS-1) + { + g_highpri.current = 0; + } + else + { + g_highpri.current += 1; + } + } + + adc->ops->int_ack(adc, pending); + +} +#endif + +/**************************************************************************** + * Name: dmach1_handler + * + * Description: + * This is the handler for the high speed ADC interrupt using DMA transfer. + * + ****************************************************************************/ + +#ifdef CONFIG_STM32_ADC1_DMA +void dma1ch1_handler(void) +{ + float ref = ADC_REF_VOLTAGE; + float bit = ADC_VAL_MAX; + uint32_t pending; + int i; + + pending = stm32_dma_intget(STM32_DMA1_CHAN1); + + g_highpri.cntr += 1; + + for (i = 0; i < 3; i += 1) + { + /* Do some floating point operations */ + + g_highpri.volt[i] = (float)g_highpri.val[i] * ref / bit; + } + + stm32_dma_intack(STM32_DMA1_CHAN1, pending); +} +#endif + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: highpri_main + * + * Description: + * Main entry point in into the high priority interrupt test. + * + ****************************************************************************/ + +int highpri_main(int argc, char *argv[]) +{ + FAR struct hrtim_dev_s *hrtim; + FAR struct adc_dev_s *adc; + FAR struct highpri_s *highpri; + int ret; + int i; + + highpri = &g_highpri; + + /* Initialize highpri structure */ + + memset(highpri, 0, sizeof(struct highpri_s)); + + printf("\nhighpri_main: Started\n"); + + /* Configure the pins as analog inputs for the selected channels */ + + for (i = 0; i < DEV1_NCHANNELS; i++) + { + stm32_configgpio(g_pinlist1[i]); + } + + /* Initialize ADC driver */ + + adc = stm32_adcinitialize(DEV1_PORT, g_chanlist1, DEV1_NCHANNELS); + if (adc == NULL) + { + aerr("ERROR: Failed to get ADC interface 1\n"); + ret = EXIT_FAILURE; + goto errout; + } + + highpri->adc = (struct stm32_adc_dev_s *)adc->ad_priv; + +#ifdef CONFIG_STM32_ADC1_DMA + /* Configure HRTIM */ + + hrtim = stm32_hrtiminitialize(); + if (hrtim == NULL) + { + printf("ERROR: Failed to get HRTIM1 interface\n"); + ret = EXIT_FAILURE; + goto errout; + } + + highpri->hrtim = hrtim; + + /* Set Timer A Period */ + + HRTIM_PER_SET(hrtim, HRTIM_TIMER_TIMA, 0xFFD0); +#endif + +#ifndef CONFIG_STM32_ADC1_DMA + + /* Attach ADC12 ram vector if no DMA */ + + ret = up_ramvec_attach(STM32_IRQ_ADC12, adc12_handler); + if (ret < 0) + { + fprintf(stderr, "highpri_main: ERROR: up_ramvec_attach failed: %d\n", ret); + ret = EXIT_FAILURE; + goto errout; + } + + /* Set the priority of the ADC12 interrupt vector */ + + ret = up_prioritize_irq(STM32_IRQ_ADC12, NVIC_SYSH_HIGH_PRIORITY); + if (ret < 0) + { + fprintf(stderr, "highpri_main: ERROR: up_prioritize_irq failed: %d\n", ret); + ret = EXIT_FAILURE; + goto errout; + } + + up_enable_irq(STM32_IRQ_ADC12); +#else + + /* Attach DMA1 CH1 ram vector if DMA */ + + ret = up_ramvec_attach(STM32_IRQ_DMA1CH1, dma1ch1_handler); + if (ret < 0) + { + fprintf(stderr, "highpri_main: ERROR: up_ramvec_attach failed: %d\n", ret); + ret = EXIT_FAILURE; + goto errout; + } + + /* Set the priority of the DMA1CH1 interrupt vector */ + + ret = up_prioritize_irq(STM32_IRQ_DMA1CH1, NVIC_SYSH_HIGH_PRIORITY); + if (ret < 0) + { + fprintf(stderr, "highpri_main: ERROR: up_prioritize_irq failed: %d\n", ret); + ret = EXIT_FAILURE; + goto errout; + } + + up_enable_irq(STM32_IRQ_DMA1CH1); +#endif + + /* Setup ADC hardware */ + + adc->ad_ops->ao_setup(adc); + +#ifndef CONFIG_STM32_ADC1_DMA + /* Enable ADC interrupts if no DMA */ + + highpri->adc->ops->int_en(highpri->adc, ADC_INT_EOC); +#else + /* Register ADC buffer for DMA transfer */ + + highpri->adc->ops->regbuf_reg(highpri->adc, g_highpri.val, 3); +#endif + + while(1) + { +#ifndef CONFIG_STM32_ADC1_DMA + /* Software triger */ + + adc->ad_ops->ao_ioctl(adc, ANIOC_TRIGGER, 0); + + usleep(100); + + printf("%d [%d] %0.3fV\n", g_highpri.cntr, g_highpri.current, + g_highpri.volt[g_highpri.current]); +#else + printf("%d ", g_highpri.cntr); + + for (i = 0; i < DEV1_NCHANNELS; i += 1) + { + printf("[%d] %0.3fV, ", i, g_highpri.volt[i]); + } + + printf("\n"); +#endif + sleep(1); + } + +errout: + return ret; +} + +#endif /* CONFIG_NUCLEOF334R8_HIGHPRI */ diff --git a/configs/nucleo-f334r8/src/stm32_hrtim.c b/configs/nucleo-f334r8/src/stm32_hrtim.c index 591e4c6fda0..a3bac42f5d0 100644 --- a/configs/nucleo-f334r8/src/stm32_hrtim.c +++ b/configs/nucleo-f334r8/src/stm32_hrtim.c @@ -45,9 +45,10 @@ #include -#include "stm32.h" +#include "stm32_hrtim.h" -#if defined(CONFIG_HRTIM) && defined(CONFIG_STM32_HRTIM1) +#if defined(CONFIG_HRTIM) && defined(CONFIG_STM32_HRTIM1) && \ + !defined(CONFIG_NUCLEOF334R8_HIGHPRI) /**************************************************************************** * Public Functions diff --git a/configs/stm32f334-disco/src/stm32_hrtim.c b/configs/stm32f334-disco/src/stm32_hrtim.c index 126e3252db8..2310f7d777e 100644 --- a/configs/stm32f334-disco/src/stm32_hrtim.c +++ b/configs/stm32f334-disco/src/stm32_hrtim.c @@ -45,7 +45,7 @@ #include -#include "stm32.h" +#include "stm32_hrtim.h" #if defined(CONFIG_HRTIM) && defined(CONFIG_STM32_HRTIM1) diff --git a/configs/stm32f334-disco/src/stm32_powerled.c b/configs/stm32f334-disco/src/stm32_powerled.c index 0e6e1ed2720..4f6f284e5d4 100644 --- a/configs/stm32f334-disco/src/stm32_powerled.c +++ b/configs/stm32f334-disco/src/stm32_powerled.c @@ -61,7 +61,9 @@ #include -#include "stm32.h" +#include "stm32_comp.h" +#include "stm32_hrtim.h" +#include "stm32_dac.h" #if defined(CONFIG_EXAMPLES_POWERLED) && defined(CONFIG_DRIVERS_POWERLED)