diff --git a/arch/arm/src/stm32/Kconfig b/arch/arm/src/stm32/Kconfig index db703d0309..1890f2840d 100644 --- a/arch/arm/src/stm32/Kconfig +++ b/arch/arm/src/stm32/Kconfig @@ -1776,6 +1776,8 @@ config STM32_STM32F33XX select STM32_HAVE_OPAMP2 select STM32_HAVE_CCM select STM32_HAVE_TIM1 + select STM32_HAVE_TIM6 + select STM32_HAVE_TIM7 select STM32_HAVE_TIM15 select STM32_HAVE_TIM16 select STM32_HAVE_TIM17 @@ -2506,44 +2508,46 @@ config STM32_SDADC3 depends on STM32_HAVE_SDADC3 select STM32_HAVE_SDADC3_DMA if STM32_DMA2 -config STM32_COMP - bool "COMP" - default n - depends on STM32_STM32L15XX || STM32_STM32F33XX - config STM32_COMP1 bool "COMP1" default n + select STM32_COMP depends on STM32_HAVE_COMP1 config STM32_COMP2 bool "COMP2" default n + select STM32_COMP depends on STM32_HAVE_COMP2 config STM32_COMP3 bool "COMP3" default n + select STM32_COMP depends on STM32_HAVE_COMP3 config STM32_COMP4 bool "COMP4" default n + select STM32_COMP depends on STM32_HAVE_COMP4 config STM32_COMP5 bool "COMP5" default n + select STM32_COMP depends on STM32_HAVE_COMP5 config STM32_COMP6 bool "COMP6" default n + select STM32_COMP depends on STM32_HAVE_COMP6 config STM32_COMP7 bool "COMP7" default n + select STM32_COMP depends on STM32_HAVE_COMP7 config STM32_BKP @@ -2749,28 +2753,28 @@ config STM32_DMA2D The STM32 DMA2D is an Chrom-Art Accelerator for image manipulation available on the STM32F429 and STM32F439 devices. -config STM32_OPAMP - bool "OPAMP" - default n - config STM32_OPAMP1 bool "OPAMP1" default n + select STM32_OPAMP depends on STM32_HAVE_OPAMP1 config STM32_OPAMP2 bool "OPAMP2" default n + select STM32_OPAMP depends on STM32_HAVE_OPAMP2 config STM32_OPAMP3 bool "OPAMP3" default n + select STM32_OPAMP depends on STM32_HAVE_OPAMP3 config STM32_OPAMP4 bool "OPAMP4" default n + select STM32_OPAMP depends on STM32_HAVE_OPAMP4 config STM32_RTC @@ -3066,6 +3070,19 @@ config STM32_TIM bool default n +config STM32_PWM + bool + default n + +config STM32_COMP + bool + default n + depends on STM32_STM32L15XX || STM32_STM32F33XX + +config STM32_OPAMP + bool + default n + config STM32_NOEXT_VECTORS bool "Disable the ARMv7-M EXT vectors" default n @@ -3445,6 +3462,7 @@ config STM32_TIM1_PWM default n depends on STM32_TIM1 select ARCH_HAVE_PWM_PULSECOUNT + select STM32_PWM ---help--- Reserve timer 1 for use by PWM @@ -3686,6 +3704,7 @@ config STM32_TIM2_PWM default n depends on STM32_TIM2 select ARCH_HAVE_PWM_PULSECOUNT + select STM32_PWM ---help--- Reserve timer 2 for use by PWM @@ -3870,6 +3889,7 @@ config STM32_TIM3_PWM default n depends on STM32_TIM3 select ARCH_HAVE_PWM_PULSECOUNT + select STM32_PWM ---help--- Reserve timer 3 for use by PWM @@ -4054,6 +4074,7 @@ config STM32_TIM4_PWM default n depends on STM32_TIM4 select ARCH_HAVE_PWM_PULSECOUNT + select STM32_PWM ---help--- Reserve timer 4 for use by PWM @@ -4238,6 +4259,7 @@ config STM32_TIM5_PWM default n depends on STM32_TIM5 select ARCH_HAVE_PWM_PULSECOUNT + select STM32_PWM ---help--- Reserve timer 5 for use by PWM @@ -4422,6 +4444,7 @@ config STM32_TIM8_PWM default n depends on STM32_TIM8 select ARCH_HAVE_PWM_PULSECOUNT + select STM32_PWM ---help--- Reserve timer 8 for use by PWM @@ -4657,6 +4680,7 @@ config STM32_TIM9_PWM default n depends on STM32_TIM9 select ARCH_HAVE_PWM_PULSECOUNT + select STM32_PWM ---help--- Reserve timer 9 for use by PWM @@ -4766,6 +4790,7 @@ config STM32_TIM10_PWM default n depends on STM32_TIM10 select ARCH_HAVE_PWM_PULSECOUNT + select STM32_PWM ---help--- Reserve timer 10 for use by PWM @@ -4841,6 +4866,7 @@ config STM32_TIM11_PWM default n depends on STM32_TIM11 select ARCH_HAVE_PWM_PULSECOUNT + select STM32_PWM ---help--- Reserve timer 11 for use by PWM @@ -4916,6 +4942,7 @@ config STM32_TIM12_PWM default n depends on STM32_TIM12 select ARCH_HAVE_PWM_PULSECOUNT + select STM32_PWM ---help--- Reserve timer 12 for use by PWM @@ -5025,6 +5052,7 @@ config STM32_TIM13_PWM default n depends on STM32_TIM13 select ARCH_HAVE_PWM_PULSECOUNT + select STM32_PWM ---help--- Reserve timer 13 for use by PWM @@ -5100,6 +5128,7 @@ config STM32_TIM14_PWM default n depends on STM32_TIM14 select ARCH_HAVE_PWM_PULSECOUNT + select STM32_PWM ---help--- Reserve timer 14 for use by PWM @@ -5174,6 +5203,7 @@ config STM32_TIM15_PWM bool "TIM15 PWM" default n depends on STM32_TIM15 + select STM32_PWM ---help--- Reserve timer 15 for use by PWM @@ -5321,6 +5351,7 @@ config STM32_TIM16_PWM bool "TIM16 PWM" default n depends on STM32_TIM16 + select STM32_PWM ---help--- Reserve timer 16 for use by PWM @@ -5414,6 +5445,7 @@ config STM32_TIM17_PWM bool "TIM17 PWM" default n depends on STM32_TIM17 + select STM32_PWM ---help--- Reserve timer 17 for use by PWM diff --git a/arch/arm/src/stm32/Make.defs b/arch/arm/src/stm32/Make.defs index 8f981ec5b7..2d5f7a8c4a 100644 --- a/arch/arm/src/stm32/Make.defs +++ b/arch/arm/src/stm32/Make.defs @@ -199,15 +199,15 @@ ifeq ($(CONFIG_STM32_SDADC),y) CHIP_CSRCS += stm32_sdadc.c endif -ifeq ($(CONFIG_DAC),y) +ifeq ($(CONFIG_STM32_DAC),y) CHIP_CSRCS += stm32_dac.c endif -ifeq ($(CONFIG_COMP),y) +ifeq ($(CONFIG_STM32_COMP),y) CHIP_CSRCS += stm32_comp.c endif -ifeq ($(CONFIG_OPAMP),y) +ifeq ($(CONFIG_STM32_OPAMP),y) CHIP_CSRCS += stm32_opamp.c endif @@ -235,7 +235,7 @@ ifeq ($(CONFIG_STM32_DMA2D),y) CHIP_CSRCS += stm32_dma2d.c endif -ifeq ($(CONFIG_PWM),y) +ifeq ($(CONFIG_STM32_PWM),y) CHIP_CSRCS += stm32_pwm.c endif @@ -243,7 +243,7 @@ ifeq ($(CONFIG_SENSORS_QENCODER),y) CHIP_CSRCS += stm32_qencoder.c endif -ifeq ($(CONFIG_CAN),y) +ifeq ($(CONFIG_STM32_CAN),y) CHIP_CSRCS += stm32_can.c endif diff --git a/arch/arm/src/stm32/stm32_adc.c b/arch/arm/src/stm32/stm32_adc.c index 904843c5b5..2bcdbda7dd 100644 --- a/arch/arm/src/stm32/stm32_adc.c +++ b/arch/arm/src/stm32/stm32_adc.c @@ -83,7 +83,7 @@ * - injected sequence conversion (not supported in upper-half ADC driver) */ -/* ADC "upper half" support must be enabled */ +/* STM32 ADC "lower-half" support must be enabled */ #ifdef CONFIG_STM32_ADC diff --git a/arch/arm/src/stm32/stm32_hrtim.c b/arch/arm/src/stm32/stm32_hrtim.c index 57e26ad817..b71d85059c 100644 --- a/arch/arm/src/stm32/stm32_hrtim.c +++ b/arch/arm/src/stm32/stm32_hrtim.c @@ -4625,7 +4625,6 @@ static int hrtim_irq_cfg(FAR struct stm32_hrtim_s *priv, uint8_t timer, uint16_t hrtim_tim_putreg(priv, timer, STM32_HRTIM_TIM_DIER_OFFSET, irq); } -errout: return ret; } diff --git a/arch/arm/src/stm32/stm32_pwm.c b/arch/arm/src/stm32/stm32_pwm.c index bcb5c47a0b..763a53238e 100644 --- a/arch/arm/src/stm32/stm32_pwm.c +++ b/arch/arm/src/stm32/stm32_pwm.c @@ -49,7 +49,6 @@ #include #include -#include #include #include "up_internal.h" @@ -67,14 +66,7 @@ * 2. STM32 TIMER IP version 2 - F3 (no F37x), F7, H7, L4, L4+ */ -#if defined(CONFIG_STM32_TIM1_PWM) || defined(CONFIG_STM32_TIM2_PWM) || \ - defined(CONFIG_STM32_TIM3_PWM) || defined(CONFIG_STM32_TIM4_PWM) || \ - defined(CONFIG_STM32_TIM5_PWM) || defined(CONFIG_STM32_TIM8_PWM) || \ - defined(CONFIG_STM32_TIM9_PWM) || defined(CONFIG_STM32_TIM10_PWM) || \ - defined(CONFIG_STM32_TIM11_PWM) || defined(CONFIG_STM32_TIM12_PWM) || \ - defined(CONFIG_STM32_TIM13_PWM) || defined(CONFIG_STM32_TIM14_PWM) || \ - defined(CONFIG_STM32_TIM15_PWM) || defined(CONFIG_STM32_TIM16_PWM) || \ - defined(CONFIG_STM32_TIM17_PWM) +#ifdef CONFIG_STM32_PWM /**************************************************************************** * Pre-processor Definitions @@ -4691,5 +4683,4 @@ errout: return (FAR struct pwm_lowerhalf_s *)lower; } -#endif /* CONFIG_STM32_TIMn_PWM, n = 1,...,17 */ - +#endif /* CONFIG_STM32_PWM */ diff --git a/arch/arm/src/stm32/stm32_pwm.h b/arch/arm/src/stm32/stm32_pwm.h index bdd08bd992..ee94ff6b98 100644 --- a/arch/arm/src/stm32/stm32_pwm.h +++ b/arch/arm/src/stm32/stm32_pwm.h @@ -51,6 +51,8 @@ #include +#include + #include "chip.h" /************************************************************************************ @@ -116,23 +118,14 @@ /* Check if PWM support for any channel is enabled. */ -#if defined(CONFIG_STM32_TIM1_PWM) || defined(CONFIG_STM32_TIM2_PWM) || \ - defined(CONFIG_STM32_TIM3_PWM) || defined(CONFIG_STM32_TIM4_PWM) || \ - defined(CONFIG_STM32_TIM5_PWM) || defined(CONFIG_STM32_TIM8_PWM) || \ - defined(CONFIG_STM32_TIM9_PWM) || defined(CONFIG_STM32_TIM10_PWM) || \ - defined(CONFIG_STM32_TIM11_PWM) || defined(CONFIG_STM32_TIM12_PWM) || \ - defined(CONFIG_STM32_TIM13_PWM) || defined(CONFIG_STM32_TIM14_PWM) || \ - defined(CONFIG_STM32_TIM15_PWM) || defined(CONFIG_STM32_TIM16_PWM) || \ - defined(CONFIG_STM32_TIM17_PWM) +#ifdef CONFIG_STM32_PWM #include #include "chip/stm32_tim.h" -#ifdef CONFIG_STM32_PWM_MULTICHAN -# ifndef CONFIG_PWM_MULTICHAN -# error CONFIG_STM32_PWM_MULTICHAN enabled but CONFIG_PWM_MULTICHAN not set! -# endif -#endif +/* Configuration needed by upper-half PWM driver */ + +#ifdef CONFIG_PWM #ifdef CONFIG_PWM_MULTICHAN @@ -612,6 +605,8 @@ #endif /* CONFIG_PWM_MULTICHAN */ +#endif /* CONFIG_PWM */ + #ifdef CONFIG_STM32_TIM1_CH1OUT # define PWM_TIM1_CH1CFG GPIO_TIM1_CH1OUT #else @@ -884,8 +879,12 @@ (dev)->llops->freq_update((FAR struct pwm_lowerhalf_s *)dev, freq) #define PWM_TIM_ENABLE(dev, state) \ (dev)->llops->tim_enable((FAR struct pwm_lowerhalf_s *)dev, state) -#define PWM_DUMP_REGS(dev) \ +#ifdef CONFIG_DEBUG_PWM_INFO +# define PWM_DUMP_REGS(dev) \ (dev)->llops->dump_regs((FAR struct pwm_lowerhalf_s *)dev) +#else +# define PWM_DUMP_REGS(dev) +#endif #define PWM_DT_UPDATE(dev, dt) \ (dev)->llops->dt_update((FAR struct pwm_lowerhalf_s *)dev, dt) @@ -1081,5 +1080,5 @@ FAR struct pwm_lowerhalf_s *stm32_pwminitialize(int timer); #endif #endif /* __ASSEMBLY__ */ -#endif /* CONFIG_STM32_TIMx_PWM */ +#endif /* CONFIG_STM32_PWM */ #endif /* __ARCH_ARM_SRC_STM32_STM32_PWM_H */ diff --git a/arch/arm/src/stm32/stm32_tim.c b/arch/arm/src/stm32/stm32_tim.c index 8b1e5cebf6..003af332aa 100644 --- a/arch/arm/src/stm32/stm32_tim.c +++ b/arch/arm/src/stm32/stm32_tim.c @@ -732,8 +732,11 @@ static int stm32_tim_setmode(FAR struct stm32_tim_dev_s *dev, stm32_tim_mode_t m #if STM32_NATIM > 0 /* Advanced registers require Main Output Enable */ - if (((struct stm32_tim_priv_s *)dev)->base == STM32_TIM1_BASE || - ((struct stm32_tim_priv_s *)dev)->base == STM32_TIM8_BASE) + if (((struct stm32_tim_priv_s *)dev)->base == STM32_TIM1_BASE +#ifdef STM32_TIM8_BASE + || ((struct stm32_tim_priv_s *)dev)->base == STM32_TIM8_BASE +#endif + ) { stm32_modifyreg16(dev, STM32_ATIM_BDTR_OFFSET, 0, ATIM_BDTR_MOE); } diff --git a/configs/nucleo-f302r8/highpri/defconfig b/configs/nucleo-f302r8/highpri/defconfig index c6f16bc255..065ee42786 100644 --- a/configs/nucleo-f302r8/highpri/defconfig +++ b/configs/nucleo-f302r8/highpri/defconfig @@ -1,7 +1,5 @@ # CONFIG_DEV_NULL is not set # CONFIG_LIBC_LONG_LONG is not set -CONFIG_ADC=y -CONFIG_ANALOG=y CONFIG_ARCH="arm" CONFIG_ARCH_BOARD="nucleo-f302r8" CONFIG_ARCH_BOARD_NUCLEO_F302R8=y diff --git a/configs/nucleo-f334r8/Kconfig b/configs/nucleo-f334r8/Kconfig index d158d1397a..624ca89a22 100644 --- a/configs/nucleo-f334r8/Kconfig +++ b/configs/nucleo-f334r8/Kconfig @@ -9,4 +9,42 @@ config NUCLEOF334R8_HIGHPRI bool "High priority interrupt test" default n +menuconfig NUCLEOF334R8_SPWM + bool "Sinusoidal PWM generator example" + default n + +if NUCLEOF334R8_SPWM + +choice + prompt "Sinusoidal PWM source" + default NUCLEOF334R8_SPWM_USE_TIM1 + +config NUCLEOF334R8_SPWM_USE_TIM1 + bool "Use TIM1 as PWM source" + +config NUCLEOF334R8_SPWM_USE_HRTIM1 + bool "Use HRTIM as PWM source" + +endchoice + +config NUCLEOF334R8_SPWM_PWM_FREQ + int "PWM frequency in Hz" + default 100000 + +config NUCLEOF334R8_SPWM_SAMPLES + int "Sine samples" + default 100 + +config NUCLEOF334R8_SPWM_FREQ + int "Waveform frequency in Hz" + default 60 + +config NUCLEOF334R8_SPWM_PHASE_NUM + int "Number of phases" + default 1 + range 1 5 if NUCLEOF334R8_SPWM_USE_HRTIM1 + range 1 4 if NUCLEOF334R8_SPWM_USE_TIM1 + +endif + endif diff --git a/configs/nucleo-f334r8/README.txt b/configs/nucleo-f334r8/README.txt index 1d3c327960..0eec6cc07d 100644 --- a/configs/nucleo-f334r8/README.txt +++ b/configs/nucleo-f334r8/README.txt @@ -24,3 +24,37 @@ Variants include NUCLEO-L152RE STM32L152RET6 NUCLEO-L452RE STM32L452RET6 NUCLEO-L476RG STM32L476RGT6 + +Configurations +============== + + nsh: + ---- + + Configures the NuttShell (nsh) located at apps/examples/nsh. + + adc: + ---- + + Configures the ADC example located at apps/examples/adc. + + highpri: + -------- + + Configures the high priority interrupts example (ADC + PWM) + + spwm1 and spwm2: + ---------------- + + Configures the sinusoidal PWM (SPWM) example which presents a simple use case + of the STM32 PWM lower-half driver without generic upper-half PWM logic. + + There are two variants of this example, where functionality is achieved with + different periperals: + + - spwm1 uses HRTIM to generate PWM and change waveform samples + - spwm2 uses TIM1 to generate PWM and TIM6 to change waveform samples + + At the moment, the waveform parameters are hardcoded, but it should be easy to + modify this example and make it more functional. + diff --git a/configs/nucleo-f334r8/highpri/defconfig b/configs/nucleo-f334r8/highpri/defconfig index 5673b98fdd..e03126c8d4 100644 --- a/configs/nucleo-f334r8/highpri/defconfig +++ b/configs/nucleo-f334r8/highpri/defconfig @@ -1,7 +1,5 @@ # CONFIG_DEV_NULL is not set # CONFIG_LIBC_LONG_LONG is not set -CONFIG_ADC=y -CONFIG_ANALOG=y CONFIG_ARCH="arm" CONFIG_ARCH_BOARD="nucleo-f334r8" CONFIG_ARCH_BOARD_NUCLEO_F334R8=y diff --git a/configs/nucleo-f334r8/include/board.h b/configs/nucleo-f334r8/include/board.h index 57e6baa4b4..796a5c1f83 100644 --- a/configs/nucleo-f334r8/include/board.h +++ b/configs/nucleo-f334r8/include/board.h @@ -279,6 +279,69 @@ #endif /* CONFIG_STM32_TIM1_PWM && CONFIG_STM32_ADC1_DMA */ #endif /* CONFIG_NUCLEOF334R8_HIGHPRI */ +#ifdef CONFIG_NUCLEOF334R8_SPWM +# ifdef CONFIG_NUCLEOF334R8_SPWM_USE_TIM1 + +/* TIM1 PWM configuration ***************************************************/ + +# define PWM_TIM1_NCHANNELS 4 + +# define GPIO_TIM1_CH1OUT GPIO_TIM1_CH1OUT_1 /* TIM1 CH1 - PA8 */ +# define GPIO_TIM1_CH1NOUT GPIO_TIM1_CH1N_3 /* TIM1 CH1N - PA7 */ + /* TIM1 CH2 - PA9 */ +# define GPIO_TIM1_CH2NOUT GPIO_TIM1_CH2N_2 /* TIM1 CH2N - PB0 */ +# define GPIO_TIM1_CH3OUT GPIO_TIM1_CH3OUT_1 /* TIM1 CH3 - PA10 */ +# define GPIO_TIM1_CH3NOUT GPIO_TIM1_CH3N_2 /* TIM1 CH3N - PB1 */ +# define GPIO_TIM1_CH4OUT GPIO_TIM1_CH4OUT_1 /* TIM1 CH4 - PA11 */ +# endif + +# ifdef CONFIG_NUCLEOF334R8_SPWM_USE_HRTIM1 + +/* HRTIM configuration ******************************************************/ + +# define HRTIM_MASTER_PRESCALER HRTIM_PRESCALER_128 +# define HRTIM_MASTER_MODE HRTIM_MODE_CONT + +# define HRTIM_TIMA_PRESCALER HRTIM_PRESCALER_128 +# define HRTIM_TIMA_MODE (HRTIM_MODE_CONT | HRTIM_MODE_PRELOAD) +# define HRTIM_TIMA_CH1_SET HRTIM_OUT_SET_PER +# define HRTIM_TIMA_CH1_RST HRTIM_OUT_RST_CMP1 +# define HRTIM_TIMA_UPDATE HRTIM_UPDATE_MSTU +# define HRTIM_TIMA_RESET 0 + +# define HRTIM_TIMB_PRESCALER HRTIM_PRESCALER_128 +# define HRTIM_TIMB_MODE (HRTIM_MODE_CONT | HRTIM_MODE_PRELOAD) +# define HRTIM_TIMB_CH1_SET HRTIM_OUT_SET_PER +# define HRTIM_TIMB_CH1_RST HRTIM_OUT_RST_CMP1 +# define HRTIM_TIMB_UPDATE HRTIM_UPDATE_MSTU +# define HRTIM_TIMB_RESET 0 + +# define HRTIM_TIMC_PRESCALER HRTIM_PRESCALER_128 +# define HRTIM_TIMC_MODE (HRTIM_MODE_CONT | HRTIM_MODE_PRELOAD) +# define HRTIM_TIMC_CH1_SET HRTIM_OUT_SET_PER +# define HRTIM_TIMC_CH1_RST HRTIM_OUT_RST_CMP1 +# define HRTIM_TIMC_UPDATE HRTIM_UPDATE_MSTU +# define HRTIM_TIMC_RESET 0 + +# define HRTIM_TIMD_PRESCALER HRTIM_PRESCALER_128 +# define HRTIM_TIMD_MODE (HRTIM_MODE_CONT | HRTIM_MODE_PRELOAD) +# define HRTIM_TIMD_CH1_SET HRTIM_OUT_SET_PER +# define HRTIM_TIMD_CH1_RST HRTIM_OUT_RST_CMP1 +# define HRTIM_TIMD_UPDATE HRTIM_UPDATE_MSTU +# define HRTIM_TIMD_RESET 0 + +# define HRTIM_TIME_PRESCALER HRTIM_PRESCALER_128 +# define HRTIM_TIME_MODE (HRTIM_MODE_CONT | HRTIM_MODE_PRELOAD) +# define HRTIM_TIME_CH1_SET HRTIM_OUT_SET_PER +# define HRTIM_TIME_CH1_RST HRTIM_OUT_RST_CMP1 +# define HRTIM_TIME_UPDATE HRTIM_UPDATE_MSTU +# define HRTIM_TIME_RESET 0 + +# define HRTIM_MASTER_IRQ HRTIM_IRQ_MCMP1 +# endif + +#endif /* CONFIG_NUCLEOF334R8_SPWM */ + /* DMA channels *************************************************************/ /* ADC */ diff --git a/configs/nucleo-f334r8/spwm1/defconfig b/configs/nucleo-f334r8/spwm1/defconfig new file mode 100644 index 0000000000..a4901453e9 --- /dev/null +++ b/configs/nucleo-f334r8/spwm1/defconfig @@ -0,0 +1,79 @@ +# CONFIG_DEV_NULL is not set +# CONFIG_LIBC_LONG_LONG is not set +CONFIG_ARCH="arm" +CONFIG_ARCH_BOARD="nucleo-f334r8" +CONFIG_ARCH_BOARD_NUCLEO_F334R8=y +CONFIG_ARCH_BUTTONS=y +CONFIG_ARCH_CHIP_STM32=y +CONFIG_ARCH_CHIP_STM32F334R8=y +CONFIG_ARCH_HIPRI_INTERRUPT=y +CONFIG_ARCH_RAMVECTORS=y +CONFIG_ARCH_STACKDUMP=y +CONFIG_BOARD_LOOPSPERMSEC=16717 +CONFIG_BUILTIN=y +CONFIG_BUILTIN_PROXY_STACKSIZE=512 +CONFIG_DISABLE_ENVIRON=y +CONFIG_DISABLE_MQUEUE=y +CONFIG_DISABLE_POLL=y +CONFIG_DISABLE_POSIX_TIMERS=y +CONFIG_FDCLONE_STDIO=y +CONFIG_INTELHEX_BINARY=y +CONFIG_LIBC_FLOATINGPOINT=y +CONFIG_LIBM=y +CONFIG_LIB_BOARDCTL=y +CONFIG_MAX_TASKS=4 +CONFIG_MAX_WDOGPARMS=1 +CONFIG_NAME_MAX=16 +CONFIG_NFILE_DESCRIPTORS=8 +CONFIG_NFILE_STREAMS=8 +CONFIG_NUCLEOF334R8_SPWM=y +CONFIG_NUCLEOF334R8_SPWM_PHASE_NUM=3 +CONFIG_NUCLEOF334R8_SPWM_USE_HRTIM1=y +CONFIG_POSIX_SPAWN_PROXY_STACKSIZE=512 +CONFIG_PREALLOC_TIMERS=2 +CONFIG_PREALLOC_WDOGS=1 +CONFIG_PTHREAD_STACK_DEFAULT=1024 +CONFIG_PTHREAD_STACK_MIN=1024 +CONFIG_RAM_SIZE=12288 +CONFIG_RAM_START=0x20000000 +CONFIG_RAW_BINARY=y +CONFIG_RR_INTERVAL=200 +CONFIG_SCHED_WAITPID=y +CONFIG_SDCLONE_DISABLE=y +CONFIG_START_DAY=6 +CONFIG_START_MONTH=12 +CONFIG_START_YEAR=2011 +CONFIG_STM32_CCMEXCLUDE=y +CONFIG_STM32_HRTIM1=y +CONFIG_STM32_HRTIM_CLK_FROM_PLL=y +CONFIG_STM32_HRTIM_DISABLE_CHARDRV=y +CONFIG_STM32_HRTIM_INTERRUPTS=y +CONFIG_STM32_HRTIM_MASTER=y +CONFIG_STM32_HRTIM_MASTER_IRQ=y +CONFIG_STM32_HRTIM_NO_ENABLE_TIMERS=y +CONFIG_STM32_HRTIM_PWM=y +CONFIG_STM32_HRTIM_TIMA=y +CONFIG_STM32_HRTIM_TIMA_PWM=y +CONFIG_STM32_HRTIM_TIMA_PWM_CH1=y +CONFIG_STM32_HRTIM_TIMB=y +CONFIG_STM32_HRTIM_TIMB_PWM=y +CONFIG_STM32_HRTIM_TIMB_PWM_CH1=y +CONFIG_STM32_HRTIM_TIMC=y +CONFIG_STM32_HRTIM_TIMC_PWM=y +CONFIG_STM32_HRTIM_TIMC_PWM_CH1=y +CONFIG_STM32_HRTIM_TIMD=y +CONFIG_STM32_HRTIM_TIMD_PWM=y +CONFIG_STM32_HRTIM_TIMD_PWM_CH1=y +CONFIG_STM32_HRTIM_TIME=y +CONFIG_STM32_HRTIM_TIME_PWM=y +CONFIG_STM32_HRTIM_TIME_PWM_CH1=y +CONFIG_STM32_JTAG_SW_ENABLE=y +CONFIG_STM32_PWR=y +CONFIG_STM32_USART2=y +CONFIG_SYSTEM_READLINE=y +CONFIG_TASK_NAME_SIZE=0 +CONFIG_TASK_SPAWN_DEFAULT_STACKSIZE=512 +CONFIG_USART2_SERIAL_CONSOLE=y +CONFIG_USERMAIN_STACKSIZE=1024 +CONFIG_USER_ENTRYPOINT="spwm_main" +CONFIG_WDOG_INTRESERVE=0 diff --git a/configs/nucleo-f334r8/spwm2/defconfig b/configs/nucleo-f334r8/spwm2/defconfig new file mode 100644 index 0000000000..b69630d1a1 --- /dev/null +++ b/configs/nucleo-f334r8/spwm2/defconfig @@ -0,0 +1,71 @@ +# CONFIG_DEV_NULL is not set +# CONFIG_LIBC_LONG_LONG is not set +CONFIG_ARCH="arm" +CONFIG_ARCH_BOARD="nucleo-f334r8" +CONFIG_ARCH_BOARD_NUCLEO_F334R8=y +CONFIG_ARCH_BUTTONS=y +CONFIG_ARCH_CHIP_STM32=y +CONFIG_ARCH_CHIP_STM32F334R8=y +CONFIG_ARCH_HIPRI_INTERRUPT=y +CONFIG_ARCH_RAMVECTORS=y +CONFIG_ARCH_STACKDUMP=y +CONFIG_BOARD_LOOPSPERMSEC=16717 +CONFIG_BUILTIN=y +CONFIG_BUILTIN_PROXY_STACKSIZE=512 +CONFIG_DEBUG_FULLOPT=y +CONFIG_DEBUG_SYMBOLS=y +CONFIG_DISABLE_ENVIRON=y +CONFIG_DISABLE_MQUEUE=y +CONFIG_DISABLE_POLL=y +CONFIG_DISABLE_POSIX_TIMERS=y +CONFIG_FDCLONE_STDIO=y +CONFIG_INTELHEX_BINARY=y +CONFIG_LIBC_FLOATINGPOINT=y +CONFIG_LIBM=y +CONFIG_LIB_BOARDCTL=y +CONFIG_MAX_TASKS=4 +CONFIG_MAX_WDOGPARMS=1 +CONFIG_NAME_MAX=16 +CONFIG_NFILE_DESCRIPTORS=8 +CONFIG_NFILE_STREAMS=8 +CONFIG_NUCLEOF334R8_SPWM=y +CONFIG_NUCLEOF334R8_SPWM_PHASE_NUM=4 +CONFIG_NUCLEOF334R8_SPWM_PWM_FREQ=100000 +CONFIG_POSIX_SPAWN_PROXY_STACKSIZE=512 +CONFIG_PREALLOC_TIMERS=2 +CONFIG_PREALLOC_WDOGS=1 +CONFIG_PTHREAD_STACK_DEFAULT=1024 +CONFIG_PTHREAD_STACK_MIN=1024 +CONFIG_RAM_SIZE=12288 +CONFIG_RAM_START=0x20000000 +CONFIG_RAW_BINARY=y +CONFIG_RR_INTERVAL=200 +CONFIG_SCHED_WAITPID=y +CONFIG_SDCLONE_DISABLE=y +CONFIG_START_DAY=6 +CONFIG_START_MONTH=12 +CONFIG_START_YEAR=2011 +CONFIG_STM32_CCMEXCLUDE=y +CONFIG_STM32_JTAG_SW_ENABLE=y +CONFIG_STM32_PWM_LL_OPS=y +CONFIG_STM32_PWM_MULTICHAN=y +CONFIG_STM32_PWR=y +CONFIG_STM32_TIM1=y +CONFIG_STM32_TIM1_CH1OUT=y +CONFIG_STM32_TIM1_CH2OUT=y +CONFIG_STM32_TIM1_CH3OUT=y +CONFIG_STM32_TIM1_CH4OUT=y +CONFIG_STM32_TIM1_CHANNEL1=y +CONFIG_STM32_TIM1_CHANNEL2=y +CONFIG_STM32_TIM1_CHANNEL3=y +CONFIG_STM32_TIM1_CHANNEL4=y +CONFIG_STM32_TIM1_PWM=y +CONFIG_STM32_TIM6=y +CONFIG_STM32_USART2=y +CONFIG_SYSTEM_READLINE=y +CONFIG_TASK_NAME_SIZE=0 +CONFIG_TASK_SPAWN_DEFAULT_STACKSIZE=512 +CONFIG_USART2_SERIAL_CONSOLE=y +CONFIG_USERMAIN_STACKSIZE=1024 +CONFIG_USER_ENTRYPOINT="spwm_main" +CONFIG_WDOG_INTRESERVE=0 diff --git a/configs/nucleo-f334r8/src/Makefile b/configs/nucleo-f334r8/src/Makefile index 55f3fc2a05..97440419bd 100644 --- a/configs/nucleo-f334r8/src/Makefile +++ b/configs/nucleo-f334r8/src/Makefile @@ -92,4 +92,8 @@ ifeq ($(CONFIG_NUCLEOF334R8_HIGHPRI),y) CSRCS += stm32_highpri.c endif +ifeq ($(CONFIG_NUCLEOF334R8_SPWM),y) +CSRCS += stm32_spwm.c +endif + include $(TOPDIR)/configs/Board.mk diff --git a/configs/nucleo-f334r8/src/stm32_hrtim.c b/configs/nucleo-f334r8/src/stm32_hrtim.c index 7a5fe91be5..93e538b771 100644 --- a/configs/nucleo-f334r8/src/stm32_hrtim.c +++ b/configs/nucleo-f334r8/src/stm32_hrtim.c @@ -47,8 +47,7 @@ #include "stm32_hrtim.h" -#if defined(CONFIG_STM32_HRTIM) && defined(CONFIG_STM32_HRTIM1) && \ - !defined(CONFIG_NUCLEOF334R8_HIGHPRI) +#ifndef CONFIG_STM32_HRTIM_DISABLE_CHARDRV /**************************************************************************** * Public Functions diff --git a/configs/nucleo-f334r8/src/stm32_spwm.c b/configs/nucleo-f334r8/src/stm32_spwm.c new file mode 100644 index 0000000000..a8c316eec2 --- /dev/null +++ b/configs/nucleo-f334r8/src/stm32_spwm.c @@ -0,0 +1,1057 @@ +/**************************************************************************** + * configs/nucleo-f334r8/src/stm32_spwm.c + * + * Copyright (C) 2018 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 + +#include "up_internal.h" +#include "ram_vectors.h" + +#include "stm32_hrtim.h" +#include "stm32_pwm.h" +#include "stm32_tim.h" + +#ifdef CONFIG_NUCLEOF334R8_SPWM + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ +/* Asserions ****************************************************************/ + +#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 + +/* Check the configuration for TIM1 */ + +#ifdef CONFIG_NUCLEOF334R8_SPWM_USE_TIM1 + +/* Phase 1 is TIM1 CH1 */ + +#if CONFIG_NUCLEOF334R8_SPWM_PHASE_NUM > 0 +# ifndef CONFIG_STM32_TIM1_CH1OUT +# error +# endif +# ifndef CONFIG_STM32_TIM6 +# error +# endif +#endif + +/* Phase 2 is TIM1 CH2 */ + +#if CONFIG_NUCLEOF334R8_SPWM_PHASE_NUM > 1 +# ifndef CONFIG_STM32_TIM1_CH2OUT +# error +# endif +#endif + +/* Phase 3 is TIM1 CH3 */ + +#if CONFIG_NUCLEOF334R8_SPWM_PHASE_NUM > 2 +# ifndef CONFIG_STM32_TIM1_CH3OUT +# error +# endif +#endif + +/* Phase 4 is TIM1 CH4 */ + +#if CONFIG_NUCLEOF334R8_SPWM_PHASE_NUM > 3 +# ifndef CONFIG_STM32_TIM1_CH4OUT +# error +# endif +#endif + +#if CONFIG_NUCLEOF334R8_SPWM_PHASE_NUM != PWM_TIM1_NCHANNELS +# error +#endif + +#endif /* CONFIG_NUCLEOF334R8_SPWM_USE_TIM1 */ + +/* Check the configuration for HRTIM */ + +#ifdef CONFIG_NUCLEOF334R8_SPWM_USE_HRTIM1 + +/* Phase 1 is TIMA */ + +#if CONFIG_NUCLEOF334R8_SPWM_PHASE_NUM > 0 +# ifndef CONFIG_STM32_HRTIM_TIMA +# error +# endif +# ifndef CONFIG_STM32_HRTIM_MASTER +# error +# endif +#endif + +/* Phase 2 is TIMB */ + +#if CONFIG_NUCLEOF334R8_SPWM_PHASE_NUM > 1 +# ifndef CONFIG_STM32_HRTIM_TIMB +# error +# endif +#endif + +/* Phase 3 is TIMC */ + +#if CONFIG_NUCLEOF334R8_SPWM_PHASE_NUM > 2 +# ifndef CONFIG_STM32_HRTIM_TIMC +# error +# endif +#endif + +/* Phase 4 is TIMD */ + +#if CONFIG_NUCLEOF334R8_SPWM_PHASE_NUM > 3 +# ifndef CONFIG_STM32_HRTIM_TIMD +# error +# endif +#endif + +/* Phase 5 is TIME */ + +#if CONFIG_NUCLEOF334R8_SPWM_PHASE_NUM > 4 +# ifndef CONFIG_STM32_HRTIM_TIME +# error +# endif +#endif + +#endif /* CONFIG_NUCLEOF334R8_SPWM_USE_HRTIM1 */ + +/* Configuration ************************************************************/ + +#ifdef CONFIG_NUCLEOF334R8_SPWM_USE_HRTIM1 +#define PWM_TIMERS_IN_USE CONFIG_NUCLEOF334R8_SPWM_PHASE_NUM +#endif + +#ifdef CONFIG_NUCLEOF334R8_SPWM_USE_TIM1 +#define PWM_TIMERS_IN_USE 1 +#endif + +#define SPWM_PHASE_SHIFT ((360.0f/CONFIG_NUCLEOF334R8_SPWM_PHASE_NUM)) + +#if defined(CONFIG_NUCLEOF334R8_SPWM_USE_HRTIM1) +# define pwm_timer_s hrtim_dev_s +#elif defined(CONFIG_NUCLEOF334R8_SPWM_USE_TIM1) +# define pwm_timer_s stm32_pwm_dev_s +#else +# error +#endif + +#define SAMPLES_NUM CONFIG_NUCLEOF334R8_SPWM_SAMPLES +#define PHASES_NUM CONFIG_NUCLEOF334R8_SPWM_PHASE_NUM + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/* SPWM private data */ + +struct spwm_s +{ + FAR struct pwm_timer_s *pwm; +#ifdef CONFIG_NUCLEOF334R8_SPWM_USE_TIM1 + FAR struct stm32_tim_dev_s *tim; +#endif + float waveform[SAMPLES_NUM]; /* Waveform samples */ + float phase_step; /* Waveform phase step */ + float waveform_freq; /* Waveform frequency */ + uint16_t cmp[SAMPLES_NUM]; /* PWM TIM compare table */ + uint16_t per; /* PWM TIM period */ + uint16_t samples; /* Modulation waveform samples num */ + uint16_t phase_shift[PHASES_NUM]; /* Phase offset */ + volatile uint16_t sample_now[PHASES_NUM]; /* Current sumple number for phase */ + uint8_t phases; /* Number of PWM phases */ +}; + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +static struct spwm_s g_spwm = +{ + .waveform_freq = ((float)CONFIG_NUCLEOF334R8_SPWM_FREQ), + .phases = PHASES_NUM, + .samples = SAMPLES_NUM, +}; + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +static float waveform_func(float x); +static int waveform_init(FAR struct spwm_s *spwm, float (*f)(float)); +static int spwm_start(FAR struct spwm_s *spwm); +static int spwm_start(FAR struct spwm_s *spwm); +static int spwm_stop(FAR struct spwm_s *spwm); +#ifdef CONFIG_NUCLEOF334R8_SPWM_USE_HRTIM1 +static int master_configure(FAR struct spwm_s *spwm); +static int slaves_configure(FAR struct spwm_s *spwm); +static void hrtim_master_handler(void); +static int spwm_hrtim_setup(FAR struct spwm_s *spwm); +static int spwm_hrtim_start(FAR struct spwm_s *spwm); +static int spwm_hrtim_stop(FAR struct spwm_s *spwm); +#endif /* CONFIG_NUCLEOF334R8_SPWM_USE_HRTIM1 */ +#ifdef CONFIG_NUCLEOF334R8_SPWM_USE_TIM1 +static int spwm_tim1_setup(FAR struct spwm_s *spwm); +static int spwm_tim6_setup(FAR struct spwm_s *spwm); +static int spwm_tim1_start(FAR struct spwm_s *spwm); +static int spwm_tim6_start(FAR struct spwm_s *spwm); +static int spwm_tim1_stop(FAR struct spwm_s *spwm); +static int spwm_tim6_stop(FAR struct spwm_s *spwm); +#endif /* CONFIG_NUCLEOF334R8_SPWM_USE_TIM1 */ +static int spwm_setup(FAR struct spwm_s *spwm); + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: waveform_func + * + * Description: + * Modulation function. This function must return values from <0.0, 1.0>! + * + ****************************************************************************/ + +static float waveform_func(float x) +{ + DEBUGASSERT(x >= 0 && x <= 2*M_PI); + + /* Sine modulation */ + + return (sinf(x)+1.0f)/2.0f; +} + +/**************************************************************************** + * Name: waveform_init + * + * Description: + * Initialize modulation waveform + * + ****************************************************************************/ + +static int waveform_init(FAR struct spwm_s *spwm, float (*f)(float)) +{ + uint16_t i = 0; + int ret = 0; + + printf("Initialize waveform\n"); + + /* Get phase step to acheive one sine waveform period */ + + spwm->phase_step = (float)(2*M_PI/spwm->samples); + + /* Initialize sine and PWM compare tables */ + + for (i = 0; i< spwm->samples; i += 1) + { + /* We need sine in range from 0 to 1.0 */ + + spwm->waveform[i] = f(spwm->phase_step*i); + + DEBUGASSERT(spwm->waveform[i] >= 0.0 && spwm->waveform[i] <= 2*M_PI); + + spwm->cmp[i] = (uint16_t)(spwm->waveform[i] * spwm->per); + } + + /* Configure phase shift + * TODO: this should be configurable + */ + + for (i = 0; i < spwm->phases; i += 1) + { + spwm->phase_shift[i] = (spwm->samples / CONFIG_NUCLEOF334R8_SPWM_PHASE_NUM) * i; + } + + /* Initialize offstes */ + + for (i = 0; i < spwm->phases; i += 1) + { + spwm->sample_now[i] = spwm->phase_shift[i]; + } + + printf("\tsamples = %d\n", spwm->samples); + printf("\tper = %d\n", spwm->per); + printf("\tphase = %d\n", spwm->phases); + for (i = 0; i < spwm->phases; i += 1) + { + printf("\tsnow%d = %d\n", i, spwm->sample_now[i]); + } + + return ret; +} + +/**************************************************************************** + * Name: spwm_start + * + * Description: + * Start SPWM + * + ****************************************************************************/ + +static int spwm_start(FAR struct spwm_s *spwm) +{ +#if defined(CONFIG_NUCLEOF334R8_SPWM_USE_HRTIM1) + /* Start HRTIM */ + + spwm_hrtim_start(spwm); + +#elif defined(CONFIG_NUCLEOF334R8_SPWM_USE_TIM1) + /* Start TIM1 */ + + spwm_tim1_start(spwm); + + /* Start TIM6 */ + + spwm_tim6_start(spwm); +#else +# error +#endif + + return OK; +} + +/**************************************************************************** + * Name: spwm_stop + * + * Description: + * Stop SPWM + * + ****************************************************************************/ + +static int spwm_stop(FAR struct spwm_s *spwm) +{ +#if defined(CONFIG_NUCLEOF334R8_SPWM_USE_HRTIM1) + /* Stop HRTIM */ + + spwm_hrtim_stop(spwm); + +#elif defined(CONFIG_NUCLEOF334R8_SPWM_USE_TIM1) + /* Stop TIM1 */ + + spwm_tim1_stop(spwm); + + /* Stop TIM6 */ + + spwm_tim6_stop(spwm); +#else +# error +#endif + + return OK; +} + +#ifdef CONFIG_NUCLEOF334R8_SPWM_USE_HRTIM1 + +/**************************************************************************** + * Name: master_configure + ****************************************************************************/ + +static int master_configure(FAR struct spwm_s *spwm) +{ + FAR struct hrtim_dev_s *hrtim = spwm->pwm; + uint64_t per = 0; + uint64_t fclk = 0; + uint64_t freq = 0; + uint16_t cmp = 0; + int ret = 0; + + /* Frequency with which we will change samples. + * + * master_freq = samples_num * waveform_freq + */ + + freq = spwm->samples * spwm->waveform_freq; + + /* Configure Master Timer period */ + + fclk = HRTIM_FCLK_GET(hrtim, HRTIM_TIMER_MASTER); + per = fclk/freq; + if (per > HRTIM_PER_MAX) + { + printf("ERROR: can not achieve master freq=%llu if fclk=%llu\n", + freq, fclk); + ret = -EINVAL; + goto errout; + } + + HRTIM_PER_SET(hrtim, HRTIM_TIMER_MASTER, (uint16_t)per); + + /* Configure Master Timer interrupt trigger (compare 1) */ + + cmp = 1; + HRTIM_CMP_SET(hrtim, HRTIM_TIMER_MASTER, HRTIM_CMP1, cmp); + +errout: + return ret; +} + +/**************************************************************************** + * Name: slaves_configure + ****************************************************************************/ + +static int slaves_configure(FAR struct spwm_s *spwm) +{ + FAR struct hrtim_dev_s *hrtim = spwm->pwm; + uint64_t fclk = 0; + uint64_t per = 0; + uint8_t index = 0; + uint8_t i = 0; + int ret = 0; + + /* Get timer period value for given frequency */ + + fclk = HRTIM_FCLK_GET(hrtim, HRTIM_TIMER_TIMA); + per = fclk/CONFIG_NUCLEOF334R8_SPWM_PWM_FREQ; + if (per > HRTIM_PER_MAX) + { + printf("ERROR: can not achieve pwm freq=%llu if fclk=%llu\n", + CONFIG_NUCLEOF334R8_SPWM_PWM_FREQ, fclk); + ret = -EINVAL; + goto errout; + } + + spwm->per = (uint16_t)per; + + for(i = 0; i < spwm->phases; i+=1) + { + /* Get slave timer index */ + + index = (1<<(i+1)); + + /* Prescalers for slave timers must be the same !!! */ + + if (fclk != HRTIM_FCLK_GET(hrtim, index)) + { + printf("ERROR: prescaler for HRTIM TIMER %d doesn't match!\n", index); + ret = -EINVAL; + goto errout; + } + + /* Set timer period value */ + + HRTIM_PER_SET(hrtim, index, (uint16_t)per); + } + +errout: + return ret; +} + +/**************************************************************************** + * Name: hrtim_master_handler + ****************************************************************************/ + +static void hrtim_master_handler(void) +{ + FAR struct spwm_s *spwm = &g_spwm; + FAR struct hrtim_dev_s *hrtim = spwm->pwm; + uint32_t pending = 0; + uint8_t i = 0; + + pending = HRTIM_IRQ_GET(hrtim, HRTIM_TIMER_MASTER); + + if (pending & HRTIM_IRQ_MCMP1) + { + /* Update CMP for slaves */ + + for(i = 0; i < spwm->phases; i += 1) + { + /* Set new CMP for timers */ + + HRTIM_CMP_SET(hrtim, (1<<(i+1)), HRTIM_CMP1, + spwm->cmp[spwm->sample_now[i]]); + + + /* Increase sample pointer */ + + spwm->sample_now[i] += 1; + + if (spwm->sample_now[i] > spwm->samples) + { + spwm->sample_now[i] = 0; + } + } + + /* Software update all slaves */ + + for(i = 0; i < spwm->phases; i += 1) + { + HRTIM_SOFT_UPDATE(hrtim, 1<<(i+1)); + } + } + + HRTIM_IRQ_ACK(hrtim, HRTIM_TIMER_MASTER, pending); +} + +/**************************************************************************** + * Name: spwm_hrtim_setup + ****************************************************************************/ + +static int spwm_hrtim_setup(FAR struct spwm_s *spwm) +{ + FAR struct hrtim_dev_s *pwm = NULL; + int ret = OK; + + /* Configure HRTIM */ + + pwm = stm32_hrtiminitialize(); + if (pwm == NULL) + { + printf("ERROR: Failed to get HRTIM1 interface\n"); + ret = -1; + goto errout; + } + + spwm->pwm = pwm; + + /* Attach HRTIM Master TImer IRQ */ + + ret = up_ramvec_attach(STM32_IRQ_HRTIMTM, hrtim_master_handler); + if (ret < 0) + { + fprintf(stderr, "spwm_main: ERROR: up_ramvec_attach failed: %d\n", ret); + ret = -1; + goto errout; + } + + /* Set the priority of the HRTIM Master interrupt vector */ + + ret = up_prioritize_irq(STM32_IRQ_HRTIMTM, NVIC_SYSH_HIGH_PRIORITY); + if (ret < 0) + { + fprintf(stderr, "spwm_main: ERROR: up_prioritize_irq failed: %d\n", ret); + ret = -1; + goto errout; + } + + /* Disable HRTIM Master interrupt */ + + up_disable_irq(STM32_IRQ_HRTIMTM); + + /* Configure Master Timer */ + + ret = master_configure(spwm); + if (ret < 0) + { + printf("ERROR: failed initialize master timer %d!\n", ret); + goto errout; + } + + /* Configure Slave Timers */ + + ret = slaves_configure(spwm); + if (ret < 0) + { + printf("ERROR: failed initialize timers %d!\n", ret); + goto errout; + } + + spwm_hrtim_stop(spwm); + +errout: + return ret; +} + +/**************************************************************************** + * Name: spwm_hrtim_start + ****************************************************************************/ + +static int spwm_hrtim_start(FAR struct spwm_s *spwm) +{ + FAR struct hrtim_dev_s *hrtim = spwm->pwm; + uint8_t timers = 0; + uint16_t outputs = 0; + int i = 0; + + /* Enable HRTIM Master interrupt */ + + up_enable_irq(STM32_IRQ_HRTIMTM); + + /* Get HRTIM timers (master+slaves) */ + + for(i = 0; i < spwm->phases+1; i += 1) + { + timers |= (1<phases; i += 1) + { + outputs |= (1<<(i*2)); + } + + /* Enable HRTIM outpus */ + + HRTIM_OUTPUTS_ENABLE(hrtim, outputs, true); + + /* Enable HRTIM timers */ + + HRTIM_TIM_ENABLE(hrtim, timers, true); + + return OK; +} + +/**************************************************************************** + * Name: spwm_hrtim_stop + ****************************************************************************/ + +static int spwm_hrtim_stop(FAR struct spwm_s *spwm) +{ + FAR struct hrtim_dev_s *hrtim = spwm->pwm; + uint8_t timers = 0; + uint16_t outputs = 0; + int i = 0; + + /* Disable HRTIM Master interrupt */ + + up_disable_irq(STM32_IRQ_HRTIMTM); + + /* Get HRTIM timers (master+slaves) */ + + for(i = 0; i < spwm->phases+1; i += 1) + { + timers |= (1<phases; i += 1) + { + outputs |= (1<<(i*2)); + } + + /* Disable HRTIM outpus */ + + HRTIM_OUTPUTS_ENABLE(hrtim, outputs, false); + + /* Disable HRTIM timers */ + + HRTIM_TIM_ENABLE(hrtim, timers, false); + + return OK; +} + +#endif /* CONFIG_NUCLEOF334R8_SPWM_USE_HRTIM1 */ + +#ifdef CONFIG_NUCLEOF334R8_SPWM_USE_TIM1 + +/**************************************************************************** + * Name: tim6_handler + ****************************************************************************/ + +static void tim6_handler(void) +{ + FAR struct spwm_s *spwm = &g_spwm; + FAR struct stm32_pwm_dev_s *pwm = spwm->pwm; + FAR struct stm32_tim_dev_s *tim = spwm->tim; + uint8_t i = 0; + + for(i = 0; i < spwm->phases; i += 1) + { + /* Set new CMP for timers */ + + PWM_CCR_UPDATE(pwm, i+1, spwm->cmp[spwm->sample_now[i]]); + + /* Increase sample pointer */ + + spwm->sample_now[i] += 1; + + if (spwm->sample_now[i] > spwm->samples) + { + spwm->sample_now[i] = 0; + } + } + + /* TODO: Software update */ + + STM32_TIM_ACKINT(tim, ATIM_SR_UIF); +} + +/**************************************************************************** + * Name: spwm_tim6_setup + ****************************************************************************/ + +static int spwm_tim6_setup(FAR struct spwm_s *spwm) +{ + FAR struct stm32_tim_dev_s *tim = NULL; + uint64_t freq = 0; + uint32_t per = 0; + int ret = OK; + + /* Get TIM6 interface */ + + tim = stm32_tim_init(6); + if (tim == NULL) + { + printf("ERROR: Failed to get TIM6 interface\n"); + ret = -1; + goto errout; + } + + spwm->tim = tim; + + /* Frequency with which we will change samples. + * + * tim6_freq = samples_num * waveform_freq + */ + + freq = spwm->samples * spwm->waveform_freq; + per = BOARD_TIM6_FREQUENCY/freq; + if (per > 0xFFFF) + { + printf("ERROR: can not achieve TIM6 frequency\n"); + ret = -1; + goto errout; + } + + /* TODO: TIM_SETFREQ */ + + STM32_TIM_SETCLOCK(tim, BOARD_TIM6_FREQUENCY); + STM32_TIM_SETPERIOD(tim, per); + + /* Attach TIM6 ram vector */ + + ret = up_ramvec_attach(STM32_IRQ_TIM6, tim6_handler); + if (ret < 0) + { + printf("ERROR: up_ramvec_attach failed: %d\n", ret); + ret = -1; + goto errout; + } + + /* Set the priority of the TIM6 interrupt vector */ + + ret = up_prioritize_irq(STM32_IRQ_TIM6, NVIC_SYSH_HIGH_PRIORITY); + if (ret < 0) + { + printf("ERROR: up_prioritize_irq failed: %d\n", ret); + ret = -1; + goto errout; + } + + spwm_tim6_stop(spwm); + +errout: + return ret; +} + +/**************************************************************************** + * Name: spwm_tim6_start + ****************************************************************************/ + +static int spwm_tim6_start(FAR struct spwm_s *spwm) +{ + FAR struct stm32_tim_dev_s *tim = spwm->tim; + + /* Enable the timer interrupt at the NVIC and at TIM6 */ + + up_enable_irq(STM32_IRQ_TIM6); + STM32_TIM_ENABLEINT(tim, BTIM_DIER_UIE); + + return OK; +} + +/**************************************************************************** + * Name: spwm_tim6_stop + ****************************************************************************/ + +static int spwm_tim6_stop(FAR struct spwm_s *spwm) +{ + FAR struct stm32_tim_dev_s *tim = spwm->tim; + + /* Disable the timer interrupt at the NVIC and at TIM6 */ + + up_disable_irq(STM32_IRQ_TIM6); + STM32_TIM_DISABLEINT(tim, BTIM_DIER_UIE); + + return OK; +} + +/**************************************************************************** + * Name: spwm_tim1_setup + ****************************************************************************/ + +static int spwm_tim1_setup(FAR struct spwm_s *spwm) +{ + FAR struct stm32_pwm_dev_s *pwm = NULL; + int ret = OK; + + /* Get TIM1 PWM interface */ + + pwm = (FAR struct stm32_pwm_dev_s *)stm32_pwminitialize(1); + if (pwm == NULL) + { + printf("ERROR: Failed to get TIM1 PWM interface\n"); + ret = -1; + goto errout; + } + + spwm->pwm = pwm; + + /* Initial PWM1 setup */ + + ret = PWM_SETUP(pwm); + if (ret < 0) + { + printf("ERROR: Failed to get setup TIM1 PWM\n"); + ret = -1; + goto errout; + } + + /* Configure TIM1 PWM frequency */ + + ret = PWM_FREQ_UPDATE(pwm, CONFIG_NUCLEOF334R8_SPWM_PWM_FREQ); + if (ret < 0) + { + printf("ERROR: Failed to set TIM1 PWM frequency\n"); + ret = -1; + goto errout; + } + + /* Get TIM1 period (ARR) */ + + spwm->per = PWM_ARR_GET(pwm); + + spwm_tim1_stop(spwm); + +errout: + return ret; +} + +/**************************************************************************** + * Name: spwm_tim1_start + ****************************************************************************/ + +static int spwm_tim1_start(FAR struct spwm_s *spwm) +{ + FAR struct stm32_pwm_dev_s *pwm = spwm->pwm; + uint16_t outputs = 0; + int i = 0; + + /* Get outputs */ + + for(i = 0; i < spwm->phases; i+=1) + { + outputs |= (1<<(i*2)); + } + + /* Enable PWM outputs */ + + PWM_OUTPUTS_ENABLE(pwm, outputs, true); + + /* Enable TIM1 */ + + PWM_TIM_ENABLE(pwm, true); + + return OK; +} + +/**************************************************************************** + * Name: spwm_tim1_stop + ****************************************************************************/ + +static int spwm_tim1_stop(FAR struct spwm_s *spwm) +{ + FAR struct stm32_pwm_dev_s *pwm = spwm->pwm; + uint16_t outputs = 0; + int i = 0; + + /* Get outputs */ + + for(i = 0; i < spwm->phases; i+=1) + { + outputs |= (1<<(i*2)); + } + + /* Disable PWM outputs */ + + PWM_OUTPUTS_ENABLE(pwm, outputs, false); + + /* Disable TIM1 */ + + PWM_TIM_ENABLE(pwm, false); + + return OK; +} + +#endif /* CONFIG_NUCLEOF334R8_SPWM_USE_TIM1 */ + +/**************************************************************************** + * Name: spwm_setup + ****************************************************************************/ + +static int spwm_setup(FAR struct spwm_s *spwm) +{ + int ret = OK; + +#if defined(CONFIG_NUCLEOF334R8_SPWM_USE_HRTIM1) + /* HRTIM setup */ + + printf("Setup HRTIM\n"); + ret = spwm_hrtim_setup(spwm); + if (ret < 0) + { + goto errout; + } +#elif defined(CONFIG_NUCLEOF334R8_SPWM_USE_TIM1) + /* TIM1 setup - PWM */ + + printf("Setup TIM1 and TIM6\n"); + ret = spwm_tim1_setup(spwm); + if (ret < 0) + { + goto errout; + } + + /* TIM6 setup - IRQ */ + + ret = spwm_tim6_setup(spwm); + if (ret < 0) + { + goto errout; + } +#else +# error +#endif + +errout: + return ret; +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: spwm_main + * + * Description: + * Entrypoint for SPWM example. + * + ****************************************************************************/ + +int spwm_main(int argc, char *argv[]) +{ + FAR struct spwm_s *spwm = NULL; + int ret = OK; + int i = 0; + + spwm = &g_spwm; + + printf("\nspwm_main: Started\n"); + + /* Setup SPWM example */ + + ret = spwm_setup(spwm); + if (ret < 0) + { + printf("ERROR: failed to setup SPWM %d!\n", ret); + goto errout; + } + + /* Initialize modulation waveform */ + + ret = waveform_init(spwm, waveform_func); + if (ret < 0) + { + printf("ERROR: failed initialize modulation wavefrom %d!\n", ret); + goto errout; + } + + /* Start SPWM */ + + ret = spwm_start(spwm); + if (ret < 0) + { + printf("ERROR: failed start SPWM %d!\n", ret); + goto errout; + } + + /* Main loop */ + + while (1) + { + /* Print counter */ + + printf("%d\n", i); + + /* Increase counter */ + + i += 1; + + /* Sleep */ + + sleep(1); + } + +errout: + spwm_stop(spwm); + + return 0; +} + +#endif /* CONFIG_NUCLEOF334R8_SPWM */ diff --git a/configs/stm32f429i-disco/highpri/defconfig b/configs/stm32f429i-disco/highpri/defconfig index 77dbf48159..8aa4c9f149 100644 --- a/configs/stm32f429i-disco/highpri/defconfig +++ b/configs/stm32f429i-disco/highpri/defconfig @@ -1,6 +1,4 @@ # CONFIG_STM32_FLASH_PREFETCH is not set -CONFIG_ADC=y -CONFIG_ANALOG=y CONFIG_ARCH="arm" CONFIG_ARCH_BOARD="stm32f429i-disco" CONFIG_ARCH_BOARD_STM32F429I_DISCO=y diff --git a/include/nuttx/drivers/pwm.h b/include/nuttx/drivers/pwm.h index 2d0a5d2c7d..c3316cd315 100644 --- a/include/nuttx/drivers/pwm.h +++ b/include/nuttx/drivers/pwm.h @@ -61,8 +61,6 @@ #include -#ifdef CONFIG_PWM - /**************************************************************************** * Pre-processor Definitions ****************************************************************************/ @@ -326,5 +324,4 @@ void pwm_expired(FAR void *handle); } #endif -#endif /* CONFIG_PWM */ #endif /* __INCLUDE_NUTTX_DRIVERS_PWM_H */