mirror of
https://github.com/apache/nuttx.git
synced 2025-01-13 09:49:21 +08:00
Merged in raiden00/nuttx_pe (pull request #767)
Improvements in STM32 ADC, minor changes in STM32 PWM, DMA, HRTIM and add some highpri ADC examples arch/arch/src/stm32/stm32_adc: fix RCC reset logic arch/arch/src/stm32/stm32_adc: move sample time change functions to low-level ADC ops arch/arch/src/stm32/stm32_adc: configurable ADC DMA mode (one shot mode, circular mode) arch/arch/src/stm32/stm32_pwm: remove llops_get interface. We can use structure casting to get pwm low-level ops arch/arch/src/stm32/stm32_pwm: add timer enable/disable and frequency update to low-level ops arch/src/arm/stm32: remove redundant stm32f33xxx_dma.c arch/arm/src/stm32/stm32f40xxx_dma.c: add interfaces to interact with highp priority DMA interupts arch/src/arm/stm32/stm32_hrtim: do not enable timers on startup if option from Kconfig selected and add interface to enable/disable timers arch/src/arm/stm32/stm32_hrtim: fix some warnings configs/nucleo-f334r8/highpri: update configuration due to changes in stm32_adc configs/stm32f334-disco/buckboost: update configuration due to changes in stm32_adc configs/nucleo-f334r8/highpri: add support for ADC injected sequence, add triggering from TIM1 configs/nucleo-f302r8/highpri: add high priority ADC interrupts example configs/stm32f429i-disco/highpri: add high priority ADC interrupts example Approved-by: GregoryN <gnutt@nuttx.org>
This commit is contained in:
parent
75f152a0b6
commit
fc46135ebc
41 changed files with 3566 additions and 3798 deletions
|
@ -1590,6 +1590,7 @@ config STM32_STM32F207
|
|||
config STM32_STM32F30XX
|
||||
bool
|
||||
default n
|
||||
select STM32_HAVE_ADC1_DMA
|
||||
select STM32_HAVE_CAN1
|
||||
select STM32_HAVE_DAC1
|
||||
select STM32_HAVE_TIM1
|
||||
|
@ -1604,6 +1605,8 @@ config STM32_STM32F30XX
|
|||
config STM32_STM32F302
|
||||
bool
|
||||
default n
|
||||
select STM32_HAVE_ADC2
|
||||
select STM32_HAVE_ADC2_DMA
|
||||
select STM32_HAVE_I2C2
|
||||
select STM32_HAVE_SPI2
|
||||
select STM32_HAVE_SPI3
|
||||
|
@ -1614,6 +1617,7 @@ config STM32_STM32F303
|
|||
bool
|
||||
default n
|
||||
select STM32_HAVE_ADC2
|
||||
select STM32_HAVE_ADC2_DMA
|
||||
select STM32_HAVE_CCM
|
||||
select STM32_HAVE_DAC2
|
||||
select STM32_HAVE_TIM7
|
||||
|
@ -6949,6 +6953,12 @@ config STM32_HRTIM_DISABLE_CHARDRV
|
|||
In most cases we do not need HRTIM Character Driver, so we can disable it
|
||||
and save some memory.
|
||||
|
||||
config STM32_HRTIM_NO_ENABLE_TIMERS
|
||||
bool "Do not enable HRTIM timers at startup"
|
||||
default n
|
||||
---help---
|
||||
Do not enable HRTIM timers at startup
|
||||
|
||||
menuconfig STM32_HRTIM_ADC
|
||||
bool "HRTIM ADC Triggering"
|
||||
default n
|
||||
|
@ -7558,15 +7568,20 @@ config STM32_ADC_NO_STARTUP_CONV
|
|||
|
||||
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_ADC_LL_OPS
|
||||
bool "ADC low-level operations"
|
||||
default n
|
||||
---help---
|
||||
Enable low-level ADC ops.
|
||||
|
||||
config STM32_ADC_CHANGE_SAMPLETIME
|
||||
bool "ADC sample time configuration"
|
||||
default n
|
||||
depends on STM32_ADC_LL_OPS
|
||||
---help---
|
||||
Enable ADC sample time configuration (SMPRx registers).
|
||||
|
||||
|
@ -7579,6 +7594,14 @@ config STM32_ADC1_DMA
|
|||
DMA transfer, which is necessary if multiple channels are read
|
||||
or if very high trigger frequencies are used.
|
||||
|
||||
config STM32_ADC1_DMA_CFG
|
||||
int "ADC1 DMA configuration"
|
||||
depends on STM32_ADC1_DMA
|
||||
range 0 1
|
||||
default 0
|
||||
---help---
|
||||
0 - ADC1 DMA in One Shot Mode, 1 - ADC1 DMA in Circular Mode
|
||||
|
||||
config STM32_ADC2_DMA
|
||||
bool "ADC2 DMA"
|
||||
depends on STM32_ADC2 && STM32_HAVE_ADC2_DMA
|
||||
|
@ -7588,6 +7611,14 @@ config STM32_ADC2_DMA
|
|||
DMA transfer, which is necessary if multiple channels are read
|
||||
or if very high trigger frequencies are used.
|
||||
|
||||
config STM32_ADC2_DMA_CFG
|
||||
int "ADC2 DMA configuration"
|
||||
depends on STM32_ADC2_DMA
|
||||
range 0 1
|
||||
default 0
|
||||
---help---
|
||||
0 - ADC2 DMA in One Shot Mode, 1 - ADC2 DMA in Circular Mode
|
||||
|
||||
config STM32_ADC3_DMA
|
||||
bool "ADC3 DMA"
|
||||
depends on STM32_ADC3 && STM32_HAVE_ADC3_DMA
|
||||
|
@ -7597,6 +7628,14 @@ config STM32_ADC3_DMA
|
|||
DMA transfer, which is necessary if multiple channels are read
|
||||
or if very high trigger frequencies are used.
|
||||
|
||||
config STM32_ADC3_DMA_CFG
|
||||
int "ADC3 DMA configuration"
|
||||
depends on STM32_ADC3_DMA
|
||||
range 0 1
|
||||
default 0
|
||||
---help---
|
||||
0 - ADC3 DMA in One Shot Mode, 1 - ADC3 DMA in Circular Mode
|
||||
|
||||
config STM32_ADC4_DMA
|
||||
bool "ADC4 DMA"
|
||||
depends on STM32_ADC4 && STM32_HAVE_ADC4_DMA
|
||||
|
@ -7606,21 +7645,45 @@ config STM32_ADC4_DMA
|
|||
DMA transfer, which is necessary if multiple channels are read
|
||||
or if very high trigger frequencies are used.
|
||||
|
||||
config STM32_ADC1_INJECTED
|
||||
bool "ADC1 INJECTED"
|
||||
depends on STM32_ADC1 && STM32_STM32F33XX
|
||||
default n
|
||||
config STM32_ADC4_DMA_CFG
|
||||
int "ADC4 DMA configuration"
|
||||
depends on STM32_ADC4_DMA
|
||||
range 0 1
|
||||
default 0
|
||||
---help---
|
||||
0 - ADC4 DMA in One Shot Mode, 1 - ADC4 DMA in Circular Mode
|
||||
|
||||
config STM32_ADC1_INJECTED_CHAN
|
||||
int "ADC1 injected channels"
|
||||
depends on STM32_ADC1
|
||||
range 0 4
|
||||
default 0
|
||||
---help---
|
||||
Support for ADC1 injected channels.
|
||||
Only for STM32_STM32F33XX at this moment.
|
||||
|
||||
config STM32_ADC2_INJECTED
|
||||
bool "ADC2 INJECTED"
|
||||
depends on STM32_ADC2 && STM32_STM32F33XX
|
||||
default n
|
||||
config STM32_ADC2_INJECTED_CHAN
|
||||
int "ADC2 injected channels"
|
||||
depends on STM32_ADC2
|
||||
range 0 4
|
||||
default 0
|
||||
---help---
|
||||
Support for ADC2 injected channels.
|
||||
Only for STM32_STM32F33XX at this moment.
|
||||
|
||||
config STM32_ADC3_INJECTED_CHAN
|
||||
int "ADC3 injected channels"
|
||||
depends on STM32_ADC3
|
||||
range 0 4
|
||||
default 0
|
||||
---help---
|
||||
Support for ADC3 injected channels.
|
||||
|
||||
config STM32_ADC4_INJECTED_CHAN
|
||||
int "ADC4 injected channels"
|
||||
depends on STM32_ADC4
|
||||
range 0 4
|
||||
default 0
|
||||
---help---
|
||||
Support for ADC4 injected channels.
|
||||
|
||||
endmenu
|
||||
|
||||
|
|
|
@ -192,12 +192,8 @@ endif
|
|||
endif
|
||||
|
||||
ifeq ($(CONFIG_STM32_ADC),y)
|
||||
ifeq ($(CONFIG_STM32_STM32F33XX),y)
|
||||
CHIP_CSRCS += stm32f33xxx_adc.c
|
||||
else
|
||||
CHIP_CSRCS += stm32_adc.c
|
||||
endif
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_STM32_SDADC),y)
|
||||
CHIP_CSRCS += stm32_sdadc.c
|
||||
|
|
|
@ -520,8 +520,10 @@
|
|||
#define ADC_JSQR_JSQ3_MASK (0x1f << ADC_JSQR_JSQ3_SHIFT)
|
||||
#define ADC_JSQR_JSQ4_SHIFT (15) /* Bits 19-15: 4th conversion in injected sequence */
|
||||
#define ADC_JSQR_JSQ4_MASK (0x1f << ADC_JSQR_JSQ4_SHIFT)
|
||||
#define ADC_JSQR_JSQ_SHIFT (5) /* Shift between JSQx bits */
|
||||
#define ADC_JSQR_JL_SHIFT (20) /* Bits 21-20: Injected Sequence length */
|
||||
#define ADC_JSQR_JL_MASK (3 << ADC_JSQR_JL_SHIFT)
|
||||
# define ADC_JSQR_JL(n) (((n)-1) << ADC_JSQR_JL_SHIFT) /* n=1..4 */
|
||||
|
||||
/* ADC injected data register 1-4 */
|
||||
|
||||
|
|
|
@ -509,8 +509,10 @@
|
|||
#define ADC_JSQR_JSQ3_MASK (0x1f << ADC_JSQR_JSQ3_SHIFT)
|
||||
#define ADC_JSQR_JSQ4_SHIFT (15) /* Bits 19-15: 4th conversion in injected sequence */
|
||||
#define ADC_JSQR_JSQ4_MASK (0x1f << ADC_JSQR_JSQ4_SHIFT)
|
||||
#define ADC_JSQR_JSQ_SHIFT (5) /* Shift between JSQx bits */
|
||||
#define ADC_JSQR_JL_SHIFT (20) /* Bits 21-20: Injected Sequence length */
|
||||
#define ADC_JSQR_JL_MASK (3 << ADC_JSQR_JL_SHIFT)
|
||||
# define ADC_JSQR_JL(n) (((n)-1) << ADC_JSQR_JL_SHIFT) /* n=1..4 */
|
||||
|
||||
/* ADC injected data register 1-4 */
|
||||
|
||||
|
|
|
@ -615,6 +615,7 @@
|
|||
#define ADC_JSQR_JSQ4_SHIFT (26) /* Bits 26-30: 4th conversion in injected sequence */
|
||||
#define ADC_JSQR_JSQ4_MASK (0x1f << ADC_JSQR_JSQ4_SHIFT)
|
||||
# define ADC_JSQR_JSQ4(ch) ((ch) << ADC_JSQR_JSQ4_SHIFT) /* Channel number 1..18 */
|
||||
#define ADC_JSQR_JSQ_SHIFT (6) /* Shift between JSQx bits */
|
||||
|
||||
/* ADC offset register 1 and 2 */
|
||||
|
||||
|
|
|
@ -183,6 +183,7 @@
|
|||
# define HRTIM_MCR_SYNCSRC_MCMP1 (1 << HRTIM_MCR_SYNCSRC_SHIFT) /* 01: Master timer Compare 1 Event */
|
||||
# define HRTIM_MCR_SYNCSRC_TASTRT (2 << HRTIM_MCR_SYNCSRC_SHIFT) /* 10: Timer A start/reset */
|
||||
# define HRTIM_MCR_SYNCSRC_TACMP1 (3 << HRTIM_MCR_SYNCSRC_SHIFT) /* 11: Timer A Compare 1 Event */
|
||||
#define HRTIM_MCR_TCEN_SHIFT (16)
|
||||
#define HRTIM_MCR_MCEN (1 << 16) /* Bit 16: Master timer counter enable */
|
||||
#define HRTIM_MCR_TACEN (1 << 17) /* Bit 17: Timer A counter enable */
|
||||
#define HRTIM_MCR_TBCEN (1 << 18) /* Bit 18: Timer B counter enable */
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -303,6 +303,15 @@
|
|||
# undef ADC4_HAVE_DMA
|
||||
#endif
|
||||
|
||||
/* Injected channels support */
|
||||
|
||||
#if (defined(CONFIG_STM32_ADC1) && (CONFIG_STM32_ADC1_INJECTED_CHAN > 0)) || \
|
||||
(defined(CONFIG_STM32_ADC2) && (CONFIG_STM32_ADC2_INJECTED_CHAN > 0)) || \
|
||||
(defined(CONFIG_STM32_ADC3) && (CONFIG_STM32_ADC3_INJECTED_CHAN > 0)) || \
|
||||
(defined(CONFIG_STM32_ADC4) && (CONFIG_STM32_ADC4_INJECTED_CHAN > 0))
|
||||
# define ADC_HAVE_INJECTED
|
||||
#endif
|
||||
|
||||
/* Timer configuration: If a timer trigger is specified, then get
|
||||
* information about the timer.
|
||||
*
|
||||
|
@ -1294,6 +1303,8 @@
|
|||
# define ADC2_JEXTSEL_HRTTRG4 ADC12_JSQR_JEXTSEL_HRT1TRG4
|
||||
#endif
|
||||
|
||||
/* EXTSEL configuration *****************************************************/
|
||||
|
||||
#if defined(CONFIG_STM32_TIM1_ADC1)
|
||||
# if CONFIG_STM32_ADC1_TIMTRIG == 0
|
||||
# define ADC1_EXTSEL_VALUE ADC1_EXTSEL_T1CC1
|
||||
|
@ -1454,14 +1465,6 @@
|
|||
# define ADC1_EXTSEL_VALUE ADC1_EXTSEL_HRTTRG3
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_STM32_HRTIM_ADC1_TRG2)
|
||||
# define ADC1_JEXTSEL_VALUE ADC1_JEXTSEL_HRTTRG2
|
||||
#elif defined(CONFIG_STM32_HRTIM_ADC1_TRG4)
|
||||
# define ADC1_JEXTSEL_VALUE ADC1_JEXTSEL_HRTTRG4
|
||||
#else
|
||||
# define ADC1_JEXTSEL_VALUE 0
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_STM32_TIM1_ADC2)
|
||||
# if CONFIG_STM32_ADC2_TIMTRIG == 0
|
||||
# define ADC2_EXTSEL_VALUE ADC2_EXTSEL_T1CC1
|
||||
|
@ -1580,14 +1583,6 @@
|
|||
# define ADC2_EXTSEL_VALUE ADC1_EXTSEL_HRTTRG3
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_STM32_HRTIM_ADC2_TRG2)
|
||||
# define ADC2_JEXTSEL_VALUE ADC2_JEXTSEL_HRTTRG2
|
||||
#elif defined(CONFIG_STM32_HRTIM_ADC2_TRG4)
|
||||
# define ADC2_JEXTSEL_VALUE ADC2_JEXTSEL_HRTTRG4
|
||||
#else
|
||||
# define ADC2_JEXTSEL_VALUE 0
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_STM32_TIM1_ADC3)
|
||||
# if CONFIG_STM32_ADC3_TIMTRIG == 0
|
||||
# define ADC3_EXTSEL_VALUE ADC3_EXTSEL_T1CC1
|
||||
|
@ -1844,6 +1839,99 @@
|
|||
# endif
|
||||
#endif
|
||||
|
||||
/* JEXTSEL configuration ****************************************************/
|
||||
|
||||
/* TODO: ADC1 JEXTSEL trigger */
|
||||
|
||||
#if defined(CONFIG_STM32_HRTIM_ADC1_TRG2)
|
||||
# define ADC1_JEXTSEL_VALUE ADC1_JEXTSEL_HRTTRG2
|
||||
#elif defined(CONFIG_STM32_HRTIM_ADC1_TRG4)
|
||||
# define ADC1_JEXTSEL_VALUE ADC1_JEXTSEL_HRTTRG4
|
||||
#else
|
||||
# undef ADC1_JEXTSEL_VALUE
|
||||
#endif
|
||||
|
||||
/* TODO: ADC2 JEXTSEL trigger */
|
||||
|
||||
#if defined(CONFIG_STM32_HRTIM_ADC2_TRG2)
|
||||
# define ADC2_JEXTSEL_VALUE ADC2_JEXTSEL_HRTTRG2
|
||||
#elif defined(CONFIG_STM32_HRTIM_ADC2_TRG4)
|
||||
# define ADC2_JEXTSEL_VALUE ADC2_JEXTSEL_HRTTRG4
|
||||
#else
|
||||
# undef ADC2_JEXTSEL_VALUE
|
||||
#endif
|
||||
|
||||
/* TODO: ADC3 JEXTSEL trigger */
|
||||
|
||||
#undef ADC3_JEXTSEL_VALUE
|
||||
|
||||
/* TODO: ADC4 JEXTSEL trigger */
|
||||
|
||||
#undef ADC4_JEXTSEL_VALUE
|
||||
|
||||
/* ADC interrupts ***********************************************************/
|
||||
|
||||
#if defined(HAVE_IP_ADC_V1)
|
||||
# define ADC_ISR_EOC ADC_SR_EOC
|
||||
# define ADC_IER_EOC ADC_CR1_EOCIE
|
||||
# define ADC_ISR_AWD ADC_SR_AWD
|
||||
# define ADC_IER_AWD ADC_CR1_AWDIE
|
||||
# define ADC_ISR_JEOC ADC_SR_JEOC
|
||||
# define ADC_IER_JEOC ADC_CR1_JEOCIE
|
||||
# define ADC_ISR_JEOS 0 /* No JEOS */
|
||||
# define ADC_IER_JEOS 0 /* No JEOS */
|
||||
# ifdef HAVE_BASIC_ADC
|
||||
# define ADC_ISR_OVR 0
|
||||
# define ADC_IER_OVR 0
|
||||
# else
|
||||
# define ADC_ISR_OVR ADC_SR_OVR
|
||||
# define ADC_IER_OVR ADC_CR1_OVRIE
|
||||
# endif
|
||||
#elif defined(HAVE_IP_ADC_V2)
|
||||
# define ADC_ISR_EOC ADC_INT_EOC
|
||||
# define ADC_IER_EOC ADC_INT_EOC
|
||||
# define ADC_ISR_AWD ADC_INT_AWD1
|
||||
# define ADC_IER_AWD ADC_INT_AWD1
|
||||
# define ADC_ISR_JEOC ADC_INT_JEOC
|
||||
# define ADC_IER_JEOC ADC_INT_JEOC
|
||||
# define ADC_ISR_OVR ADC_INT_OVR
|
||||
# define ADC_IER_OVR ADC_INT_OVR
|
||||
# define ADC_ISR_JEOS ADC_INT_JEOS
|
||||
# define ADC_IER_JEOS ADC_INT_JEOS
|
||||
#endif
|
||||
|
||||
#define ADC_ISR_ALLINTS (ADC_ISR_EOC | ADC_ISR_AWD | ADC_ISR_JEOC | \
|
||||
ADC_ISR_JEOS | ADC_ISR_OVR)
|
||||
#define ADC_IER_ALLINTS (ADC_IER_EOC | ADC_IER_AWD | ADC_IER_JEOC | \
|
||||
ADC_IER_JEOS | ADC_IER_OVR)
|
||||
|
||||
/* Low-level ops helpers ****************************************************/
|
||||
|
||||
#define ADC_INT_ACK(adc, source) \
|
||||
(adc)->llops->int_ack(adc, source)
|
||||
#define ADC_INT_GET(adc) \
|
||||
(adc)->llops->int_get(adc)
|
||||
#define ADC_INT_ENABLE(adc, source) \
|
||||
(adc)->llops->int_en(adc, source)
|
||||
#define ADC_INT_DISABLE(adc, source) \
|
||||
(adc)->llops->int_dis(adc, source)
|
||||
#define ADC_REGDATA_GET(adc) \
|
||||
(adc)->llops->val_get(adc)
|
||||
#define ADC_REGBUF_REGISTER(adc, buffer, len) \
|
||||
(adc)->llops->regbuf_reg(adc, buffer, len)
|
||||
#define ADC_REG_STARTCONV(adc, state) \
|
||||
(adc)->llops->reg_startconv(adc, state)
|
||||
#define ADC_INJ_STARTCONV(adc, state) \
|
||||
(adc)->llops->inj_startconv(adc, state)
|
||||
#define ADC_INJDATA_GET(adc, chan) \
|
||||
(adc)->llops->inj_get(adc, chan)
|
||||
#define ADC_SAMPLETIME_SET(adc, time_samples) \
|
||||
(adc)->llops->stime_set(adc, time_samples)
|
||||
#define ADC_SAMPLETIME_WRITE(adc) \
|
||||
(adc)->llops->stime_write(adc)
|
||||
#define ADC_DUMP_REGS(adc) \
|
||||
(adc)->llops->dump_regs(adc)
|
||||
|
||||
/************************************************************************************
|
||||
* Public Types
|
||||
************************************************************************************/
|
||||
|
@ -1870,6 +1958,10 @@ enum adc_io_cmds_e
|
|||
IO_STOP_ADC,
|
||||
IO_START_ADC,
|
||||
IO_START_CONV,
|
||||
IO_TRIGGER_REG,
|
||||
#ifdef ADC_HAVE_INJECTED
|
||||
IO_TRIGGER_INJ,
|
||||
#endif
|
||||
#ifdef HAVE_ADC_POWERDOWN
|
||||
IO_ENABLE_DISABLE_PDI,
|
||||
IO_ENABLE_DISABLE_PDD,
|
||||
|
@ -1887,6 +1979,8 @@ enum stm32_adc_resoluton_e
|
|||
ADC_RESOLUTION_6BIT = 3 /* 6 bit */
|
||||
};
|
||||
|
||||
#ifdef CONFIG_STM32_ADC_LL_OPS
|
||||
|
||||
#ifdef CONFIG_STM32_ADC_CHANGE_SAMPLETIME
|
||||
|
||||
/* Channel and sample time pair */
|
||||
|
@ -1895,16 +1989,7 @@ typedef struct adc_channel_s
|
|||
{
|
||||
uint8_t channel:5;
|
||||
|
||||
/* Sampling time individually for each channel
|
||||
* 000: 4 cycles
|
||||
* 001: 9 cycles
|
||||
* 010: 16 cycles
|
||||
* 011: 24 cycles
|
||||
* 100: 48 cycles
|
||||
* 101: 96 cycles
|
||||
* 110: 192 cycles
|
||||
* 111: 384 cycles - selected for all channels
|
||||
*/
|
||||
/* Sampling time individually for each channel. It differs between families */
|
||||
|
||||
uint8_t sample_time:3;
|
||||
} adc_channel_t;
|
||||
|
@ -1915,19 +2000,13 @@ typedef struct adc_channel_s
|
|||
|
||||
struct adc_sample_time_s
|
||||
{
|
||||
adc_channel_t *channel; /* Array of channels */
|
||||
uint8_t channels_nbr:5; /* Number of channels in array */
|
||||
bool all_same:1; /* All channels will get the
|
||||
* same value of the sample time */
|
||||
uint8_t all_ch_sample_time:3; /* Sample time for all channels */
|
||||
adc_channel_t *channel; /* Array of channels */
|
||||
uint8_t channels_nbr:5; /* Number of channels in array */
|
||||
bool all_same:1; /* All channels will get the
|
||||
* same value of the sample time */
|
||||
uint8_t all_ch_sample_time:3; /* Sample time for all channels */
|
||||
};
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_STM32_STM32F33XX
|
||||
|
||||
/* At this moment only for STM32F33XX family */
|
||||
|
||||
#ifdef CONFIG_STM32_ADC_NOIRQ
|
||||
#endif /* CONFIG_STM32_ADC_CHANGE_SAMPLETIME */
|
||||
|
||||
/* This structure provides the publicly visable representation of the
|
||||
* "lower-half" ADC driver structure.
|
||||
|
@ -1937,14 +2016,15 @@ struct stm32_adc_dev_s
|
|||
{
|
||||
/* Publicly visible portion of the "lower-half" ADC driver structure */
|
||||
|
||||
FAR const struct stm32_adc_ops_s *ops;
|
||||
FAR const struct stm32_adc_ops_s *llops;
|
||||
|
||||
/* Require cast-compatibility with private "lower-half" ADC strucutre */
|
||||
};
|
||||
|
||||
/* Low-level operations for ADC */
|
||||
|
||||
struct stm32_adc_ops_s
|
||||
{
|
||||
|
||||
/* Acknowledge interrupts */
|
||||
|
||||
void (*int_ack)(FAR struct stm32_adc_dev_s *dev, uint32_t source);
|
||||
|
@ -1969,13 +2049,35 @@ struct stm32_adc_ops_s
|
|||
|
||||
int (*regbuf_reg)(FAR struct stm32_adc_dev_s *dev, uint16_t *buffer, uint8_t len);
|
||||
|
||||
/* Start/stop regular conversion */
|
||||
|
||||
void (*reg_startconv)(FAR struct stm32_adc_dev_s *dev, bool state);
|
||||
|
||||
#ifdef ADC_HAVE_INJECTED
|
||||
/* Get current ADC injected data register */
|
||||
|
||||
uint32_t (*inj_get)(FAR struct stm32_adc_dev_s *dev, uint8_t chan);
|
||||
|
||||
/* Start/stop injected conversion */
|
||||
|
||||
void (*inj_startconv)(FAR struct stm32_adc_dev_s *dev, bool state);
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_STM32_ADC_CHANGE_SAMPLETIME
|
||||
/* Set ADC sample time */
|
||||
|
||||
void (*stime_set)(FAR struct stm32_adc_dev_s *dev,
|
||||
FAR struct adc_sample_time_s *time_samples);
|
||||
|
||||
/* Write ADC sample time */
|
||||
|
||||
void (*stime_write)(FAR struct stm32_adc_dev_s *dev);
|
||||
#endif
|
||||
|
||||
void (*dump_regs)(FAR struct stm32_adc_dev_s *dev);
|
||||
};
|
||||
|
||||
#endif /* CONFIG_STM32_ADC_NOIRQ */
|
||||
#endif /* CONFIG_STM32_STM32F33XX */
|
||||
#endif /* CONFIG_STM32_ADC_LL_OPS */
|
||||
|
||||
/************************************************************************************
|
||||
* Public Function Prototypes
|
||||
|
@ -1994,12 +2096,12 @@ extern "C"
|
|||
* Name: stm32_adcinitialize
|
||||
*
|
||||
* Description:
|
||||
* Initialize the ADC.
|
||||
* Initialize the ADC. See stm32_adc.c for more details.
|
||||
*
|
||||
* Input Parameters:
|
||||
* intf - Could be {1,2,3} for ADC1, ADC2, or ADC3
|
||||
* chanlist - The list of channels
|
||||
* nchannels - Number of channels
|
||||
* intf - Could be {1,2,3,4} for ADC1, ADC2, ADC3 or ADC4
|
||||
* chanlist - The list of channels (regular + injected)
|
||||
* nchannels - Number of channels (regular + injected)
|
||||
*
|
||||
* Returned Value:
|
||||
* Valid can device structure reference on succcess; a NULL on failure
|
||||
|
@ -2008,11 +2110,14 @@ extern "C"
|
|||
|
||||
struct adc_dev_s;
|
||||
struct adc_dev_s *stm32_adcinitialize(int intf, FAR const uint8_t *chanlist,
|
||||
int nchannels);
|
||||
int channels);
|
||||
|
||||
#ifdef CONFIG_STM32_ADC_CHANGE_SAMPLETIME
|
||||
void stm32_adcchange_sample_time(FAR struct adc_dev_s *dev,
|
||||
FAR struct adc_sample_time_s *time_samples);
|
||||
/************************************************************************************
|
||||
* Name: stm32_adc_llops_get
|
||||
************************************************************************************/
|
||||
|
||||
#ifdef CONFIG_STM32_ADC_LL_OPS
|
||||
FAR const struct stm32_adc_ops_s *stm32_adc_llops_get(FAR struct adc_dev_s *dev);
|
||||
#endif
|
||||
|
||||
#undef EXTERN
|
||||
|
|
|
@ -53,13 +53,16 @@
|
|||
* The STM32 F4 DMA differs from the F1 DMA primarily in that it adds the
|
||||
* concept of "streams" that are used to associate DMA sources with DMA
|
||||
* channels.
|
||||
*
|
||||
* TODO: use STM32 DMA IP version instead of chip faimily:
|
||||
* - STM32 DMA IP core version 1 - F0, F1, F3, L1
|
||||
* - STM32 DMA IP core version 2 - F2, F4, F7, H7
|
||||
*/
|
||||
|
||||
#if defined(CONFIG_STM32_STM32L15XX) || defined(CONFIG_STM32_STM32F10XX) || \
|
||||
defined(CONFIG_STM32_STM32F30XX) || defined(CONFIG_STM32_STM32F37XX)
|
||||
defined(CONFIG_STM32_STM32F30XX) || defined(CONFIG_STM32_STM32F33XX) || \
|
||||
defined(CONFIG_STM32_STM32F37XX)
|
||||
# include "stm32f10xxx_dma.c"
|
||||
#elif defined(CONFIG_STM32_STM32F33XX)
|
||||
# include "stm32f33xxx_dma.c"
|
||||
#elif defined(CONFIG_STM32_STM32F20XX)
|
||||
# include "stm32f20xxx_dma.c"
|
||||
#elif defined(CONFIG_STM32_STM32F4XXX)
|
||||
|
|
|
@ -347,12 +347,11 @@ 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.
|
||||
*
|
||||
* TODO: For now the interface is different for STM32 DMAv1 and STM32 DMAv2.
|
||||
* It should be unified somehow.
|
||||
*/
|
||||
|
||||
#ifdef CONFIG_ARCH_HIPRI_INTERRUPT
|
||||
|
@ -365,7 +364,11 @@ void stm32_dmadump(DMA_HANDLE handle, const struct stm32_dmaregs_s *regs,
|
|||
*
|
||||
****************************************************************************/
|
||||
|
||||
#if defined(HAVE_IP_DMA_V1)
|
||||
void stm32_dma_intack(unsigned int chndx, uint32_t isr);
|
||||
#elif defined(HAVE_IP_DMA_V2)
|
||||
void stm32_dma_intack(unsigned int controller, uint8_t stream, uint32_t isr);
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Name: stm32_dma_intget
|
||||
|
@ -375,9 +378,13 @@ void stm32_dma_intack(unsigned int chndx, uint32_t isr);
|
|||
*
|
||||
****************************************************************************/
|
||||
|
||||
#if defined(HAVE_IP_DMA_V1)
|
||||
uint32_t stm32_dma_intget(unsigned int chndx);
|
||||
#elif defined(HAVE_IP_DMA_V2)
|
||||
uint8_t stm32_dma_intget(unsigned int controller, uint8_t stream);
|
||||
#endif
|
||||
|
||||
#endif /* CONFIG_ARCH_HIPRI_INTERRUPT */
|
||||
#endif /* CONFIG_STM32_STM32F33XX */
|
||||
|
||||
#undef EXTERN
|
||||
#if defined(__cplusplus)
|
||||
|
|
|
@ -646,13 +646,13 @@ static int stm32_hrtim_ioctl(FAR struct file *filep, int cmd, unsigned long arg)
|
|||
|
||||
/* HRTIM Register access */
|
||||
|
||||
static void stm32_modifyreg32(unsigned int addr, uint32_t clrbits,
|
||||
uint32_t setbits);
|
||||
static uint32_t hrtim_cmn_getreg(FAR struct stm32_hrtim_s *priv, uint32_t offset);
|
||||
static void hrtim_cmn_putreg(FAR struct stm32_hrtim_s *priv, uint32_t offset,
|
||||
uint32_t value);
|
||||
#ifdef CONFIG_STM32_HRTIM_BURST
|
||||
static void hrtim_cmn_modifyreg(FAR struct stm32_hrtim_s *priv, uint32_t offset,
|
||||
uint32_t clrbits, uint32_t setbits);
|
||||
#endif
|
||||
static void hrtim_tim_putreg(FAR struct stm32_hrtim_s *priv, uint8_t timer,
|
||||
uint32_t offset, uint32_t value);
|
||||
static void hrtim_tim_modifyreg(FAR struct stm32_hrtim_s *priv, uint8_t timer,
|
||||
|
@ -671,8 +671,10 @@ static uint32_t hrtim_tim_getreg(FAR struct stm32_hrtim_s *priv, uint8_t timer,
|
|||
uint32_t offset);
|
||||
static FAR struct stm32_hrtim_tim_s *hrtim_tim_get(FAR struct stm32_hrtim_s *priv,
|
||||
uint8_t timer);
|
||||
#if defined(CONFIG_STM32_HRTIM_PWM) || defined(CONFIG_STM32_HRTIM_FAULTS)
|
||||
static FAR struct stm32_hrtim_slave_priv_s *hrtim_slave_get(FAR struct stm32_hrtim_s *priv,
|
||||
uint8_t timer);
|
||||
#endif
|
||||
static uint32_t hrtim_base_get(FAR struct stm32_hrtim_s *priv, uint8_t timer);
|
||||
|
||||
/* Configuration */
|
||||
|
@ -764,8 +766,10 @@ static uint16_t hrtim_cmp_get(FAR struct hrtim_dev_s *dev, uint8_t timer,
|
|||
static uint64_t hrtim_fclk_get(FAR struct hrtim_dev_s *dev, uint8_t timer);
|
||||
static int hrtim_soft_update(FAR struct hrtim_dev_s *dev, uint8_t timer);
|
||||
static int hrtim_soft_reset(FAR struct hrtim_dev_s *dev, uint8_t timer);
|
||||
static int hrtim_tim_freq_set(FAR struct hrtim_dev_s *hrtim, uint8_t timer,
|
||||
static int hrtim_tim_freq_set(FAR struct hrtim_dev_s *dev, uint8_t timer,
|
||||
uint64_t freq);
|
||||
static int hrtim_tim_enable(FAR struct hrtim_dev_s *dev, uint8_t timers,
|
||||
bool state);
|
||||
static int hrtim_tim_reset_set(FAR struct stm32_hrtim_s *priv, uint8_t timer,
|
||||
uint64_t reset);
|
||||
static int hrtim_reset_config(FAR struct stm32_hrtim_s *priv);
|
||||
|
@ -1585,6 +1589,7 @@ static const struct stm32_hrtim_ops_s g_hrtim1ops =
|
|||
.soft_update = hrtim_soft_update,
|
||||
.soft_reset = hrtim_soft_reset,
|
||||
.freq_set = hrtim_tim_freq_set,
|
||||
.tim_enable = hrtim_tim_enable,
|
||||
#ifdef CONFIG_STM32_HRTIM_INTERRUPTS
|
||||
.irq_ack = hrtim_irq_ack,
|
||||
.irq_get = hrtim_irq_get,
|
||||
|
@ -1699,28 +1704,6 @@ static int stm32_hrtim_ioctl(FAR struct file *filep, int cmd, unsigned long arg)
|
|||
|
||||
#endif /* CONFIG_STM32_HRTIM_DISABLE_CHARDRV */
|
||||
|
||||
/****************************************************************************
|
||||
* Name: stm32_modifyreg32
|
||||
*
|
||||
* Description:
|
||||
* Modify the value of a 32-bit register (not atomic).
|
||||
*
|
||||
* Input Parameters:
|
||||
* addr - The address of the register
|
||||
* clrbits - The bits to clear
|
||||
* setbits - The bits to set
|
||||
*
|
||||
* Returned Value:
|
||||
* None
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static void stm32_modifyreg32(unsigned int addr, uint32_t clrbits,
|
||||
uint32_t setbits)
|
||||
{
|
||||
putreg32((getreg32(addr) & ~clrbits) | setbits, addr);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: hrtim_cmn_getreg
|
||||
*
|
||||
|
@ -1781,6 +1764,7 @@ static void hrtim_cmn_putreg(FAR struct stm32_hrtim_s *priv, uint32_t offset,
|
|||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_STM32_HRTIM_BURST
|
||||
static void hrtim_cmn_modifyreg(FAR struct stm32_hrtim_s *priv,
|
||||
uint32_t offset, uint32_t clrbits,
|
||||
uint32_t setbits)
|
||||
|
@ -1788,6 +1772,7 @@ static void hrtim_cmn_modifyreg(FAR struct stm32_hrtim_s *priv,
|
|||
hrtim_cmn_putreg(priv, offset,
|
||||
(hrtim_cmn_getreg(priv, offset) & ~clrbits) | setbits);
|
||||
}
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Name: hrtim_tim_get
|
||||
|
@ -1882,7 +1867,7 @@ static FAR struct stm32_hrtim_tim_s *
|
|||
*
|
||||
****************************************************************************/
|
||||
|
||||
|
||||
#if defined(CONFIG_STM32_HRTIM_PWM) || defined(CONFIG_STM32_HRTIM_FAULTS)
|
||||
static FAR struct stm32_hrtim_slave_priv_s *
|
||||
hrtim_slave_get(FAR struct stm32_hrtim_s *priv, uint8_t timer)
|
||||
{
|
||||
|
@ -1913,6 +1898,7 @@ static FAR struct stm32_hrtim_slave_priv_s *
|
|||
errout:
|
||||
return slave;
|
||||
}
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Name: hrtim_base_get
|
||||
|
@ -3253,6 +3239,7 @@ errout:
|
|||
/****************************************************************************
|
||||
* Name: hrtim_output_rst_set
|
||||
****************************************************************************/
|
||||
|
||||
static int hrtim_output_rst_set(FAR struct hrtim_dev_s *dev, uint16_t output,
|
||||
uint32_t rst)
|
||||
{
|
||||
|
@ -5256,7 +5243,7 @@ static int hrtim_soft_reset(FAR struct hrtim_dev_s *dev, uint8_t timer)
|
|||
*
|
||||
****************************************************************************/
|
||||
|
||||
static int hrtim_tim_freq_set(FAR struct hrtim_dev_s *hrtim, uint8_t timer,
|
||||
static int hrtim_tim_freq_set(FAR struct hrtim_dev_s *dev, uint8_t timer,
|
||||
uint64_t freq)
|
||||
{
|
||||
uint64_t per = 0;
|
||||
|
@ -5265,7 +5252,7 @@ static int hrtim_tim_freq_set(FAR struct hrtim_dev_s *hrtim, uint8_t timer,
|
|||
|
||||
/* Get Timer period value for given frequency */
|
||||
|
||||
fclk = HRTIM_FCLK_GET(hrtim, timer);
|
||||
fclk = HRTIM_FCLK_GET(dev, timer);
|
||||
per = fclk/freq;
|
||||
if (per > HRTIM_PER_MAX)
|
||||
{
|
||||
|
@ -5277,12 +5264,49 @@ static int hrtim_tim_freq_set(FAR struct hrtim_dev_s *hrtim, uint8_t timer,
|
|||
|
||||
/* Set Timer period value */
|
||||
|
||||
HRTIM_PER_SET(hrtim, timer, (uint16_t)per);
|
||||
HRTIM_PER_SET(dev, timer, (uint16_t)per);
|
||||
|
||||
errout:
|
||||
errout:
|
||||
return ret;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: hrtim_tim_enable
|
||||
*
|
||||
* Description:
|
||||
* Enable/disable HRTIM timer counter (bulk operation)
|
||||
*
|
||||
* Returned Value:
|
||||
* 0 on success, a negated errno value on failure
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static int hrtim_tim_enable(FAR struct hrtim_dev_s *dev, uint8_t timers,
|
||||
bool state)
|
||||
{
|
||||
FAR struct stm32_hrtim_s *priv = (FAR struct stm32_hrtim_s *)dev->hd_priv;
|
||||
uint32_t regval = 0;
|
||||
|
||||
regval |= (timers & HRTIM_TIMERS_MASK) << HRTIM_MCR_TCEN_SHIFT;
|
||||
|
||||
if (state == true)
|
||||
{
|
||||
/* Set bits */
|
||||
|
||||
hrtim_tim_modifyreg(priv, HRTIM_TIMER_MASTER, STM32_HRTIM_TIM_CR_OFFSET,
|
||||
0, regval);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Clear bits */
|
||||
|
||||
hrtim_tim_modifyreg(priv, HRTIM_TIMER_MASTER, STM32_HRTIM_TIM_CR_OFFSET,
|
||||
regval, 0);
|
||||
}
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: hrtim_tim_reset_set
|
||||
*
|
||||
|
@ -5727,33 +5751,36 @@ static int stm32_hrtimconfig(FAR struct stm32_hrtim_s *priv)
|
|||
}
|
||||
#endif
|
||||
|
||||
#ifndef CONFIG_STM32_HRTIM_NO_ENABLE_TIMERS
|
||||
/* Enable Master Timer */
|
||||
|
||||
#ifdef CONFIG_STM32_HRTIM_MASTER
|
||||
# ifdef CONFIG_STM32_HRTIM_MASTER
|
||||
regval |= HRTIM_MCR_MCEN;
|
||||
#endif
|
||||
# endif
|
||||
|
||||
/* Enable Slave Timers */
|
||||
|
||||
#ifdef CONFIG_STM32_HRTIM_TIMA
|
||||
# ifdef CONFIG_STM32_HRTIM_TIMA
|
||||
regval |= HRTIM_MCR_TACEN;
|
||||
#endif
|
||||
# endif
|
||||
|
||||
#ifdef CONFIG_STM32_HRTIM_TIMB
|
||||
# ifdef CONFIG_STM32_HRTIM_TIMB
|
||||
regval |= HRTIM_MCR_TBCEN;
|
||||
#endif
|
||||
# endif
|
||||
|
||||
#ifdef CONFIG_STM32_HRTIM_TIMC
|
||||
# ifdef CONFIG_STM32_HRTIM_TIMC
|
||||
regval |= HRTIM_MCR_TCCEN;
|
||||
#endif
|
||||
# endif
|
||||
|
||||
#ifdef CONFIG_STM32_HRTIM_TIMD
|
||||
# ifdef CONFIG_STM32_HRTIM_TIMD
|
||||
regval |= HRTIM_MCR_TDCEN;
|
||||
#endif
|
||||
# endif
|
||||
|
||||
#ifdef CONFIG_STM32_HRTIM_TIME
|
||||
# ifdef CONFIG_STM32_HRTIM_TIME
|
||||
regval |= HRTIM_MCR_TECEN;
|
||||
#endif
|
||||
# endif
|
||||
|
||||
#endif /* CONFIG_STM32_HRTIM_NO_ENABLE_TIMERS */
|
||||
|
||||
/* Write enable bits at once */
|
||||
|
||||
|
|
|
@ -232,6 +232,8 @@
|
|||
(hrtim)->hd_ops->soft_reset(hrtim, timer)
|
||||
#define HRTIM_FREQ_SET(hrtim, timer,freq) \
|
||||
(hrtim)->hd_ops->freq_set(hrtim, timer, freq)
|
||||
#define HRTIM_TIM_ENABLE(hrtim, timers, state) \
|
||||
(hrtim)->hd_ops->tim_enable(hrtim, timers, state)
|
||||
#define HRTIM_OUTPUTS_ENABLE(hrtim, outputs, state) \
|
||||
(hrtim)->hd_ops->outputs_enable(hrtim, outputs, state)
|
||||
#define HRTIM_OUTPUT_SET_SET(hrtim, output, set) \
|
||||
|
@ -278,7 +280,9 @@ enum stm32_hrtim_tim_e
|
|||
#ifdef CONFIG_STM32_HRTIM_TIME
|
||||
HRTIM_TIMER_TIME = (1<<5),
|
||||
#endif
|
||||
HRTIM_TIMER_COMMON = (1<<6)
|
||||
HRTIM_TIMER_COMMON = (1<<6),
|
||||
|
||||
HRTIM_TIMERS_MASK = 0x3f
|
||||
};
|
||||
|
||||
/* Source which can force the Tx1/Tx2 output to its inactive state */
|
||||
|
@ -1028,8 +1032,10 @@ struct stm32_hrtim_ops_s
|
|||
uint64_t (*fclk_get)(FAR struct hrtim_dev_s *dev, uint8_t timer);
|
||||
int (*soft_update)(FAR struct hrtim_dev_s *dev, uint8_t timer);
|
||||
int (*soft_reset)(FAR struct hrtim_dev_s *dev, uint8_t timer);
|
||||
int (*freq_set)(FAR struct hrtim_dev_s *hrtim, uint8_t timer,
|
||||
int (*freq_set)(FAR struct hrtim_dev_s *dev, uint8_t timer,
|
||||
uint64_t freq);
|
||||
int (*tim_enable)(FAR struct hrtim_dev_s *dev, uint8_t timers,
|
||||
bool state);
|
||||
|
||||
#ifdef CONFIG_STM32_HRTIM_INTERRUPTS
|
||||
int (*irq_ack)(FAR struct hrtim_dev_s *dev, uint8_t timer, int source);
|
||||
|
|
|
@ -486,6 +486,7 @@ static int pwm_arr_update(FAR struct pwm_lowerhalf_s *dev, uint32_t arr);
|
|||
static uint32_t pwm_arr_get(FAR struct pwm_lowerhalf_s *dev);
|
||||
static int pwm_duty_update(FAR struct pwm_lowerhalf_s *dev, uint8_t channel,
|
||||
ub16_t duty);
|
||||
static int pwm_timer_enable(FAR struct pwm_lowerhalf_s *dev, bool state);
|
||||
|
||||
#ifdef HAVE_ADVTIM
|
||||
static int pwm_break_dt_configure(FAR struct stm32_pwmtimer_s *priv);
|
||||
|
@ -569,9 +570,14 @@ static const struct stm32_pwm_ops_s g_llpwmops =
|
|||
.arr_get = pwm_arr_get,
|
||||
.outputs_enable = pwm_outputs_enable,
|
||||
.soft_update = pwm_soft_update,
|
||||
#ifdef HAVE_COMPLEMENTARY
|
||||
.freq_update = pwm_frequency_update,
|
||||
.tim_enable = pwm_timer_enable,
|
||||
# ifdef CONFIG_DEBUG_PWM_INFO
|
||||
.dump_regs = pwm_dumpregs,
|
||||
# endif
|
||||
# ifdef HAVE_COMPLEMENTARY
|
||||
.dt_update = pwm_deadtime_update,
|
||||
#endif
|
||||
# endif
|
||||
};
|
||||
#endif
|
||||
|
||||
|
@ -2010,7 +2016,7 @@ static void pwm_dumpregs(struct stm32_pwmtimer_s *priv, FAR const char *msg)
|
|||
pwm_getreg(priv, STM32_GTIM_PSC_OFFSET),
|
||||
pwm_getreg(priv, STM32_GTIM_ARR_OFFSET));
|
||||
|
||||
if (priv->timid == 1 || priv->timid == 8 ||i
|
||||
if (priv->timid == 1 || priv->timid == 8 ||
|
||||
(priv->timid >= 15 && priv->timid <= 17))
|
||||
{
|
||||
pwminfo(" RCR: %04x BDTR: %04x\n",
|
||||
|
@ -2067,6 +2073,8 @@ static int pwm_ccr_update(FAR struct pwm_lowerhalf_s *dev, uint8_t index,
|
|||
}
|
||||
#endif
|
||||
|
||||
/* REVISIT: start index from 0? */
|
||||
|
||||
switch (index)
|
||||
{
|
||||
case 1:
|
||||
|
@ -2267,6 +2275,30 @@ static int pwm_duty_update(FAR struct pwm_lowerhalf_s *dev, uint8_t channel,
|
|||
return OK;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: pwm_timer_enable
|
||||
****************************************************************************/
|
||||
|
||||
static int pwm_timer_enable(FAR struct pwm_lowerhalf_s *dev, bool state)
|
||||
{
|
||||
FAR struct stm32_pwmtimer_s *priv = (FAR struct stm32_pwmtimer_s *)dev;
|
||||
|
||||
if (state == true)
|
||||
{
|
||||
/* Enable timer counter */
|
||||
|
||||
pwm_modifyreg(priv, STM32_GTIM_CR1_OFFSET, 0, GTIM_CR1_CEN);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Disable timer counter */
|
||||
|
||||
pwm_modifyreg(priv, STM32_GTIM_CR1_OFFSET, GTIM_CR1_CEN, 0);
|
||||
}
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: pwm_frequency_update
|
||||
*
|
||||
|
@ -3138,7 +3170,7 @@ static int pwm_pulsecount_configure(FAR struct pwm_lowerhalf_s *dev)
|
|||
|
||||
/* Disable the timer until we get it configured */
|
||||
|
||||
pwm_modifyreg(priv, STM32_GTIM_CR1_OFFSET, GTIM_CR1_CEN, 0);
|
||||
pwm_timer_enable(dev, false);
|
||||
|
||||
/* Get configured outputs */
|
||||
|
||||
|
@ -3348,7 +3380,7 @@ static int pwm_pulsecount_timer(FAR struct pwm_lowerhalf_s *dev,
|
|||
|
||||
/* Enable the timer */
|
||||
|
||||
pwm_modifyreg(priv, STM32_GTIM_CR1_OFFSET, 0, GTIM_CR1_CEN);
|
||||
pwm_timer_enable(dev, true);
|
||||
|
||||
/* And enable timer interrupts at the NVIC */
|
||||
|
||||
|
@ -3394,7 +3426,7 @@ static int pwm_configure(FAR struct pwm_lowerhalf_s *dev)
|
|||
|
||||
/* Disable the timer until we get it configured */
|
||||
|
||||
pwm_modifyreg(priv, STM32_GTIM_CR1_OFFSET, GTIM_CR1_CEN, 0);
|
||||
pwm_timer_enable(dev, false);
|
||||
|
||||
/* Initial timer configuration */
|
||||
|
||||
|
@ -3646,7 +3678,7 @@ static int pwm_timer(FAR struct pwm_lowerhalf_s *dev,
|
|||
|
||||
/* Just enable the timer, leaving all interrupts disabled */
|
||||
|
||||
pwm_modifyreg(priv, STM32_GTIM_CR1_OFFSET, 0, GTIM_CR1_CEN);
|
||||
pwm_timer_enable(dev, true);
|
||||
|
||||
pwm_dumpregs(priv, "After starting");
|
||||
|
||||
|
@ -4659,29 +4691,5 @@ errout:
|
|||
return (FAR struct pwm_lowerhalf_s *)lower;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: stm32_llops_get
|
||||
*
|
||||
* Description:
|
||||
* Get low-level ops from the generic PWM lower-half data.
|
||||
*
|
||||
* Input Parameters:
|
||||
* dev - A reference to the lower half PWM driver state structure
|
||||
*
|
||||
* Returned Value:
|
||||
* Pointer to low-level PWM ops
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_STM32_PWM_LL_OPS
|
||||
FAR const struct stm32_pwm_ops_s *
|
||||
stm32_pwm_llops_get(FAR struct pwm_lowerhalf_s *dev)
|
||||
{
|
||||
FAR struct stm32_pwmtimer_s *priv = (FAR struct stm32_pwmtimer_s *)dev;
|
||||
|
||||
return priv->llops;
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* CONFIG_STM32_TIMn_PWM, n = 1,...,17 */
|
||||
|
||||
|
|
|
@ -854,6 +854,40 @@
|
|||
# define PWM_TIM17_CH1NCFG 0
|
||||
#endif
|
||||
|
||||
/* Low-level ops helpers ************************************************************/
|
||||
|
||||
/* NOTE: low-level ops accept pwm_lowerhalf_s as first argument, but llops access
|
||||
* can be found in stm32_pwm_dev_s
|
||||
*/
|
||||
|
||||
#define PWM_SETUP(dev) \
|
||||
(dev)->ops->setup((FAR struct pwm_lowerhalf_s *)dev)
|
||||
#define PWM_SHUTDOWN(dev) \
|
||||
(dev)->ops->shutdown((FAR struct pwm_lowerhalf_s *)dev)
|
||||
#define PWM_CCR_UPDATE(dev, index, ccr) \
|
||||
(dev)->llops->ccr_update((FAR struct pwm_lowerhalf_s *)dev, index, ccr)
|
||||
#define PWM_CCR_GET(dev, index) \
|
||||
(dev)->llops->ccr_get((FAR struct pwm_lowerhalf_s *)dev, index)
|
||||
#define PWM_ARR_UPDATE(dev, arr) \
|
||||
(dev)->llops->arr_update((FAR struct pwm_lowerhalf_s *)dev, arr)
|
||||
#define PWM_ARR_GET(dev) \
|
||||
(dev)->llops->arr_get((FAR struct pwm_lowerhalf_s *)dev)
|
||||
#define PWM_OUTPUTS_ENABLE(dev, out, state) \
|
||||
(dev)->llops->outputs_enable((FAR struct pwm_lowerhalf_s *)dev, out, state)
|
||||
#define PWM_SOFT_UPDATE(dev) \
|
||||
(dev)->llops->soft_update((FAR struct pwm_lowerhalf_s *)dev)
|
||||
#define PWM_CONFIGURE(dev) \
|
||||
(dev)->llops->configure((FAR struct pwm_lowerhalf_s *)dev)
|
||||
#define PWM_SOFT_BREAK(dev, state) \
|
||||
(dev)->llops->soft_break((FAR struct pwm_lowerhalf_s *)dev, state)
|
||||
#define PWM_FREQ_UPDATE(dev, freq) \
|
||||
(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) \
|
||||
(dev)->llops->dump_regs((FAR struct pwm_lowerhalf_s *)dev)
|
||||
#define PWM_DT_UPDATE(dev, dt) \
|
||||
(dev)->llops->dt_update((FAR struct pwm_lowerhalf_s *)dev, dt)
|
||||
|
||||
/************************************************************************************
|
||||
* Public Types
|
||||
|
@ -924,7 +958,27 @@ enum stm32_chan_e
|
|||
|
||||
#ifdef CONFIG_STM32_PWM_LL_OPS
|
||||
|
||||
/* */
|
||||
/* This structure provides the publicly visable representation of the
|
||||
* "lower-half" PWM driver structure.
|
||||
*/
|
||||
|
||||
struct stm32_pwm_dev_s
|
||||
{
|
||||
/* The first field of this state structure must be a pointer to the PWM
|
||||
* callback structure to be consistent with upper-half PWM driver.
|
||||
*/
|
||||
|
||||
FAR const struct pwm_ops_s *ops;
|
||||
|
||||
/* Publicly visible portion of the "lower-half" PWM driver structure */
|
||||
|
||||
FAR const struct stm32_pwm_ops_s *llops;
|
||||
|
||||
/* Require cast-compatibility with private "lower-half" PWM strucutre */
|
||||
};
|
||||
|
||||
/* Low-level operations for PWM */
|
||||
|
||||
struct pwm_lowerhalf_s;
|
||||
struct stm32_pwm_ops_s
|
||||
{
|
||||
|
@ -960,6 +1014,20 @@ struct stm32_pwm_ops_s
|
|||
|
||||
int (*soft_break)(FAR struct pwm_lowerhalf_s *dev, bool state);
|
||||
|
||||
/* Update frequency */
|
||||
|
||||
int (*freq_update)(FAR struct pwm_lowerhalf_s *dev, uint32_t frequency);
|
||||
|
||||
/* Enable timer counter */
|
||||
|
||||
int (*tim_enable)(FAR struct pwm_lowerhalf_s *dev, bool state);
|
||||
|
||||
#ifdef CONFIG_DEBUG_PWM_INFO
|
||||
/* Dump timer registers */
|
||||
|
||||
int (*dump_regs)(FAR struct pwm_lowerhalf_s *dev);
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_COMPLEMENTARY
|
||||
/* Deadtime update */
|
||||
|
||||
|
@ -967,7 +1035,7 @@ struct stm32_pwm_ops_s
|
|||
#endif
|
||||
};
|
||||
|
||||
#endif
|
||||
#endif /* CONFIG_STM32_PWM_LL_OPS */
|
||||
|
||||
/************************************************************************************
|
||||
* Public Data
|
||||
|
@ -1007,15 +1075,6 @@ extern "C"
|
|||
|
||||
FAR struct pwm_lowerhalf_s *stm32_pwminitialize(int timer);
|
||||
|
||||
/************************************************************************************
|
||||
* Name: stm32_pwm_llops_get
|
||||
*
|
||||
************************************************************************************/
|
||||
|
||||
#ifdef CONFIG_STM32_PWM_LL_OPS
|
||||
FAR const struct stm32_pwm_ops_s *stm32_pwm_llops_get(FAR struct pwm_lowerhalf_s *dev);
|
||||
#endif
|
||||
|
||||
#undef EXTERN
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
|
|
|
@ -55,7 +55,6 @@
|
|||
#include "stm32_dma.h"
|
||||
#include "stm32.h"
|
||||
|
||||
|
||||
#if defined(CONFIG_STM32_STM32F10XX) || defined(CONFIG_STM32_STM32F30XX) || \
|
||||
defined(CONFIG_STM32_STM32F33XX) || defined(CONFIG_STM32_STM32F37XX) || \
|
||||
defined(CONFIG_STM32_STM32L15XX)
|
||||
|
@ -756,4 +755,37 @@ void stm32_dmadump(DMA_HANDLE handle, const struct stm32_dmaregs_s *regs,
|
|||
}
|
||||
#endif
|
||||
|
||||
#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)
|
||||
{
|
||||
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_ARCH_HIPRI_INTERRUPT */
|
||||
|
||||
#endif /* CONFIG_STM32_STM32F10XX */
|
||||
|
|
|
@ -57,6 +57,8 @@
|
|||
|
||||
/* This file supports only the STM32 F2 family (although it is identical to
|
||||
* the corresponding F4 file).
|
||||
*
|
||||
* TODO: merge this with stm32f40xxx_dma.c (STM32 DMA IP core version 2)
|
||||
*/
|
||||
|
||||
#if defined(CONFIG_STM32_STM32F20XX)
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -1,731 +0,0 @@
|
|||
/****************************************************************************
|
||||
* arch/arm/src/stm32/stm32f33xxx_dma.c
|
||||
*
|
||||
* Copyright (C) 2017 Gregory Nutt. All rights reserved.
|
||||
* Authors: Gregory Nutt <gnutt@nuttx.org>
|
||||
* Mateusz Szafoni <raiden00@railab.me>
|
||||
*
|
||||
* 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 <nuttx/config.h>
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include <semaphore.h>
|
||||
#include <debug.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include <nuttx/irq.h>
|
||||
#include <nuttx/arch.h>
|
||||
|
||||
#include "up_arch.h"
|
||||
#include "up_internal.h"
|
||||
#include "sched/sched.h"
|
||||
#include "chip.h"
|
||||
#include "stm32_dma.h"
|
||||
#include "stm32.h"
|
||||
|
||||
#if defined(CONFIG_STM32_DMA1) && defined(CONFIG_STM32_STM32F33XX)
|
||||
|
||||
#ifndef CONFIG_ARCH_DMA
|
||||
# warning "STM32 DMA enabled but CONFIG_ARCH_DMA disabled"
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
#define DMA1_NCHANNELS 7
|
||||
#define DMA_NCHANNELS DMA1_NCHANNELS
|
||||
|
||||
#ifndef CONFIG_DMA_PRI
|
||||
# define CONFIG_DMA_PRI NVIC_SYSH_PRIORITY_DEFAULT
|
||||
#endif
|
||||
|
||||
/* Convert the DMA channel base address to the DMA register block address */
|
||||
|
||||
#define DMA_BASE(ch) (ch & 0xfffffc00)
|
||||
|
||||
/****************************************************************************
|
||||
* Private Types
|
||||
****************************************************************************/
|
||||
|
||||
/* This structure descibes one DMA channel */
|
||||
|
||||
struct stm32_dma_s
|
||||
{
|
||||
uint8_t chan; /* DMA channel number (0-6) */
|
||||
uint8_t irq; /* DMA channel IRQ number */
|
||||
sem_t sem; /* Used to wait for DMA channel to become available */
|
||||
uint32_t base; /* DMA register channel base address */
|
||||
dma_callback_t callback; /* Callback invoked when the DMA completes */
|
||||
void *arg; /* Argument passed to callback function */
|
||||
};
|
||||
|
||||
/****************************************************************************
|
||||
* Private Data
|
||||
****************************************************************************/
|
||||
|
||||
/* This array describes the state of each DMA */
|
||||
|
||||
static struct stm32_dma_s g_dma[DMA_NCHANNELS] =
|
||||
{
|
||||
{
|
||||
.chan = 0,
|
||||
.irq = STM32_IRQ_DMA1CH1,
|
||||
.base = STM32_DMA1_BASE + STM32_DMACHAN_OFFSET(0),
|
||||
},
|
||||
{
|
||||
.chan = 1,
|
||||
.irq = STM32_IRQ_DMA1CH2,
|
||||
.base = STM32_DMA1_BASE + STM32_DMACHAN_OFFSET(1),
|
||||
},
|
||||
{
|
||||
.chan = 2,
|
||||
.irq = STM32_IRQ_DMA1CH3,
|
||||
.base = STM32_DMA1_BASE + STM32_DMACHAN_OFFSET(2),
|
||||
},
|
||||
{
|
||||
.chan = 3,
|
||||
.irq = STM32_IRQ_DMA1CH4,
|
||||
.base = STM32_DMA1_BASE + STM32_DMACHAN_OFFSET(3),
|
||||
},
|
||||
{
|
||||
.chan = 4,
|
||||
.irq = STM32_IRQ_DMA1CH5,
|
||||
.base = STM32_DMA1_BASE + STM32_DMACHAN_OFFSET(4),
|
||||
},
|
||||
{
|
||||
.chan = 5,
|
||||
.irq = STM32_IRQ_DMA1CH6,
|
||||
.base = STM32_DMA1_BASE + STM32_DMACHAN_OFFSET(5),
|
||||
},
|
||||
{
|
||||
.chan = 6,
|
||||
.irq = STM32_IRQ_DMA1CH7,
|
||||
.base = STM32_DMA1_BASE + STM32_DMACHAN_OFFSET(6),
|
||||
},
|
||||
};
|
||||
|
||||
/****************************************************************************
|
||||
* Private Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* DMA register access functions
|
||||
****************************************************************************/
|
||||
|
||||
/* Get non-channel register from DMA1 or DMA2 */
|
||||
|
||||
static inline uint32_t dmabase_getreg(struct stm32_dma_s *dmach, uint32_t offset)
|
||||
{
|
||||
return getreg32(DMA_BASE(dmach->base) + offset);
|
||||
}
|
||||
|
||||
/* Write to non-channel register in DMA1 or DMA2 */
|
||||
|
||||
static inline void dmabase_putreg(struct stm32_dma_s *dmach, uint32_t offset, uint32_t value)
|
||||
{
|
||||
putreg32(value, DMA_BASE(dmach->base) + offset);
|
||||
}
|
||||
|
||||
/* Get channel register from DMA1 or DMA2 */
|
||||
|
||||
static inline uint32_t dmachan_getreg(struct stm32_dma_s *dmach, uint32_t offset)
|
||||
{
|
||||
return getreg32(dmach->base + offset);
|
||||
}
|
||||
|
||||
/* Write to channel register in DMA1 or DMA2 */
|
||||
|
||||
static inline void dmachan_putreg(struct stm32_dma_s *dmach, uint32_t offset, uint32_t value)
|
||||
{
|
||||
putreg32(value, dmach->base + offset);
|
||||
}
|
||||
|
||||
/************************************************************************************
|
||||
* Name: stm32_dmatake() and stm32_dmagive()
|
||||
*
|
||||
* Description:
|
||||
* Used to get exclusive access to a DMA channel.
|
||||
*
|
||||
************************************************************************************/
|
||||
|
||||
static void stm32_dmatake(FAR struct stm32_dma_s *dmach)
|
||||
{
|
||||
int ret;
|
||||
|
||||
do
|
||||
{
|
||||
/* Take the semaphore (perhaps waiting) */
|
||||
|
||||
ret = nxsem_wait(&dmach->sem);
|
||||
|
||||
/* The only case that an error should occur here is if the wait was
|
||||
* awakened by a signal.
|
||||
*/
|
||||
|
||||
DEBUGASSERT(ret == OK || ret == -EINTR);
|
||||
}
|
||||
while (ret == -EINTR);
|
||||
}
|
||||
|
||||
static inline void stm32_dmagive(FAR struct stm32_dma_s *dmach)
|
||||
{
|
||||
(void)nxsem_post(&dmach->sem);
|
||||
}
|
||||
|
||||
/************************************************************************************
|
||||
* Name: stm32_dmachandisable
|
||||
*
|
||||
* Description:
|
||||
* Disable the DMA channel
|
||||
*
|
||||
************************************************************************************/
|
||||
|
||||
static void stm32_dmachandisable(struct stm32_dma_s *dmach)
|
||||
{
|
||||
uint32_t regval;
|
||||
|
||||
/* Disable all interrupts at the DMA controller */
|
||||
|
||||
regval = dmachan_getreg(dmach, STM32_DMACHAN_CCR_OFFSET);
|
||||
regval &= ~DMA_CCR_ALLINTS;
|
||||
|
||||
/* Disable the DMA channel */
|
||||
|
||||
regval &= ~DMA_CCR_EN;
|
||||
dmachan_putreg(dmach, STM32_DMACHAN_CCR_OFFSET, regval);
|
||||
|
||||
/* Clear pending channel interrupts */
|
||||
|
||||
dmabase_putreg(dmach, STM32_DMA_IFCR_OFFSET, DMA_ISR_CHAN_MASK(dmach->chan));
|
||||
}
|
||||
|
||||
/************************************************************************************
|
||||
* Name: stm32_dmainterrupt
|
||||
*
|
||||
* Description:
|
||||
* DMA interrupt handler
|
||||
*
|
||||
************************************************************************************/
|
||||
|
||||
static int stm32_dmainterrupt(int irq, void *context, FAR void *arg)
|
||||
{
|
||||
struct stm32_dma_s *dmach;
|
||||
uint32_t isr;
|
||||
int chndx = 0;
|
||||
|
||||
/* Get the channel structure from the interrupt number */
|
||||
|
||||
if (irq >= STM32_IRQ_DMA1CH1 && irq <= STM32_IRQ_DMA1CH7)
|
||||
{
|
||||
chndx = irq - STM32_IRQ_DMA1CH1;
|
||||
}
|
||||
else
|
||||
{
|
||||
DEBUGPANIC();
|
||||
}
|
||||
dmach = &g_dma[chndx];
|
||||
|
||||
/* Get the interrupt status (for this channel only) */
|
||||
|
||||
isr = dmabase_getreg(dmach, STM32_DMA_ISR_OFFSET) & DMA_ISR_CHAN_MASK(dmach->chan);
|
||||
|
||||
/* Clear the interrupts we are handling */
|
||||
|
||||
dmabase_putreg(dmach, STM32_DMA_IFCR_OFFSET, isr);
|
||||
|
||||
/* Invoke the callback */
|
||||
|
||||
if (dmach->callback)
|
||||
{
|
||||
dmach->callback(dmach, isr >> DMA_ISR_CHAN_SHIFT(dmach->chan), dmach->arg);
|
||||
}
|
||||
return OK;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: stm32_dmainitialize
|
||||
*
|
||||
* Description:
|
||||
* Initialize the DMA subsystem
|
||||
*
|
||||
* Returned Value:
|
||||
* None
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
void weak_function up_dma_initialize(void)
|
||||
{
|
||||
struct stm32_dma_s *dmach;
|
||||
int chndx;
|
||||
|
||||
/* Initialize each DMA channel */
|
||||
|
||||
for (chndx = 0; chndx < DMA_NCHANNELS; chndx++)
|
||||
{
|
||||
dmach = &g_dma[chndx];
|
||||
nxsem_init(&dmach->sem, 0, 1);
|
||||
|
||||
/* Attach DMA interrupt vectors */
|
||||
|
||||
(void)irq_attach(dmach->irq, stm32_dmainterrupt, NULL);
|
||||
|
||||
/* Disable the DMA channel */
|
||||
|
||||
stm32_dmachandisable(dmach);
|
||||
|
||||
/* Enable the IRQ at the NVIC (still disabled at the DMA controller) */
|
||||
|
||||
up_enable_irq(dmach->irq);
|
||||
|
||||
#ifdef CONFIG_ARCH_IRQPRIO
|
||||
/* Set the interrupt priority */
|
||||
|
||||
up_prioritize_irq(dmach->irq, CONFIG_DMA_PRI);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: stm32_dmachannel
|
||||
*
|
||||
* Description:
|
||||
* Allocate a DMA channel. This function gives the caller mutually
|
||||
* exclusive access to the DMA channel specified by the 'chndx' argument.
|
||||
* DMA channels are shared on the STM32: Devices sharing the same DMA
|
||||
* channel cannot do DMA concurrently! See the DMACHAN_* definitions in
|
||||
* stm32_dma.h.
|
||||
*
|
||||
* If the DMA channel is not available, then stm32_dmachannel() will wait
|
||||
* until the holder of the channel relinquishes the channel by calling
|
||||
* stm32_dmafree(). WARNING: If you have two devices sharing a DMA
|
||||
* channel and the code never releases the channel, the stm32_dmachannel
|
||||
* call for the other will hang forever in this function! Don't let your
|
||||
* design do that!
|
||||
*
|
||||
* Hmm.. I suppose this interface could be extended to make a non-blocking
|
||||
* version. Feel free to do that if that is what you need.
|
||||
*
|
||||
* Input Parameters:
|
||||
* chndx - Identifies the stream/channel resource. For the STM32 F1, this
|
||||
* is simply the channel number as provided by the DMACHAN_* definitions
|
||||
* in chip/stm32f10xxx_dma.h.
|
||||
*
|
||||
* Returned Value:
|
||||
* Provided that 'chndx' is valid, this function ALWAYS returns a non-NULL,
|
||||
* void* DMA channel handle. (If 'chndx' is invalid, the function will
|
||||
* assert if debug is enabled or do something ignorant otherwise).
|
||||
*
|
||||
* Assumptions:
|
||||
* - The caller does not hold he DMA channel.
|
||||
* - The caller can wait for the DMA channel to be freed if it is no
|
||||
* available.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
DMA_HANDLE stm32_dmachannel(unsigned int chndx)
|
||||
{
|
||||
struct stm32_dma_s *dmach = &g_dma[chndx];
|
||||
|
||||
DEBUGASSERT(chndx < DMA_NCHANNELS);
|
||||
|
||||
/* Get exclusive access to the DMA channel -- OR wait until the channel
|
||||
* is available if it is currently being used by another driver
|
||||
*/
|
||||
|
||||
stm32_dmatake(dmach);
|
||||
|
||||
/* The caller now has exclusive use of the DMA channel */
|
||||
|
||||
return (DMA_HANDLE)dmach;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: stm32_dmafree
|
||||
*
|
||||
* Description:
|
||||
* Release a DMA channel. If another thread is waiting for this DMA channel
|
||||
* in a call to stm32_dmachannel, then this function will re-assign the
|
||||
* DMA channel to that thread and wake it up. NOTE: The 'handle' used
|
||||
* in this argument must NEVER be used again until stm32_dmachannel() is
|
||||
* called again to re-gain access to the channel.
|
||||
*
|
||||
* Returned Value:
|
||||
* None
|
||||
*
|
||||
* Assumptions:
|
||||
* - The caller holds the DMA channel.
|
||||
* - There is no DMA in progress
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
void stm32_dmafree(DMA_HANDLE handle)
|
||||
{
|
||||
struct stm32_dma_s *dmach = (struct stm32_dma_s *)handle;
|
||||
|
||||
DEBUGASSERT(handle != NULL);
|
||||
|
||||
/* Release the channel */
|
||||
|
||||
stm32_dmagive(dmach);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: stm32_dmasetup
|
||||
*
|
||||
* Description:
|
||||
* Configure DMA before using
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
void stm32_dmasetup(DMA_HANDLE handle, uint32_t paddr, uint32_t maddr,
|
||||
size_t ntransfers, uint32_t ccr)
|
||||
{
|
||||
struct stm32_dma_s *dmach = (struct stm32_dma_s *)handle;
|
||||
uint32_t regval;
|
||||
|
||||
/* Then DMA_CNDTRx register can only be modified if the DMA channel is
|
||||
* disabled.
|
||||
*/
|
||||
|
||||
regval = dmachan_getreg(dmach, STM32_DMACHAN_CCR_OFFSET);
|
||||
regval &= ~(DMA_CCR_EN);
|
||||
dmachan_putreg(dmach, STM32_DMACHAN_CCR_OFFSET, regval);
|
||||
|
||||
/* Set the peripheral register address in the DMA_CPARx register. The data
|
||||
* will be moved from/to this address to/from the memory after the
|
||||
* peripheral event.
|
||||
*/
|
||||
|
||||
dmachan_putreg(dmach, STM32_DMACHAN_CPAR_OFFSET, paddr);
|
||||
|
||||
/* Set the memory address in the DMA_CMARx register. The data will be
|
||||
* written to or read from this memory after the peripheral event.
|
||||
*/
|
||||
|
||||
dmachan_putreg(dmach, STM32_DMACHAN_CMAR_OFFSET, maddr);
|
||||
|
||||
/* Configure the total number of data to be transferred in the DMA_CNDTRx
|
||||
* register. After each peripheral event, this value will be decremented.
|
||||
*/
|
||||
|
||||
dmachan_putreg(dmach, STM32_DMACHAN_CNDTR_OFFSET, ntransfers);
|
||||
|
||||
/* Configure the channel priority using the PL[1:0] bits in the DMA_CCRx
|
||||
* register. Configure data transfer direction, circular mode, peripheral & memory
|
||||
* incremented mode, peripheral & memory data size, and interrupt after
|
||||
* half and/or full transfer in the DMA_CCRx register.
|
||||
*/
|
||||
|
||||
regval = dmachan_getreg(dmach, STM32_DMACHAN_CCR_OFFSET);
|
||||
regval &= ~(DMA_CCR_MEM2MEM | DMA_CCR_PL_MASK | DMA_CCR_MSIZE_MASK |
|
||||
DMA_CCR_PSIZE_MASK | DMA_CCR_MINC | DMA_CCR_PINC | DMA_CCR_CIRC |
|
||||
DMA_CCR_DIR);
|
||||
ccr &= (DMA_CCR_MEM2MEM | DMA_CCR_PL_MASK | DMA_CCR_MSIZE_MASK |
|
||||
DMA_CCR_PSIZE_MASK | DMA_CCR_MINC | DMA_CCR_PINC | DMA_CCR_CIRC |
|
||||
DMA_CCR_DIR);
|
||||
regval |= ccr;
|
||||
dmachan_putreg(dmach, STM32_DMACHAN_CCR_OFFSET, regval);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: stm32_dmastart
|
||||
*
|
||||
* Description:
|
||||
* Start the DMA transfer
|
||||
*
|
||||
* Assumptions:
|
||||
* - DMA handle allocated by stm32_dmachannel()
|
||||
* - No DMA in progress
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
void stm32_dmastart(DMA_HANDLE handle, dma_callback_t callback,
|
||||
void *arg, bool half)
|
||||
{
|
||||
struct stm32_dma_s *dmach = (struct stm32_dma_s *)handle;
|
||||
uint32_t ccr;
|
||||
|
||||
DEBUGASSERT(handle != NULL);
|
||||
|
||||
/* Save the callback info. This will be invoked whent the DMA commpletes */
|
||||
|
||||
dmach->callback = callback;
|
||||
dmach->arg = arg;
|
||||
|
||||
/* Activate the channel by setting the ENABLE bit in the DMA_CCRx register.
|
||||
* As soon as the channel is enabled, it can serve any DMA request from the
|
||||
* peripheral connected on the channel.
|
||||
*/
|
||||
|
||||
ccr = dmachan_getreg(dmach, STM32_DMACHAN_CCR_OFFSET);
|
||||
ccr |= DMA_CCR_EN;
|
||||
|
||||
/* In normal mode, interrupt at either half or full completion. In circular mode,
|
||||
* always interrupt on buffer wrap, and optionally interrupt at the halfway point.
|
||||
*/
|
||||
|
||||
if ((ccr & DMA_CCR_CIRC) == 0)
|
||||
{
|
||||
/* Once half of the bytes are transferred, the half-transfer flag (HTIF) is
|
||||
* set and an interrupt is generated if the Half-Transfer Interrupt Enable
|
||||
* bit (HTIE) is set. At the end of the transfer, the Transfer Complete Flag
|
||||
* (TCIF) is set and an interrupt is generated if the Transfer Complete
|
||||
* Interrupt Enable bit (TCIE) is set.
|
||||
*/
|
||||
|
||||
ccr |= (half ? (DMA_CCR_HTIE | DMA_CCR_TEIE) : (DMA_CCR_TCIE | DMA_CCR_TEIE));
|
||||
}
|
||||
else
|
||||
{
|
||||
/* In nonstop mode, when the transfer completes it immediately resets
|
||||
* and starts again. The transfer-complete interrupt is thus always
|
||||
* enabled, and the half-complete interrupt can be used in circular
|
||||
* mode to determine when the buffer is half-full, or in double-buffered
|
||||
* mode to determine when one of the two buffers is full.
|
||||
*/
|
||||
|
||||
ccr |= (half ? DMA_CCR_HTIE : 0) | DMA_CCR_TCIE | DMA_CCR_TEIE;
|
||||
}
|
||||
|
||||
dmachan_putreg(dmach, STM32_DMACHAN_CCR_OFFSET, ccr);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: stm32_dmastop
|
||||
*
|
||||
* Description:
|
||||
* Cancel the DMA. After stm32_dmastop() is called, the DMA channel is
|
||||
* reset and stm32_dmasetup() must be called before stm32_dmastart() can be
|
||||
* called again
|
||||
*
|
||||
* Assumptions:
|
||||
* - DMA handle allocated by stm32_dmachannel()
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
void stm32_dmastop(DMA_HANDLE handle)
|
||||
{
|
||||
struct stm32_dma_s *dmach = (struct stm32_dma_s *)handle;
|
||||
stm32_dmachandisable(dmach);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: stm32_dmaresidual
|
||||
*
|
||||
* Description:
|
||||
* Returns the number of bytes remaining to be transferred
|
||||
*
|
||||
* Assumptions:
|
||||
* - DMA handle allocated by stm32_dmachannel()
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
size_t stm32_dmaresidual(DMA_HANDLE handle)
|
||||
{
|
||||
struct stm32_dma_s *dmach = (struct stm32_dma_s *)handle;
|
||||
|
||||
return dmachan_getreg(dmach, STM32_DMACHAN_CNDTR_OFFSET);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: stm32_dmacapable
|
||||
*
|
||||
* Description:
|
||||
* Check if the DMA controller can transfer data to/from given memory
|
||||
* address. This depends on the internal connections in the ARM bus matrix
|
||||
* of the processor. Note that this only applies to memory addresses, it
|
||||
* will return false for any peripheral address.
|
||||
*
|
||||
* Returned Value:
|
||||
* True, if transfer is possible.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_STM32_DMACAPABLE
|
||||
bool stm32_dmacapable(uint32_t maddr, uint32_t count, uint32_t ccr)
|
||||
{
|
||||
uint32_t transfer_size;
|
||||
uint32_t mend;
|
||||
|
||||
/* Verify that the address conforms to the memory transfer size.
|
||||
* Transfers to/from memory performed by the DMA controller are
|
||||
* required to be aligned to their size.
|
||||
*
|
||||
* See ST RM0090 rev4, section 9.3.11
|
||||
*
|
||||
* Compute mend inline to avoid a possible non-constant integer
|
||||
* multiply.
|
||||
*/
|
||||
|
||||
switch (ccr & DMA_CCR_MSIZE_MASK)
|
||||
{
|
||||
case DMA_CCR_MSIZE_8BITS:
|
||||
transfer_size = 1;
|
||||
mend = maddr + count - 1;
|
||||
break;
|
||||
|
||||
case DMA_CCR_MSIZE_16BITS:
|
||||
transfer_size = 2;
|
||||
mend = maddr + (count << 1) - 1;
|
||||
break;
|
||||
|
||||
case DMA_CCR_MSIZE_32BITS:
|
||||
transfer_size = 4;
|
||||
mend = maddr + (count << 2) - 1;
|
||||
break;
|
||||
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
|
||||
if ((maddr & (transfer_size - 1)) != 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Verify that the transfer is to a memory region that supports DMA. */
|
||||
|
||||
if ((maddr & STM32_REGION_MASK) != (mend & STM32_REGION_MASK))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
switch (maddr & STM32_REGION_MASK)
|
||||
{
|
||||
case STM32_SRAM_BASE:
|
||||
case STM32_CODE_BASE:
|
||||
/* All RAM and flash is supported */
|
||||
|
||||
return true;
|
||||
|
||||
default:
|
||||
/* Everything else is unsupported by DMA */
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Name: stm32_dmasample
|
||||
*
|
||||
* Description:
|
||||
* Sample DMA register contents
|
||||
*
|
||||
* Assumptions:
|
||||
* - DMA handle allocated by stm32_dmachannel()
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_DEBUG_DMA_INFO
|
||||
void stm32_dmasample(DMA_HANDLE handle, struct stm32_dmaregs_s *regs)
|
||||
{
|
||||
struct stm32_dma_s *dmach = (struct stm32_dma_s *)handle;
|
||||
irqstate_t flags;
|
||||
|
||||
flags = enter_critical_section();
|
||||
regs->isr = dmabase_getreg(dmach, STM32_DMA_ISR_OFFSET);
|
||||
regs->ccr = dmachan_getreg(dmach, STM32_DMACHAN_CCR_OFFSET);
|
||||
regs->cndtr = dmachan_getreg(dmach, STM32_DMACHAN_CNDTR_OFFSET);
|
||||
regs->cpar = dmachan_getreg(dmach, STM32_DMACHAN_CPAR_OFFSET);
|
||||
regs->cmar = dmachan_getreg(dmach, STM32_DMACHAN_CMAR_OFFSET);
|
||||
leave_critical_section(flags);
|
||||
}
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Name: stm32_dmadump
|
||||
*
|
||||
* Description:
|
||||
* Dump previously sampled DMA register contents
|
||||
*
|
||||
* Assumptions:
|
||||
* - DMA handle allocated by stm32_dmachannel()
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_DEBUG_DMA_INFO
|
||||
void stm32_dmadump(DMA_HANDLE handle, const struct stm32_dmaregs_s *regs,
|
||||
const char *msg)
|
||||
{
|
||||
struct stm32_dma_s *dmach = (struct stm32_dma_s *)handle;
|
||||
uint32_t dmabase = DMA_BASE(dmach->base);
|
||||
|
||||
dmainfo("DMA Registers: %s\n", msg);
|
||||
dmainfo(" ISRC[%08x]: %08x\n", dmabase + STM32_DMA_ISR_OFFSET, regs->isr);
|
||||
dmainfo(" CCR[%08x]: %08x\n", dmach->base + STM32_DMACHAN_CCR_OFFSET, regs->ccr);
|
||||
dmainfo(" CNDTR[%08x]: %08x\n", dmach->base + STM32_DMACHAN_CNDTR_OFFSET, regs->cndtr);
|
||||
dmainfo(" CPAR[%08x]: %08x\n", dmach->base + STM32_DMACHAN_CPAR_OFFSET, regs->cpar);
|
||||
dmainfo(" CMAR[%08x]: %08x\n", dmach->base + STM32_DMACHAN_CMAR_OFFSET, regs->cmar);
|
||||
}
|
||||
#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 */
|
|
@ -1055,4 +1055,81 @@ void stm32_dmadump(DMA_HANDLE handle, const struct stm32_dmaregs_s *regs,
|
|||
}
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_ARCH_HIPRI_INTERRUPT
|
||||
|
||||
/****************************************************************************
|
||||
* Name: stm32_dma_intack
|
||||
*
|
||||
* Description:
|
||||
* Public visible interface to acknowledge interrupts on DMA stream
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
void stm32_dma_intack(unsigned int controller, uint8_t stream, uint32_t isr)
|
||||
{
|
||||
struct stm32_dma_s *dmast = stm32_dmastream(stream, controller);
|
||||
uint32_t regval = 0;
|
||||
uint32_t offset = 0;
|
||||
|
||||
/* Select the interrupt flag clear register (either the LIFCR or HIFCR)
|
||||
* based on the stream number
|
||||
*/
|
||||
|
||||
if (stream < 4)
|
||||
{
|
||||
offset = STM32_DMA_LIFCR_OFFSET;
|
||||
}
|
||||
else
|
||||
{
|
||||
offset = STM32_DMA_HIFCR_OFFSET;
|
||||
}
|
||||
|
||||
/* Get value to write */
|
||||
|
||||
regval |= ((isr & DMA_STREAM_MASK) << dmast->shift);
|
||||
|
||||
/* Write register */
|
||||
|
||||
dmabase_putreg(dmast, offset, regval);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: stm32_dma_intget
|
||||
*
|
||||
* Description:
|
||||
* Public visible interface to get pending interrupts from DMA stream
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
uint8_t stm32_dma_intget(unsigned int controller, uint8_t stream)
|
||||
{
|
||||
struct stm32_dma_s *dmast = stm32_dmastream(stream, controller);
|
||||
uint32_t regval = 0;
|
||||
uint32_t offset = 0;
|
||||
|
||||
/* Select the interrupt status register (either the LISR or HISR)
|
||||
* based on the stream number
|
||||
*/
|
||||
|
||||
if (stream < 4)
|
||||
{
|
||||
offset = STM32_DMA_LISR_OFFSET;
|
||||
}
|
||||
else
|
||||
{
|
||||
offset = STM32_DMA_HISR_OFFSET;
|
||||
}
|
||||
|
||||
/* Get register value */
|
||||
|
||||
regval = dmabase_getreg(dmast, offset);
|
||||
|
||||
/* Get stream status */
|
||||
|
||||
regval = ((regval >> dmast->shift) & DMA_STREAM_MASK);
|
||||
|
||||
return (uint8_t)regval;
|
||||
}
|
||||
#endif /* CONFIG_ARCH_HIPRI_INTERRUPT */
|
||||
|
||||
#endif /* CONFIG_STM32_STM32F4XXX */
|
||||
|
|
|
@ -2094,6 +2094,9 @@ endif
|
|||
if ARCH_BOARD_NUCLEO_F091RC
|
||||
source "configs/nucleo-f091rc/Kconfig"
|
||||
endif
|
||||
if ARCH_BOARD_NUCLEO_F302R8
|
||||
source "configs/nucleo-f302r8/Kconfig"
|
||||
endif
|
||||
if ARCH_BOARD_NUCLEO_F303RE
|
||||
source "configs/nucleo-f303re/Kconfig"
|
||||
endif
|
||||
|
|
|
@ -5,4 +5,8 @@
|
|||
|
||||
if ARCH_BOARD_NUCLEO_F302R8
|
||||
|
||||
config NUCLEOF302R8_HIGHPRI
|
||||
bool "High priority interrupt test"
|
||||
default n
|
||||
|
||||
endif
|
||||
|
|
65
configs/nucleo-f302r8/highpri/defconfig
Normal file
65
configs/nucleo-f302r8/highpri/defconfig
Normal file
|
@ -0,0 +1,65 @@
|
|||
# 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
|
||||
CONFIG_ARCH_BUTTONS=y
|
||||
CONFIG_ARCH_CHIP_STM32=y
|
||||
CONFIG_ARCH_CHIP_STM32F302R8=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_NUCLEOF302R8_HIGHPRI=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_PWM=y
|
||||
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_ADC1=y
|
||||
CONFIG_STM32_ADC1_DMA=y
|
||||
CONFIG_STM32_ADC1_DMA_CFG=1
|
||||
CONFIG_STM32_ADC_LL_OPS=y
|
||||
CONFIG_STM32_ADC_NOIRQ=y
|
||||
CONFIG_STM32_DMA1=y
|
||||
CONFIG_STM32_JTAG_SW_ENABLE=y
|
||||
CONFIG_STM32_PWM_LL_OPS=y
|
||||
CONFIG_STM32_PWR=y
|
||||
CONFIG_STM32_TIM1=y
|
||||
CONFIG_STM32_TIM1_PWM=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="highpri_main"
|
||||
CONFIG_WDOG_INTRESERVE=0
|
|
@ -238,4 +238,25 @@
|
|||
#define GPIO_TIM2_CH2OUT GPIO_TIM2_CH2OUT_1 /* PA1 */
|
||||
#define GPIO_TIM2_CH3OUT GPIO_TIM2_CH3OUT_1 /* PA9 */
|
||||
|
||||
/* Configuration specific to high priority interrupts example:
|
||||
* - TIM1 CC1 trigger for ADC if DMA transfer and TIM1 PWM
|
||||
* - ADC DMA transfer on DMA1_CH1
|
||||
*/
|
||||
|
||||
#ifdef CONFIG_NUCLEOF302R8_HIGHPRI
|
||||
|
||||
#if defined(CONFIG_STM32_TIM1_PWM) && defined(CONFIG_STM32_ADC1_DMA)
|
||||
|
||||
/* TIM1 - ADC trigger */
|
||||
|
||||
#define ADC1_EXTSEL_VALUE ADC1_EXTSEL_T1CC1
|
||||
|
||||
#endif /* CONFIG_STM32_TIM1_PWM */
|
||||
#endif /* CONFIG_NUCLEOF302R8_HIGHPRI */
|
||||
|
||||
/* DMA channels *************************************************************/
|
||||
/* ADC */
|
||||
|
||||
#define ADC1_DMA_CHAN DMACHAN_ADC1 /* DMA1_CH1 */
|
||||
|
||||
#endif /* __CONFIG_NUCLEO_F302R8_INCLUDE_BOARD_H */
|
||||
|
|
|
@ -86,6 +86,12 @@ SECTIONS
|
|||
|
||||
_eronly = ABSOLUTE(.);
|
||||
|
||||
/* The RAM vector table (if present) should lie at the beginning of SRAM */
|
||||
|
||||
.ram_vectors : {
|
||||
*(.ram_vectors)
|
||||
} > sram
|
||||
|
||||
.data : {
|
||||
_sdata = ABSOLUTE(.);
|
||||
*(.data .data.*)
|
||||
|
|
|
@ -56,4 +56,8 @@ ifeq ($(CONFIG_PWM),y)
|
|||
CSRCS += stm32_pwm.c
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_NUCLEOF302R8_HIGHPRI),y)
|
||||
CSRCS += stm32_highpri.c
|
||||
endif
|
||||
|
||||
include $(TOPDIR)/configs/Board.mk
|
||||
|
|
552
configs/nucleo-f302r8/src/stm32_highpri.c
Normal file
552
configs/nucleo-f302r8/src/stm32_highpri.c
Normal file
|
@ -0,0 +1,552 @@
|
|||
/****************************************************************************
|
||||
* configs/nucleo-f302r8/src/stm32_highpri.c
|
||||
*
|
||||
* Copyright (C) 2018 Gregory Nutt. All rights reserved.
|
||||
* Author: Mateusz Szafoni <raiden00@railab.me>
|
||||
*
|
||||
* 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 <nuttx/config.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <strings.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <nuttx/arch.h>
|
||||
#include <nuttx/signal.h>
|
||||
|
||||
#include <arch/irq.h>
|
||||
#include <arch/chip/chip.h>
|
||||
#include <arch/board/board.h>
|
||||
|
||||
#include "up_internal.h"
|
||||
#include "ram_vectors.h"
|
||||
|
||||
#include <nuttx/drivers/pwm.h>
|
||||
#include <nuttx/analog/adc.h>
|
||||
#include <nuttx/analog/ioctl.h>
|
||||
|
||||
#include "stm32_pwm.h"
|
||||
#include "stm32_adc.h"
|
||||
#include "stm32_dma.h"
|
||||
|
||||
#ifdef CONFIG_NUCLEOF302R8_HIGHPRI
|
||||
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
/* Configuration ************************************************************/
|
||||
|
||||
#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_TIM1_PWM)
|
||||
# define HIGHPRI_HAVE_TIM1
|
||||
# endif
|
||||
# if (CONFIG_STM32_ADC1_DMA_CFG != 1)
|
||||
# error ADC1 DMA must be configured in Circular Mode
|
||||
# endif
|
||||
# if !defined(HIGHPRI_HAVE_TIM1)
|
||||
# error "Needs TIM1 to trigger ADC DMA"
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifdef HIGHPRI_HAVE_TIM1
|
||||
# ifndef ADC1_EXTSEL_VALUE
|
||||
# error ADC1 EXTSEL have to be configured in board.h
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#if (CONFIG_STM32_ADC1_INJECTED_CHAN > 0)
|
||||
# if (CONFIG_STM32_ADC1_INJECTED_CHAN > 2)
|
||||
# error Max 2 injected channels supported for now
|
||||
# else
|
||||
# define HIGHPRI_HAVE_INJECTED
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifdef HIGHPRI_HAVE_INJECTED
|
||||
# define INJ_NCHANNELS CONFIG_STM32_ADC1_INJECTED_CHAN
|
||||
#else
|
||||
# define INJ_NCHANNELS (0)
|
||||
#endif
|
||||
|
||||
#ifndef CONFIG_STM32_ADC1_DMA
|
||||
# define REG_NCHANNELS (1)
|
||||
#else
|
||||
# define REG_NCHANNELS (3)
|
||||
#endif
|
||||
|
||||
#define ADC1_NCHANNELS (REG_NCHANNELS + INJ_NCHANNELS)
|
||||
|
||||
#define DEV1_PORT (1)
|
||||
#define DEV1_NCHANNELS ADC1_NCHANNELS
|
||||
#define ADC_REF_VOLTAGE (3.3f)
|
||||
#define ADC_VAL_MAX (4095)
|
||||
|
||||
/****************************************************************************
|
||||
* Private Types
|
||||
****************************************************************************/
|
||||
|
||||
/* High priority example private data */
|
||||
|
||||
struct highpri_s
|
||||
{
|
||||
FAR struct stm32_adc_dev_s *adc1;
|
||||
#ifdef HIGHPRI_HAVE_TIM1
|
||||
struct stm32_pwm_dev_s *pwm;
|
||||
#endif
|
||||
volatile uint32_t cntr1;
|
||||
volatile uint32_t cntr2;
|
||||
volatile uint8_t current;
|
||||
uint16_t r_val[REG_NCHANNELS];
|
||||
float r_volt[REG_NCHANNELS];
|
||||
#ifdef HIGHPRI_HAVE_INJECTED
|
||||
uint16_t j_val[INJ_NCHANNELS];
|
||||
float j_volt[INJ_NCHANNELS];
|
||||
#endif
|
||||
bool lock;
|
||||
};
|
||||
|
||||
/****************************************************************************
|
||||
* Private Data
|
||||
****************************************************************************/
|
||||
|
||||
/* ADC channel list */
|
||||
|
||||
static const uint8_t g_chanlist1[DEV1_NCHANNELS] =
|
||||
{
|
||||
1,
|
||||
#ifdef CONFIG_STM32_ADC1_DMA
|
||||
2,
|
||||
11,
|
||||
#endif
|
||||
#if INJ_NCHANNELS > 0
|
||||
7,
|
||||
#endif
|
||||
#if INJ_NCHANNELS > 1
|
||||
6
|
||||
#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
|
||||
#if INJ_NCHANNELS > 0
|
||||
GPIO_ADC1_IN7, /* PC1/A4 */
|
||||
#endif
|
||||
#if INJ_NCHANNELS > 1
|
||||
GPIO_ADC1_IN6 /* PC0/A5 */
|
||||
#endif
|
||||
};
|
||||
|
||||
static struct highpri_s g_highpri;
|
||||
|
||||
/****************************************************************************
|
||||
* Private Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: adc12_handler
|
||||
*
|
||||
* Description:
|
||||
* This is the handler for the high speed ADC interrupt.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#if !defined(CONFIG_STM32_ADC1_DMA) || defined(HIGHPRI_HAVE_INJECTED)
|
||||
void adc12_handler(void)
|
||||
{
|
||||
FAR struct stm32_adc_dev_s *adc = g_highpri.adc1;
|
||||
float ref = ADC_REF_VOLTAGE;
|
||||
float bit = ADC_VAL_MAX;
|
||||
uint32_t pending;
|
||||
#ifdef HIGHPRI_HAVE_INJECTED
|
||||
int i = 0;
|
||||
#endif
|
||||
|
||||
/* Get pending ADC interrupts */
|
||||
|
||||
pending = ADC_INT_GET(adc);
|
||||
|
||||
if (g_highpri.lock == true)
|
||||
{
|
||||
goto irq_out;
|
||||
}
|
||||
|
||||
#ifndef CONFIG_STM32_ADC1_DMA
|
||||
/* Regular channel end of conversion */
|
||||
|
||||
if (pending & ADC_ISR_EOC)
|
||||
{
|
||||
/* Increase regular sequence counter */
|
||||
|
||||
g_highpri.cntr1 += 1;
|
||||
|
||||
/* Get regular data */
|
||||
|
||||
g_highpri.r_val[g_highpri.current] = ADC_REGDATA_GET(adc);
|
||||
|
||||
/* Do some floating point operations */
|
||||
|
||||
g_highpri.r_volt[g_highpri.current] = (float)g_highpri.r_val[g_highpri.current] * ref / bit;
|
||||
|
||||
if (g_highpri.current >= REG_NCHANNELS-1)
|
||||
{
|
||||
g_highpri.current = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
g_highpri.current += 1;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef HIGHPRI_HAVE_INJECTED
|
||||
/* Injected channel end of sequence */
|
||||
|
||||
if (pending & ADC_ISR_JEOS)
|
||||
{
|
||||
/* Increase injected sequence counter */
|
||||
|
||||
g_highpri.cntr2 += 1;
|
||||
|
||||
/* Get injected channels */
|
||||
|
||||
for (i = 0; i < INJ_NCHANNELS; i += 1)
|
||||
{
|
||||
g_highpri.j_val[i] = ADC_INJDATA_GET(adc, i);
|
||||
}
|
||||
|
||||
/* Do some floating point operations */
|
||||
|
||||
for (i = 0; i < INJ_NCHANNELS; i += 1)
|
||||
{
|
||||
g_highpri.j_volt[i] = (float)g_highpri.j_val[i] * ref / bit;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
irq_out:
|
||||
/* Clear ADC pending interrupts */
|
||||
|
||||
ADC_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);
|
||||
|
||||
if (g_highpri.lock == true)
|
||||
{
|
||||
goto irq_out;
|
||||
}
|
||||
|
||||
/* Increase regular sequence counter */
|
||||
|
||||
g_highpri.cntr1 += 1;
|
||||
|
||||
for (i = 0; i < REG_NCHANNELS; i += 1)
|
||||
{
|
||||
/* Do some floating point operations */
|
||||
|
||||
g_highpri.r_volt[i] = (float)g_highpri.r_val[i] * ref / bit;
|
||||
}
|
||||
|
||||
irq_out:
|
||||
/* Clear DMA pending interrupts */
|
||||
|
||||
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[])
|
||||
{
|
||||
#ifdef HIGHPRI_HAVE_TIM1
|
||||
struct stm32_pwm_dev_s *pwm1;
|
||||
#endif
|
||||
FAR struct adc_dev_s *adc1;
|
||||
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 */
|
||||
|
||||
adc1 = stm32_adcinitialize(DEV1_PORT, g_chanlist1, DEV1_NCHANNELS);
|
||||
if (adc1 == NULL)
|
||||
{
|
||||
aerr("ERROR: Failed to get ADC interface 1\n");
|
||||
ret = EXIT_FAILURE;
|
||||
goto errout;
|
||||
}
|
||||
|
||||
highpri->adc1 = (struct stm32_adc_dev_s *)adc1->ad_priv;
|
||||
|
||||
#ifdef HIGHPRI_HAVE_TIM1
|
||||
/* Initialize TIM1 */
|
||||
|
||||
pwm1 = (FAR struct stm32_pwm_dev_s *) stm32_pwminitialize(1);
|
||||
if (pwm1 == NULL)
|
||||
{
|
||||
printf("ERROR: Failed to get PWM1 interface\n");
|
||||
ret = EXIT_FAILURE;
|
||||
goto errout;
|
||||
}
|
||||
|
||||
highpri->pwm = pwm1;
|
||||
|
||||
/* Setup PWM device */
|
||||
|
||||
PWM_SETUP(pwm1);
|
||||
|
||||
/* Set timer frequency */
|
||||
|
||||
PWM_FREQ_UPDATE(pwm1, 1000);
|
||||
|
||||
#if ADC1_EXTSEL_VALUE == ADC1_EXTSEL_T1CC1
|
||||
/* Set CCR1 */
|
||||
|
||||
PWM_CCR_UPDATE(pwm1, 1, 0x0f00);
|
||||
|
||||
/* Enable TIM1 CHAN1 */
|
||||
|
||||
PWM_OUTPUTS_ENABLE(pwm1, STM32_CHAN1, true);
|
||||
#else
|
||||
# error T1CC1 only supported for now
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_DEBUG_PWM_INFO
|
||||
/* Print debug */
|
||||
|
||||
PWM_DUMP_REGS(pwm1);
|
||||
#endif
|
||||
|
||||
#endif /* HIGHPRI_HAVE_TIM1 */
|
||||
|
||||
#if !defined(CONFIG_STM32_ADC1_DMA) || defined(HIGHPRI_HAVE_INJECTED)
|
||||
/* Attach ADC12 ram vector if no DMA or injected channels support */
|
||||
|
||||
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);
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_STM32_ADC1_DMA
|
||||
/* 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 */
|
||||
|
||||
adc1->ad_ops->ao_setup(adc1);
|
||||
|
||||
#ifndef CONFIG_STM32_ADC1_DMA
|
||||
/* Enable ADC regular convertion interrupts if no DMA */
|
||||
|
||||
ADC_INT_ENABLE(highpri->adc1, ADC_IER_EOC);
|
||||
#else
|
||||
/* Register ADC buffer for DMA transfer */
|
||||
|
||||
ADC_REGBUF_REGISTER(highpri->adc1, g_highpri.r_val, REG_NCHANNELS);
|
||||
#endif
|
||||
|
||||
#ifdef HIGHPRI_HAVE_INJECTED
|
||||
/* Enable ADC injected sequence end interrupts */
|
||||
|
||||
ADC_INT_ENABLE(highpri->adc1, ADC_IER_JEOS);
|
||||
#endif
|
||||
|
||||
#ifdef HIGHPRI_HAVE_TIM1
|
||||
/* Enable timer counter after ADC configuration */
|
||||
|
||||
PWM_TIM_ENABLE(pwm1, true);
|
||||
#endif
|
||||
|
||||
while(1)
|
||||
{
|
||||
#ifndef CONFIG_STM32_ADC1_DMA
|
||||
/* Software trigger for regular sequence */
|
||||
|
||||
adc1->ad_ops->ao_ioctl(adc1, IO_TRIGGER_REG, 0);
|
||||
|
||||
usleep(100);
|
||||
#endif
|
||||
|
||||
#ifdef HIGHPRI_HAVE_INJECTED
|
||||
/* Software trigger for injected sequence */
|
||||
|
||||
adc1->ad_ops->ao_ioctl(adc1, IO_TRIGGER_INJ, 0);
|
||||
|
||||
usleep(100);
|
||||
#endif
|
||||
/* Lock global data */
|
||||
|
||||
g_highpri.lock = true;
|
||||
|
||||
#ifndef CONFIG_STM32_ADC1_DMA
|
||||
printf("%d [%d] %0.3fV\n", g_highpri.cntr1, g_highpri.current,
|
||||
g_highpri.r_volt[g_highpri.current]);
|
||||
#else
|
||||
printf("%d ", g_highpri.cntr1);
|
||||
|
||||
for (i = 0; i < REG_NCHANNELS; i += 1)
|
||||
{
|
||||
printf("r:[%d] %0.3fV, ", i, g_highpri.r_volt[i]);
|
||||
}
|
||||
|
||||
printf("\n");
|
||||
#endif
|
||||
|
||||
#ifdef HIGHPRI_HAVE_INJECTED
|
||||
/* Print data from injected channels */
|
||||
|
||||
printf("%d ", g_highpri.cntr2);
|
||||
|
||||
for (i = 0; i < INJ_NCHANNELS; i += 1)
|
||||
{
|
||||
printf("j:[%d] %0.3fV, ", i, g_highpri.j_volt[i]);
|
||||
}
|
||||
|
||||
printf("\n");
|
||||
#endif
|
||||
/* Unlock global data */
|
||||
|
||||
g_highpri.lock = false;
|
||||
|
||||
sleep(1);
|
||||
}
|
||||
|
||||
errout:
|
||||
return ret;
|
||||
}
|
||||
|
||||
#endif /* CONFIG_NUCLEOF302R8_HIGHPRI */
|
|
@ -13,6 +13,7 @@ CONFIG_ARCH_STACKDUMP=y
|
|||
CONFIG_BOARD_LOOPSPERMSEC=6522
|
||||
CONFIG_DISABLE_POLL=y
|
||||
CONFIG_EXAMPLES_ADC=y
|
||||
CONFIG_EXAMPLES_ADC_GROUPSIZE=3
|
||||
CONFIG_EXAMPLES_ADC_SWTRIG=y
|
||||
CONFIG_IDLETHREAD_STACKSIZE=2048
|
||||
CONFIG_INTELHEX_BINARY=y
|
||||
|
|
|
@ -22,6 +22,7 @@ CONFIG_DISABLE_POSIX_TIMERS=y
|
|||
CONFIG_DISABLE_PTHREAD=y
|
||||
CONFIG_DISABLE_SIGNALS=y
|
||||
CONFIG_EXAMPLES_ADC=y
|
||||
CONFIG_EXAMPLES_ADC_GROUPSIZE=3
|
||||
CONFIG_EXAMPLES_ADC_SWTRIG=y
|
||||
CONFIG_FDCLONE_STDIO=y
|
||||
CONFIG_INTELHEX_BINARY=y
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
# CONFIG_DEV_NULL is not set
|
||||
# CONFIG_LIBC_LONG_LONG is not set
|
||||
# CONFIG_NSH_DISABLE_PRINTF is not set
|
||||
CONFIG_ADC=y
|
||||
CONFIG_ANALOG=y
|
||||
CONFIG_ARCH="arm"
|
||||
|
@ -19,58 +18,16 @@ CONFIG_DISABLE_ENVIRON=y
|
|||
CONFIG_DISABLE_MQUEUE=y
|
||||
CONFIG_DISABLE_POLL=y
|
||||
CONFIG_DISABLE_POSIX_TIMERS=y
|
||||
CONFIG_SYSTEM_NSH=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_NSH_ARCHINIT=y
|
||||
CONFIG_NSH_BUILTIN_APPS=y
|
||||
CONFIG_NSH_DISABLE_BASENAME=y
|
||||
CONFIG_NSH_DISABLE_CAT=y
|
||||
CONFIG_NSH_DISABLE_CD=y
|
||||
CONFIG_NSH_DISABLE_CMP=y
|
||||
CONFIG_NSH_DISABLE_CP=y
|
||||
CONFIG_NSH_DISABLE_DD=y
|
||||
CONFIG_NSH_DISABLE_DF=y
|
||||
CONFIG_NSH_DISABLE_DIRNAME=y
|
||||
CONFIG_NSH_DISABLE_EXEC=y
|
||||
CONFIG_NSH_DISABLE_EXIT=y
|
||||
CONFIG_NSH_DISABLE_GET=y
|
||||
CONFIG_NSH_DISABLE_HEXDUMP=y
|
||||
CONFIG_NSH_DISABLE_KILL=y
|
||||
CONFIG_NSH_DISABLE_LOSETUP=y
|
||||
CONFIG_NSH_DISABLE_LS=y
|
||||
CONFIG_NSH_DISABLE_MB=y
|
||||
CONFIG_NSH_DISABLE_MH=y
|
||||
CONFIG_NSH_DISABLE_MKDIR=y
|
||||
CONFIG_NSH_DISABLE_MKRD=y
|
||||
CONFIG_NSH_DISABLE_MOUNT=y
|
||||
CONFIG_NSH_DISABLE_MV=y
|
||||
CONFIG_NSH_DISABLE_MW=y
|
||||
CONFIG_NSH_DISABLE_PUT=y
|
||||
CONFIG_NSH_DISABLE_PWD=y
|
||||
CONFIG_NSH_DISABLE_RM=y
|
||||
CONFIG_NSH_DISABLE_RMDIR=y
|
||||
CONFIG_NSH_DISABLE_SET=y
|
||||
CONFIG_NSH_DISABLE_SH=y
|
||||
CONFIG_NSH_DISABLE_SLEEP=y
|
||||
CONFIG_NSH_DISABLE_TEST=y
|
||||
CONFIG_NSH_DISABLE_TIME=y
|
||||
CONFIG_NSH_DISABLE_UMOUNT=y
|
||||
CONFIG_NSH_DISABLE_UNAME=y
|
||||
CONFIG_NSH_DISABLE_UNSET=y
|
||||
CONFIG_NSH_DISABLE_USLEEP=y
|
||||
CONFIG_NSH_DISABLE_WGET=y
|
||||
CONFIG_NSH_DISABLE_XD=y
|
||||
CONFIG_NSH_FILEIOSIZE=256
|
||||
CONFIG_NSH_LINELEN=64
|
||||
CONFIG_NSH_READLINE=y
|
||||
CONFIG_NUCLEOF334R8_HIGHPRI=y
|
||||
CONFIG_POSIX_SPAWN_PROXY_STACKSIZE=512
|
||||
CONFIG_PREALLOC_TIMERS=2
|
||||
|
@ -88,6 +45,9 @@ CONFIG_START_MONTH=12
|
|||
CONFIG_START_YEAR=2011
|
||||
CONFIG_STM32_ADC1=y
|
||||
CONFIG_STM32_ADC1_DMA=y
|
||||
CONFIG_STM32_ADC1_DMA_CFG=1
|
||||
CONFIG_STM32_ADC1_INJECTED_CHAN=1
|
||||
CONFIG_STM32_ADC_LL_OPS=y
|
||||
CONFIG_STM32_ADC_NOIRQ=y
|
||||
CONFIG_STM32_DMA1=y
|
||||
CONFIG_STM32_HRTIM1=y
|
||||
|
@ -95,10 +55,12 @@ CONFIG_STM32_HRTIM_ADC1_TRG1=y
|
|||
CONFIG_STM32_HRTIM_ADC=y
|
||||
CONFIG_STM32_HRTIM_CLK_FROM_PLL=y
|
||||
CONFIG_STM32_HRTIM_DISABLE_CHARDRV=y
|
||||
CONFIG_STM32_HRTIM_NO_ENABLE_TIMERS=y
|
||||
CONFIG_STM32_HRTIM_TIMA=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
|
||||
|
|
|
@ -250,24 +250,38 @@
|
|||
#define OPAMP2_VPSEL OPAMP2_VPSEL_PB14
|
||||
|
||||
/* Configuration specific to high priority interrupts example:
|
||||
* - HRTIM Timer A trigger for ADC if DMA transfer
|
||||
* - HRTIM Timer A trigger for ADC if DMA transfer and HRTIM
|
||||
* - TIM1 CC1 trigger for ADC if DMA transfer and TIM1 PWM
|
||||
* - ADC DMA transfer on DMA1_CH1
|
||||
*/
|
||||
|
||||
#ifdef CONFIG_NUCLEOF334R8_HIGHPRI
|
||||
|
||||
/* HRTIM */
|
||||
#if defined(CONFIG_STM32_HRTIM1) && defined(CONFIG_STM32_ADC1_DMA)
|
||||
|
||||
/* HRTIM - ADC trigger */
|
||||
|
||||
#define HRTIM_TIMA_PRESCALER HRTIM_PRESCALER_128
|
||||
#define HRTIM_TIMA_MODE HRTIM_MODE_CONT
|
||||
#define HRTIM_TIMA_UPDATE 0
|
||||
#define HRTIM_TIMA_RESET 0
|
||||
|
||||
#define HRTIM_ADC_TRG1 HRTIM_ADCTRG13_APER
|
||||
|
||||
#endif /* CONFIG_STM32_HRTIM1 && CONFIG_STM32_ADC1_DMA*/
|
||||
|
||||
#if defined(CONFIG_STM32_TIM1_PWM) && defined(CONFIG_STM32_ADC1_DMA)
|
||||
|
||||
/* TIM1 - ADC trigger */
|
||||
|
||||
#define ADC1_EXTSEL_VALUE ADC1_EXTSEL_T1CC1
|
||||
|
||||
#endif /* CONFIG_STM32_TIM1_PWM && CONFIG_STM32_ADC1_DMA */
|
||||
#endif /* CONFIG_NUCLEOF334R8_HIGHPRI */
|
||||
|
||||
/* DMA channels *************************************************************/
|
||||
/* ADC */
|
||||
|
||||
#define ADC1_DMA_CHAN DMACHAN_ADC1 /* DMA1_CH1 */
|
||||
|
||||
#endif /* CONFIG_NUCLEOF334R8_HIGHPRI */
|
||||
|
||||
#endif /* __CONFIG_NUCLEO_F334R8_INCLUDE_BOARD_H */
|
||||
|
|
|
@ -96,7 +96,6 @@ int board_app_initialize(uintptr_t arg)
|
|||
{
|
||||
int ret;
|
||||
|
||||
#ifndef CONFIG_NUCLEOF334R8_HIGHPRI
|
||||
#ifdef HAVE_LEDS
|
||||
/* Register the LED driver */
|
||||
|
||||
|
@ -146,7 +145,6 @@ int board_app_initialize(uintptr_t arg)
|
|||
{
|
||||
syslog(LOG_ERR, "ERROR: stm32_opamp_setup failed: %d\n", ret);
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
UNUSED(ret);
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/****************************************************************************
|
||||
* configs/nucleo-f334r8/src/stm32_highpri.c
|
||||
*
|
||||
* Copyright (C) 2017 Gregory Nutt. All rights reserved.
|
||||
* Copyright (C) 2018 Gregory Nutt. All rights reserved.
|
||||
* Author: Mateusz Szafoni <raiden00@railab.me>
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
|
@ -54,10 +54,12 @@
|
|||
#include "up_internal.h"
|
||||
#include "ram_vectors.h"
|
||||
|
||||
#include <nuttx/drivers/pwm.h>
|
||||
#include <nuttx/analog/adc.h>
|
||||
#include <nuttx/analog/ioctl.h>
|
||||
|
||||
#include "stm32_hrtim.h"
|
||||
#include "stm32_pwm.h"
|
||||
#include "stm32_adc.h"
|
||||
#include "stm32_dma.h"
|
||||
|
||||
|
@ -68,10 +70,6 @@
|
|||
****************************************************************************/
|
||||
/* 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
|
||||
|
@ -89,21 +87,60 @@
|
|||
#endif
|
||||
|
||||
#ifdef CONFIG_STM32_ADC1_DMA
|
||||
# if !defined(CONFIG_STM32_HRTIM1) || !defined(CONFIG_STM32_HRTIM_TIMA)
|
||||
# error "Needs HRTIM TIMA to trigger ADC"
|
||||
# if defined(CONFIG_STM32_HRTIM1) && defined(CONFIG_STM32_HRTIM_TIMA)
|
||||
# define HIGHPRI_HAVE_HRTIM
|
||||
# endif
|
||||
# if defined(CONFIG_STM32_TIM1_PWM)
|
||||
# define HIGHPRI_HAVE_TIM1
|
||||
# endif
|
||||
# if (CONFIG_STM32_ADC1_DMA_CFG != 1)
|
||||
# error ADC1 DMA must be configured in Circular Mode
|
||||
# endif
|
||||
# if defined(HIGHPRI_HAVE_HRTIM) && defined(HIGHPRI_HAVE_TIM1)
|
||||
# error HRTIM TIM A or TIM1 !
|
||||
# elif !defined(HIGHPRI_HAVE_HRTIM) && !defined(HIGHPRI_HAVE_TIM1)
|
||||
# error "Needs HRTIM TIMA or TIM1 to trigger ADC DMA"
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifndef CONFIG_STM32_ADC1_DMA
|
||||
# define ADC1_NCHANNELS 1
|
||||
#else
|
||||
# define ADC1_NCHANNELS 3
|
||||
#ifdef HIGHPRI_HAVE_HRTIM
|
||||
# if !defined(CONFIG_STM32_HRTIM_ADC1_TRG1) || !defined(CONFIG_STM32_HRTIM_ADC)
|
||||
# error
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#define DEV1_PORT 1
|
||||
#ifdef HIGHPRI_HAVE_TIM1
|
||||
# ifndef ADC1_EXTSEL_VALUE
|
||||
# error ADC1 EXTSEL have to be configured in board.h
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#if (CONFIG_STM32_ADC1_INJECTED_CHAN > 0)
|
||||
# if (CONFIG_STM32_ADC1_INJECTED_CHAN > 2)
|
||||
# error Max 2 injected channels supported for now
|
||||
# else
|
||||
# define HIGHPRI_HAVE_INJECTED
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifdef HIGHPRI_HAVE_INJECTED
|
||||
# define INJ_NCHANNELS CONFIG_STM32_ADC1_INJECTED_CHAN
|
||||
#else
|
||||
# define INJ_NCHANNELS (0)
|
||||
#endif
|
||||
|
||||
#ifndef CONFIG_STM32_ADC1_DMA
|
||||
# define REG_NCHANNELS (1)
|
||||
#else
|
||||
# define REG_NCHANNELS (3)
|
||||
#endif
|
||||
|
||||
#define ADC1_NCHANNELS (REG_NCHANNELS + INJ_NCHANNELS)
|
||||
|
||||
#define DEV1_PORT (1)
|
||||
#define DEV1_NCHANNELS ADC1_NCHANNELS
|
||||
#define ADC_REF_VOLTAGE 3.3
|
||||
#define ADC_VAL_MAX 4095
|
||||
#define ADC_REF_VOLTAGE (3.3f)
|
||||
#define ADC_VAL_MAX (4095)
|
||||
|
||||
/****************************************************************************
|
||||
* Private Types
|
||||
|
@ -113,14 +150,23 @@
|
|||
|
||||
struct highpri_s
|
||||
{
|
||||
FAR struct stm32_adc_dev_s *adc;
|
||||
#ifdef CONFIG_STM32_ADC1_DMA
|
||||
FAR struct stm32_adc_dev_s *adc1;
|
||||
#ifdef HIGHPRI_HAVE_HRTIM
|
||||
FAR struct hrtim_dev_s *hrtim;
|
||||
#endif
|
||||
volatile uint32_t cntr;
|
||||
#ifdef HIGHPRI_HAVE_TIM1
|
||||
struct stm32_pwm_dev_s *pwm;
|
||||
#endif
|
||||
volatile uint32_t cntr1;
|
||||
volatile uint32_t cntr2;
|
||||
volatile uint8_t current;
|
||||
uint16_t val[DEV1_NCHANNELS];
|
||||
float volt[DEV1_NCHANNELS];
|
||||
uint16_t r_val[REG_NCHANNELS];
|
||||
float r_volt[REG_NCHANNELS];
|
||||
#ifdef HIGHPRI_HAVE_INJECTED
|
||||
uint16_t j_val[INJ_NCHANNELS];
|
||||
float j_volt[INJ_NCHANNELS];
|
||||
#endif
|
||||
bool lock;
|
||||
};
|
||||
|
||||
/****************************************************************************
|
||||
|
@ -134,7 +180,13 @@ static const uint8_t g_chanlist1[DEV1_NCHANNELS] =
|
|||
1,
|
||||
#ifdef CONFIG_STM32_ADC1_DMA
|
||||
2,
|
||||
11
|
||||
11,
|
||||
#endif
|
||||
#if INJ_NCHANNELS > 0
|
||||
7,
|
||||
#endif
|
||||
#if INJ_NCHANNELS > 1
|
||||
6
|
||||
#endif
|
||||
};
|
||||
|
||||
|
@ -143,11 +195,16 @@ static const uint8_t g_chanlist1[DEV1_NCHANNELS] =
|
|||
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
|
||||
#if INJ_NCHANNELS > 0
|
||||
GPIO_ADC1_IN7, /* PC1/A4 */
|
||||
#endif
|
||||
#if INJ_NCHANNELS > 1
|
||||
GPIO_ADC1_IN6 /* PC0/A5 */
|
||||
#endif
|
||||
};
|
||||
|
||||
static struct highpri_s g_highpri;
|
||||
|
@ -164,27 +221,44 @@ static struct highpri_s g_highpri;
|
|||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef CONFIG_STM32_ADC1_DMA
|
||||
#if !defined(CONFIG_STM32_ADC1_DMA) || defined(HIGHPRI_HAVE_INJECTED)
|
||||
void adc12_handler(void)
|
||||
{
|
||||
FAR struct stm32_adc_dev_s *adc = g_highpri.adc;
|
||||
FAR struct stm32_adc_dev_s *adc = g_highpri.adc1;
|
||||
float ref = ADC_REF_VOLTAGE;
|
||||
float bit = ADC_VAL_MAX;
|
||||
uint32_t pending;
|
||||
#ifdef HIGHPRI_HAVE_INJECTED
|
||||
int i = 0;
|
||||
#endif
|
||||
|
||||
g_highpri.cntr += 1;
|
||||
/* Get pending ADC interrupts */
|
||||
|
||||
pending = adc->ops->int_get(adc);
|
||||
pending = ADC_INT_GET(adc);
|
||||
|
||||
if (pending & ADC_INT_EOC)
|
||||
if (g_highpri.lock == true)
|
||||
{
|
||||
g_highpri.val[g_highpri.current] = adc->ops->val_get(adc);
|
||||
goto irq_out;
|
||||
}
|
||||
|
||||
#ifndef CONFIG_STM32_ADC1_DMA
|
||||
/* Regular channel end of conversion */
|
||||
|
||||
if (pending & ADC_ISR_EOC)
|
||||
{
|
||||
/* Increase regular sequence counter */
|
||||
|
||||
g_highpri.cntr1 += 1;
|
||||
|
||||
/* Get regular data */
|
||||
|
||||
g_highpri.r_val[g_highpri.current] = ADC_REGDATA_GET(adc);
|
||||
|
||||
/* Do some floating point operations */
|
||||
|
||||
g_highpri.volt[g_highpri.current] = (float)g_highpri.val[g_highpri.current] * ref / bit;
|
||||
g_highpri.r_volt[g_highpri.current] = (float)g_highpri.r_val[g_highpri.current] * ref / bit;
|
||||
|
||||
if (g_highpri.current >= DEV1_NCHANNELS-1)
|
||||
if (g_highpri.current >= REG_NCHANNELS-1)
|
||||
{
|
||||
g_highpri.current = 0;
|
||||
}
|
||||
|
@ -193,8 +267,37 @@ void adc12_handler(void)
|
|||
g_highpri.current += 1;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
adc->ops->int_ack(adc, pending);
|
||||
#ifdef HIGHPRI_HAVE_INJECTED
|
||||
/* Injected channel end of sequence */
|
||||
|
||||
if (pending & ADC_ISR_JEOS)
|
||||
{
|
||||
/* Increase injected sequence counter */
|
||||
|
||||
g_highpri.cntr2 += 1;
|
||||
|
||||
/* Get injected channels */
|
||||
|
||||
for (i = 0; i < INJ_NCHANNELS; i += 1)
|
||||
{
|
||||
g_highpri.j_val[i] = ADC_INJDATA_GET(adc, i);
|
||||
}
|
||||
|
||||
/* Do some floating point operations */
|
||||
|
||||
for (i = 0; i < INJ_NCHANNELS; i += 1)
|
||||
{
|
||||
g_highpri.j_volt[i] = (float)g_highpri.j_val[i] * ref / bit;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
irq_out:
|
||||
/* Clear ADC pending interrupts */
|
||||
|
||||
ADC_INT_ACK(adc, pending);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -216,15 +319,25 @@ void dma1ch1_handler(void)
|
|||
|
||||
pending = stm32_dma_intget(STM32_DMA1_CHAN1);
|
||||
|
||||
g_highpri.cntr += 1;
|
||||
if (g_highpri.lock == true)
|
||||
{
|
||||
goto irq_out;
|
||||
}
|
||||
|
||||
for (i = 0; i < 3; i += 1)
|
||||
/* Increase regular sequence counter */
|
||||
|
||||
g_highpri.cntr1 += 1;
|
||||
|
||||
for (i = 0; i < REG_NCHANNELS; i += 1)
|
||||
{
|
||||
/* Do some floating point operations */
|
||||
|
||||
g_highpri.volt[i] = (float)g_highpri.val[i] * ref / bit;
|
||||
g_highpri.r_volt[i] = (float)g_highpri.r_val[i] * ref / bit;
|
||||
}
|
||||
|
||||
irq_out:
|
||||
/* Clear DMA pending interrupts */
|
||||
|
||||
stm32_dma_intack(STM32_DMA1_CHAN1, pending);
|
||||
}
|
||||
#endif
|
||||
|
@ -243,10 +356,13 @@ void dma1ch1_handler(void)
|
|||
|
||||
int highpri_main(int argc, char *argv[])
|
||||
{
|
||||
#ifdef CONFIG_STM32_ADC1_DMA
|
||||
#ifdef HIGHPRI_HAVE_HRTIM
|
||||
FAR struct hrtim_dev_s *hrtim;
|
||||
#endif
|
||||
FAR struct adc_dev_s *adc;
|
||||
#ifdef HIGHPRI_HAVE_TIM1
|
||||
struct stm32_pwm_dev_s *pwm1;
|
||||
#endif
|
||||
FAR struct adc_dev_s *adc1;
|
||||
FAR struct highpri_s *highpri;
|
||||
int ret;
|
||||
int i;
|
||||
|
@ -268,17 +384,17 @@ int highpri_main(int argc, char *argv[])
|
|||
|
||||
/* Initialize ADC driver */
|
||||
|
||||
adc = stm32_adcinitialize(DEV1_PORT, g_chanlist1, DEV1_NCHANNELS);
|
||||
if (adc == NULL)
|
||||
adc1 = stm32_adcinitialize(DEV1_PORT, g_chanlist1, DEV1_NCHANNELS);
|
||||
if (adc1 == 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;
|
||||
highpri->adc1 = (struct stm32_adc_dev_s *)adc1->ad_priv;
|
||||
|
||||
#ifdef CONFIG_STM32_ADC1_DMA
|
||||
#ifdef HIGHPRI_HAVE_HRTIM
|
||||
/* Configure HRTIM */
|
||||
|
||||
hrtim = stm32_hrtiminitialize();
|
||||
|
@ -294,11 +410,51 @@ int highpri_main(int argc, char *argv[])
|
|||
/* Set Timer A Period */
|
||||
|
||||
HRTIM_PER_SET(hrtim, HRTIM_TIMER_TIMA, 0xFFD0);
|
||||
#endif /* HIGHPRI_HAVE_HRTIM */
|
||||
|
||||
#ifdef HIGHPRI_HAVE_TIM1
|
||||
/* Initialize TIM1 */
|
||||
|
||||
pwm1 = (FAR struct stm32_pwm_dev_s *) stm32_pwminitialize(1);
|
||||
if (pwm1 == NULL)
|
||||
{
|
||||
printf("ERROR: Failed to get PWM1 interface\n");
|
||||
ret = EXIT_FAILURE;
|
||||
goto errout;
|
||||
}
|
||||
|
||||
highpri->pwm = pwm1;
|
||||
|
||||
/* Setup PWM device */
|
||||
|
||||
PWM_SETUP(pwm1);
|
||||
|
||||
/* Set timer frequency */
|
||||
|
||||
PWM_FREQ_UPDATE(pwm1, 1000);
|
||||
|
||||
#if ADC1_EXTSEL_VALUE == ADC1_EXTSEL_T1CC1
|
||||
/* Set CCR1 */
|
||||
|
||||
PWM_CCR_UPDATE(pwm1, 1, 0x0f00);
|
||||
|
||||
/* Enable TIM1 CHAN1 */
|
||||
|
||||
PWM_OUTPUTS_ENABLE(pwm1, STM32_CHAN1, true);
|
||||
#else
|
||||
# error T1CC1 only supported for now
|
||||
#endif
|
||||
|
||||
#ifndef CONFIG_STM32_ADC1_DMA
|
||||
#ifdef CONFIG_DEBUG_PWM_INFO
|
||||
/* Print debug */
|
||||
|
||||
/* Attach ADC12 ram vector if no DMA */
|
||||
PWM_DUMP_REGS(pwm1);
|
||||
#endif
|
||||
|
||||
#endif /* HIGHPRI_HAVE_TIM1 */
|
||||
|
||||
#if !defined(CONFIG_STM32_ADC1_DMA) || defined(HIGHPRI_HAVE_INJECTED)
|
||||
/* Attach ADC12 ram vector if no DMA or injected channels support */
|
||||
|
||||
ret = up_ramvec_attach(STM32_IRQ_ADC12, adc12_handler);
|
||||
if (ret < 0)
|
||||
|
@ -319,8 +475,9 @@ int highpri_main(int argc, char *argv[])
|
|||
}
|
||||
|
||||
up_enable_irq(STM32_IRQ_ADC12);
|
||||
#else
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_STM32_ADC1_DMA
|
||||
/* Attach DMA1 CH1 ram vector if DMA */
|
||||
|
||||
ret = up_ramvec_attach(STM32_IRQ_DMA1CH1, dma1ch1_handler);
|
||||
|
@ -346,39 +503,87 @@ int highpri_main(int argc, char *argv[])
|
|||
|
||||
/* Setup ADC hardware */
|
||||
|
||||
adc->ad_ops->ao_setup(adc);
|
||||
adc1->ad_ops->ao_setup(adc1);
|
||||
|
||||
#ifndef CONFIG_STM32_ADC1_DMA
|
||||
/* Enable ADC interrupts if no DMA */
|
||||
/* Enable ADC regular convertion interrupts if no DMA */
|
||||
|
||||
highpri->adc->ops->int_en(highpri->adc, ADC_INT_EOC);
|
||||
ADC_INT_ENABLE(highpri->adc1, ADC_IER_EOC);
|
||||
#else
|
||||
/* Register ADC buffer for DMA transfer */
|
||||
|
||||
highpri->adc->ops->regbuf_reg(highpri->adc, g_highpri.val, 3);
|
||||
ADC_REGBUF_REGISTER(highpri->adc1, g_highpri.r_val, REG_NCHANNELS);
|
||||
#endif
|
||||
|
||||
#ifdef HIGHPRI_HAVE_INJECTED
|
||||
/* Enable ADC injected sequence end interrupts */
|
||||
|
||||
ADC_INT_ENABLE(highpri->adc1, ADC_IER_JEOS);
|
||||
#endif
|
||||
|
||||
#ifdef HIGHPRI_HAVE_HRTIM
|
||||
/* Enable HRTIM TIMA after ADC configuration */
|
||||
|
||||
HRTIM_TIM_ENABLE(highpri->hrtim, HRTIM_TIMER_TIMA, true);
|
||||
#endif
|
||||
|
||||
#ifdef HIGHPRI_HAVE_TIM1
|
||||
/* Enable timer counter after ADC configuration */
|
||||
|
||||
PWM_TIM_ENABLE(pwm1, true);
|
||||
#endif
|
||||
|
||||
while(1)
|
||||
{
|
||||
#ifndef CONFIG_STM32_ADC1_DMA
|
||||
/* Software triger */
|
||||
/* Software trigger for regular sequence */
|
||||
|
||||
adc->ad_ops->ao_ioctl(adc, ANIOC_TRIGGER, 0);
|
||||
adc1->ad_ops->ao_ioctl(adc1, IO_TRIGGER_REG, 0);
|
||||
|
||||
usleep(100);
|
||||
#endif
|
||||
|
||||
printf("%d [%d] %0.3fV\n", g_highpri.cntr, g_highpri.current,
|
||||
g_highpri.volt[g_highpri.current]);
|
||||
#ifdef HIGHPRI_HAVE_INJECTED
|
||||
/* Software trigger for injected sequence */
|
||||
|
||||
adc1->ad_ops->ao_ioctl(adc1, IO_TRIGGER_INJ, 0);
|
||||
|
||||
usleep(100);
|
||||
#endif
|
||||
/* Lock global data */
|
||||
|
||||
g_highpri.lock = true;
|
||||
|
||||
#ifndef CONFIG_STM32_ADC1_DMA
|
||||
printf("%d [%d] %0.3fV\n", g_highpri.cntr1, g_highpri.current,
|
||||
g_highpri.r_volt[g_highpri.current]);
|
||||
#else
|
||||
printf("%d ", g_highpri.cntr);
|
||||
printf("%d ", g_highpri.cntr1);
|
||||
|
||||
for (i = 0; i < DEV1_NCHANNELS; i += 1)
|
||||
for (i = 0; i < REG_NCHANNELS; i += 1)
|
||||
{
|
||||
printf("[%d] %0.3fV, ", i, g_highpri.volt[i]);
|
||||
printf("r:[%d] %0.3fV, ", i, g_highpri.r_volt[i]);
|
||||
}
|
||||
|
||||
printf("\n");
|
||||
#endif
|
||||
|
||||
#ifdef HIGHPRI_HAVE_INJECTED
|
||||
/* Print data from injected channels */
|
||||
|
||||
printf("%d ", g_highpri.cntr2);
|
||||
|
||||
for (i = 0; i < INJ_NCHANNELS; i += 1)
|
||||
{
|
||||
printf("j:[%d] %0.3fV, ", i, g_highpri.j_volt[i]);
|
||||
}
|
||||
|
||||
printf("\n");
|
||||
#endif
|
||||
/* Unlock global data */
|
||||
|
||||
g_highpri.lock = false;
|
||||
|
||||
sleep(1);
|
||||
}
|
||||
|
||||
|
|
|
@ -104,7 +104,9 @@ CONFIG_START_MONTH=12
|
|||
CONFIG_START_YEAR=2011
|
||||
CONFIG_STDIO_BUFFER_SIZE=128
|
||||
CONFIG_STM32_ADC1=y
|
||||
CONFIG_STM32_ADC1_INJECTED=y
|
||||
CONFIG_STM32_ADC1_INJECTED_CHAN=2
|
||||
CONFIG_STM32_ADC_CHANGE_SAMPLETIME=y
|
||||
CONFIG_STM32_ADC_LL_OPS=y
|
||||
CONFIG_STM32_ADC_NOIRQ=y
|
||||
CONFIG_STM32_CCMEXCLUDE=y
|
||||
CONFIG_STM32_HRTIM1=y
|
||||
|
|
|
@ -268,13 +268,6 @@
|
|||
|
||||
#if defined(CONFIG_EXAMPLES_SMPS)
|
||||
|
||||
/* ADC configuration ******************************************************/
|
||||
|
||||
#define ADC1_INJECTED_CHAN 2
|
||||
#define ADC1_EXTSEL_VALUE 0
|
||||
#define ADC1_SMP2 ADC_SMPR_61p5
|
||||
#define ADC1_SMP4 ADC_SMPR_61p5
|
||||
|
||||
/* HRTIM configuration ******************************************************/
|
||||
|
||||
/* Timer A configuration - Buck operations */
|
||||
|
|
|
@ -206,7 +206,7 @@ enum converter_mode_e
|
|||
struct smps_lower_dev_s
|
||||
{
|
||||
FAR struct hrtim_dev_s *hrtim; /* PWM generation */
|
||||
FAR struct adc_dev_s *adc; /* input and output voltage sense */
|
||||
FAR struct stm32_adc_dev_s *adc; /* input and output voltage sense */
|
||||
FAR struct comp_dev_s *comp; /* not used in this demo - only as reference */
|
||||
FAR struct dac_dev_s *dac; /* not used in this demo - only as reference */
|
||||
FAR struct opamp_dev_s *opamp; /* not used in this demo - only as reference */
|
||||
|
@ -360,8 +360,12 @@ static int smps_setup(FAR struct smps_dev_s *dev)
|
|||
FAR struct smps_lower_dev_s *lower = dev->lower;
|
||||
FAR struct smps_s *smps = (FAR struct smps_s *)dev->priv;
|
||||
FAR struct hrtim_dev_s *hrtim = NULL;
|
||||
FAR struct adc_dev_s *adc = NULL;
|
||||
FAR struct stm32_adc_dev_s *adc = NULL;
|
||||
FAR struct smps_priv_s *priv;
|
||||
struct adc_channel_s channels[ADC1_NCHANNELS];
|
||||
struct adc_sample_time_s stime;
|
||||
int ret = OK;
|
||||
int i = 0;
|
||||
|
||||
/* Initialize smps structure */
|
||||
|
||||
|
@ -375,28 +379,49 @@ static int smps_setup(FAR struct smps_dev_s *dev)
|
|||
if (hrtim == NULL)
|
||||
{
|
||||
pwrerr("ERROR: Failed to get hrtim ");
|
||||
ret = ERROR;
|
||||
goto errout;
|
||||
}
|
||||
|
||||
adc = lower->adc;
|
||||
if (adc == NULL)
|
||||
{
|
||||
pwrerr("ERROR: Failed to get ADC lower level interface");
|
||||
ret = ERROR;
|
||||
goto errout;
|
||||
}
|
||||
|
||||
/* Update ADC sample time */
|
||||
|
||||
for (i = 0; i < ADC1_NCHANNELS; i+= 1)
|
||||
{
|
||||
channels[i].sample_time = ADC_SMPR_61p5;
|
||||
channels[i].channel = g_adc1chan[i];
|
||||
}
|
||||
|
||||
memset(&stime, 0, sizeof(struct adc_sample_time_s));
|
||||
|
||||
stime.channels_nbr = ADC1_NCHANNELS;
|
||||
stime.channel = channels;
|
||||
|
||||
ADC_SAMPLETIME_SET(adc, &stime);
|
||||
ADC_SAMPLETIME_WRITE(adc);
|
||||
|
||||
/* TODO: create current limit table */
|
||||
|
||||
UNUSED(priv);
|
||||
return OK;
|
||||
|
||||
errout:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int smps_start(FAR struct smps_dev_s *dev)
|
||||
{
|
||||
FAR struct smps_lower_dev_s *lower = dev->lower;
|
||||
FAR struct stm32_adc_dev_s *stm32_adc =
|
||||
(FAR struct stm32_adc_dev_s *) lower->adc->ad_priv;
|
||||
FAR struct smps_s *smps = (FAR struct smps_s *)dev->priv;
|
||||
FAR struct smps_priv_s *priv = (struct smps_priv_s *)smps->priv;
|
||||
FAR struct hrtim_dev_s *hrtim = lower->hrtim;
|
||||
FAR struct smps_s *smps = (FAR struct smps_s *)dev->priv;
|
||||
FAR struct smps_priv_s *priv = (struct smps_priv_s *)smps->priv;
|
||||
FAR struct hrtim_dev_s *hrtim = lower->hrtim;
|
||||
FAR struct stm32_adc_dev_s *adc = lower->adc;
|
||||
volatile uint64_t per = 0;
|
||||
uint64_t fclk = 0;
|
||||
int ret = OK;
|
||||
|
@ -482,9 +507,17 @@ static int smps_start(FAR struct smps_dev_s *dev)
|
|||
|
||||
HRTIM_ALL_OUTPUTS_ENABLE(hrtim, true);
|
||||
|
||||
/* Enable ADC interrupts */
|
||||
/* Enable ADC JEOS interrupts */
|
||||
|
||||
stm32_adc->ops->int_en(stm32_adc, ADC_INT_JEOS);
|
||||
ADC_INT_ENABLE(adc, ADC_INT_JEOS);
|
||||
|
||||
/* Enable ADC12 interrups */
|
||||
|
||||
up_enable_irq(STM32_IRQ_ADC12);
|
||||
|
||||
/* Start injected conversion */
|
||||
|
||||
ADC_INJ_STARTCONV(adc, true);
|
||||
|
||||
errout:
|
||||
return ret;
|
||||
|
@ -493,19 +526,26 @@ errout:
|
|||
static int smps_stop(FAR struct smps_dev_s *dev)
|
||||
{
|
||||
FAR struct smps_lower_dev_s *lower = dev->lower;
|
||||
FAR struct smps_s *smps = (FAR struct smps_s *)dev->priv;
|
||||
FAR struct smps_priv_s *priv = (struct smps_priv_s *)smps->priv;
|
||||
FAR struct hrtim_dev_s *hrtim = lower->hrtim;
|
||||
FAR struct stm32_adc_dev_s *stm32_adc =
|
||||
(FAR struct stm32_adc_dev_s *) lower->adc->ad_priv;
|
||||
FAR struct smps_s *smps = (FAR struct smps_s *)dev->priv;
|
||||
FAR struct smps_priv_s *priv = (struct smps_priv_s *)smps->priv;
|
||||
FAR struct hrtim_dev_s *hrtim = lower->hrtim;
|
||||
FAR struct stm32_adc_dev_s *adc = lower->adc;
|
||||
|
||||
/* Disable HRTIM outputs */
|
||||
|
||||
HRTIM_ALL_OUTPUTS_ENABLE(hrtim, false);
|
||||
|
||||
/* Disable ADC interrupts */
|
||||
/* Stop injected conversion */
|
||||
|
||||
stm32_adc->ops->int_dis(stm32_adc, ADC_INT_JEOS);
|
||||
ADC_INJ_STARTCONV(adc, false);
|
||||
|
||||
/* Disable ADC JEOS interrupts */
|
||||
|
||||
ADC_INT_DISABLE(adc, ADC_INT_JEOS);
|
||||
|
||||
/* Disable ADC12 interrups */
|
||||
|
||||
up_disable_irq(STM32_IRQ_ADC12);
|
||||
|
||||
/* Reset running flag */
|
||||
|
||||
|
@ -885,7 +925,6 @@ static void smps_conv_mode_set(struct smps_priv_s *priv, struct smps_lower_dev_s
|
|||
/* Enable outputs */
|
||||
|
||||
HRTIM_ALL_OUTPUTS_ENABLE(hrtim, true);
|
||||
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
|
@ -894,12 +933,11 @@ static void smps_conv_mode_set(struct smps_priv_s *priv, struct smps_lower_dev_s
|
|||
|
||||
static void adc12_handler(void)
|
||||
{
|
||||
FAR struct smps_dev_s *dev = &g_smps_dev;
|
||||
FAR struct smps_s *smps = (FAR struct smps_s *)dev->priv;
|
||||
FAR struct smps_priv_s *priv = (struct smps_priv_s *)smps->priv;
|
||||
FAR struct smps_dev_s *dev = &g_smps_dev;
|
||||
FAR struct smps_s *smps = (FAR struct smps_s *)dev->priv;
|
||||
FAR struct smps_priv_s *priv = (struct smps_priv_s *)smps->priv;
|
||||
FAR struct smps_lower_dev_s *lower = dev->lower;
|
||||
FAR struct stm32_adc_dev_s *adc =
|
||||
(FAR struct stm32_adc_dev_s*)lower->adc->ad_priv;
|
||||
FAR struct stm32_adc_dev_s *adc = lower->adc;
|
||||
uint32_t pending;
|
||||
float ref = ADC_REF_VOLTAGE;
|
||||
float bit = ADC_VAL_MAX;
|
||||
|
@ -907,14 +945,14 @@ static void adc12_handler(void)
|
|||
float out;
|
||||
uint8_t mode;
|
||||
|
||||
pending = adc->ops->int_get(adc);
|
||||
pending = ADC_INT_GET(adc);
|
||||
|
||||
if (pending & ADC_INT_JEOC && priv->running == true)
|
||||
{
|
||||
/* Get raw ADC values */
|
||||
|
||||
priv->v_out_raw = adc->ops->inj_get(adc, V_OUT_ADC_INJ_CHANNEL);
|
||||
priv->v_in_raw = adc->ops->inj_get(adc, V_IN_ADC_INJ_CHANNEL);
|
||||
priv->v_out_raw = ADC_INJDATA_GET(adc, V_OUT_ADC_INJ_CHANNEL);
|
||||
priv->v_in_raw = ADC_INJDATA_GET(adc, V_IN_ADC_INJ_CHANNEL);
|
||||
|
||||
/* Convert raw values to real values */
|
||||
|
||||
|
@ -969,7 +1007,7 @@ static void adc12_handler(void)
|
|||
|
||||
/* Clear pending */
|
||||
|
||||
adc->ops->int_ack(adc, pending);
|
||||
ADC_INT_ACK(adc, pending);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
|
@ -1031,7 +1069,7 @@ int stm32_smps_setup(void)
|
|||
/* Initialize SMPS lower driver interfaces */
|
||||
|
||||
lower->hrtim = hrtim;
|
||||
lower->adc = adc;
|
||||
lower->adc = adc->ad_priv;
|
||||
lower->comp = NULL;
|
||||
lower->dac = NULL;
|
||||
lower->opamp = NULL;
|
||||
|
@ -1056,8 +1094,6 @@ int stm32_smps_setup(void)
|
|||
goto errout;
|
||||
}
|
||||
|
||||
up_enable_irq(STM32_IRQ_ADC12);
|
||||
|
||||
/* Setup ADC hardware */
|
||||
|
||||
adc->ad_ops->ao_setup(adc);
|
||||
|
|
|
@ -237,4 +237,9 @@ endchoice
|
|||
|
||||
endif # STM32F429I_DISCO_ILI9341_FBIFACE
|
||||
endif # STM32F429I_DISCO_ILI9341
|
||||
|
||||
config STM32F429I_DISCO_HIGHPRI
|
||||
bool "High priority interrupt test"
|
||||
default n
|
||||
|
||||
endif # ARCH_BOARD_STM32F429I_DISCO
|
||||
|
|
64
configs/stm32f429i-disco/highpri/defconfig
Normal file
64
configs/stm32f429i-disco/highpri/defconfig
Normal file
|
@ -0,0 +1,64 @@
|
|||
# CONFIG_ARCH_FPU is not set
|
||||
# CONFIG_STM32_CCMEXCLUDE is not set
|
||||
# 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
|
||||
CONFIG_ARCH_BUTTONS=y
|
||||
CONFIG_ARCH_CHIP_STM32=y
|
||||
CONFIG_ARCH_CHIP_STM32F429Z=y
|
||||
CONFIG_ARCH_HIPRI_INTERRUPT=y
|
||||
CONFIG_ARCH_RAMVECTORS=y
|
||||
CONFIG_ARCH_STACKDUMP=y
|
||||
CONFIG_BOARD_LOOPSPERMSEC=16717
|
||||
CONFIG_BUILTIN=y
|
||||
CONFIG_DEBUG_NOOPT=y
|
||||
CONFIG_DISABLE_POLL=y
|
||||
CONFIG_HAVE_CXX=y
|
||||
CONFIG_HEAP2_BASE=0xD0000000
|
||||
CONFIG_HEAP2_SIZE=8388608
|
||||
CONFIG_INTELHEX_BINARY=y
|
||||
CONFIG_LIBC_FLOATINGPOINT=y
|
||||
CONFIG_LIBM=y
|
||||
CONFIG_MAX_TASKS=16
|
||||
CONFIG_MAX_WDOGPARMS=2
|
||||
CONFIG_MM_REGIONS=3
|
||||
CONFIG_NFILE_DESCRIPTORS=8
|
||||
CONFIG_NFILE_STREAMS=8
|
||||
CONFIG_PREALLOC_MQ_MSGS=4
|
||||
CONFIG_PREALLOC_TIMERS=4
|
||||
CONFIG_PREALLOC_WDOGS=4
|
||||
CONFIG_PWM=y
|
||||
CONFIG_RAM_SIZE=114688
|
||||
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_STM32F429I_DISCO_HIGHPRI=y
|
||||
CONFIG_STM32_ADC1=y
|
||||
CONFIG_STM32_ADC1_DMA=y
|
||||
CONFIG_STM32_ADC1_DMA_CFG=1
|
||||
CONFIG_STM32_ADC1_INJECTED_CHAN=1
|
||||
CONFIG_STM32_ADC_LL_OPS=y
|
||||
CONFIG_STM32_ADC_NOIRQ=y
|
||||
CONFIG_STM32_DISABLE_IDLE_SLEEP_DURING_DEBUG=y
|
||||
CONFIG_STM32_DMA2=y
|
||||
CONFIG_STM32_FSMC=y
|
||||
CONFIG_STM32_FSMC_SRAM=y
|
||||
CONFIG_STM32_JTAG_SW_ENABLE=y
|
||||
CONFIG_STM32_PWM_LL_OPS=y
|
||||
CONFIG_STM32_PWR=y
|
||||
CONFIG_STM32_TIM1=y
|
||||
CONFIG_STM32_TIM1_PWM=y
|
||||
CONFIG_STM32_USART1=y
|
||||
CONFIG_SYSTEM_READLINE=y
|
||||
CONFIG_TASK_NAME_SIZE=0
|
||||
CONFIG_USART1_SERIAL_CONSOLE=y
|
||||
CONFIG_USER_ENTRYPOINT="highpri_main"
|
||||
CONFIG_WDOG_INTRESERVE=0
|
|
@ -444,6 +444,22 @@
|
|||
|
||||
#endif /* CONFIG_STM32_LTDC */
|
||||
|
||||
/* Configuration specific to high priority interrupts example:
|
||||
* - TIM1 CC1 trigger for ADC if DMA transfer and TIM1 PWM
|
||||
* - ADC DMA transfer on DMA1_CH1
|
||||
*/
|
||||
|
||||
#ifdef CONFIG_STM32F429I_DISCO_HIGHPRI
|
||||
|
||||
#if defined(CONFIG_STM32_TIM1_PWM) && defined(CONFIG_STM32_ADC1_DMA)
|
||||
|
||||
/* TIM1 - ADC trigger */
|
||||
|
||||
#define ADC1_EXTSEL_VALUE ADC1_EXTSEL_T1CC1
|
||||
|
||||
#endif /* CONFIG_STM32_TIM1_PWM */
|
||||
#endif /* CONFIG_STM32F429I_DISCO_HIGHPRI */
|
||||
|
||||
/* DMA *************************************************************************/
|
||||
|
||||
#define ADC1_DMA_CHAN DMAMAP_ADC1_1
|
||||
|
|
|
@ -94,6 +94,12 @@ SECTIONS
|
|||
|
||||
_eronly = ABSOLUTE(.);
|
||||
|
||||
/* The RAM vector table (if present) should lie at the beginning of SRAM */
|
||||
|
||||
.ram_vectors : {
|
||||
*(.ram_vectors)
|
||||
} > sram
|
||||
|
||||
.data : {
|
||||
_sdata = ABSOLUTE(.);
|
||||
*(.data .data.*)
|
||||
|
|
|
@ -95,4 +95,8 @@ ifeq ($(CONFIG_ADC),y)
|
|||
CSRCS += stm32_adc.c
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_STM32F429I_DISCO_HIGHPRI),y)
|
||||
CSRCS += stm32_highpri.c
|
||||
endif
|
||||
|
||||
include $(TOPDIR)/configs/Board.mk
|
||||
|
|
544
configs/stm32f429i-disco/src/stm32_highpri.c
Normal file
544
configs/stm32f429i-disco/src/stm32_highpri.c
Normal file
|
@ -0,0 +1,544 @@
|
|||
/****************************************************************************
|
||||
* configs/stm32f429i-disco/src/stm32_highpri.c
|
||||
*
|
||||
* Copyright (C) 2018 Gregory Nutt. All rights reserved.
|
||||
* Author: Mateusz Szafoni <raiden00@railab.me>
|
||||
*
|
||||
* 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 <nuttx/config.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <strings.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <nuttx/arch.h>
|
||||
#include <nuttx/signal.h>
|
||||
|
||||
#include <arch/irq.h>
|
||||
#include <arch/chip/chip.h>
|
||||
#include <arch/board/board.h>
|
||||
|
||||
#include "up_internal.h"
|
||||
#include "ram_vectors.h"
|
||||
|
||||
#include <nuttx/drivers/pwm.h>
|
||||
#include <nuttx/analog/adc.h>
|
||||
#include <nuttx/analog/ioctl.h>
|
||||
|
||||
#include "stm32_pwm.h"
|
||||
#include "stm32_adc.h"
|
||||
#include "stm32_dma.h"
|
||||
|
||||
#ifdef CONFIG_STM32F429I_DISCO_HIGHPRI
|
||||
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
/* Configuration ************************************************************/
|
||||
|
||||
#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_TIM1_PWM)
|
||||
# define HIGHPRI_HAVE_TIM1
|
||||
# endif
|
||||
# if (CONFIG_STM32_ADC1_DMA_CFG != 1)
|
||||
# error ADC1 DMA must be configured in Circular Mode
|
||||
# endif
|
||||
# if !defined(HIGHPRI_HAVE_TIM1)
|
||||
# error "Needs TIM1 to trigger ADC DMA"
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifdef HIGHPRI_HAVE_TIM1
|
||||
# ifndef ADC1_EXTSEL_VALUE
|
||||
# error ADC1 EXTSEL have to be configured in board.h
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#if (CONFIG_STM32_ADC1_INJECTED_CHAN > 0)
|
||||
# if (CONFIG_STM32_ADC1_INJECTED_CHAN > 1)
|
||||
# error Max 1 injected channels supported for now
|
||||
# else
|
||||
# define HIGHPRI_HAVE_INJECTED
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifdef HIGHPRI_HAVE_INJECTED
|
||||
# define INJ_NCHANNELS CONFIG_STM32_ADC1_INJECTED_CHAN
|
||||
#else
|
||||
# define INJ_NCHANNELS (0)
|
||||
#endif
|
||||
|
||||
#ifndef CONFIG_STM32_ADC1_DMA
|
||||
# define REG_NCHANNELS (1)
|
||||
#else
|
||||
# define REG_NCHANNELS (1)
|
||||
#endif
|
||||
|
||||
#define ADC1_NCHANNELS (REG_NCHANNELS + INJ_NCHANNELS)
|
||||
|
||||
#define DEV1_PORT (1)
|
||||
#define DEV1_NCHANNELS ADC1_NCHANNELS
|
||||
#define ADC_REF_VOLTAGE (3.3f)
|
||||
#define ADC_VAL_MAX (4095)
|
||||
|
||||
/****************************************************************************
|
||||
* Private Types
|
||||
****************************************************************************/
|
||||
|
||||
/* High priority example private data */
|
||||
|
||||
struct highpri_s
|
||||
{
|
||||
FAR struct stm32_adc_dev_s *adc1;
|
||||
#ifdef HIGHPRI_HAVE_TIM1
|
||||
struct stm32_pwm_dev_s *pwm;
|
||||
#endif
|
||||
volatile uint32_t cntr1;
|
||||
volatile uint32_t cntr2;
|
||||
volatile uint8_t current;
|
||||
uint16_t r_val[REG_NCHANNELS];
|
||||
float r_volt[REG_NCHANNELS];
|
||||
#ifdef HIGHPRI_HAVE_INJECTED
|
||||
uint16_t j_val[INJ_NCHANNELS];
|
||||
float j_volt[INJ_NCHANNELS];
|
||||
#endif
|
||||
bool lock;
|
||||
};
|
||||
|
||||
/****************************************************************************
|
||||
* Private Data
|
||||
****************************************************************************/
|
||||
|
||||
/* ADC channel list */
|
||||
|
||||
static const uint8_t g_chanlist1[DEV1_NCHANNELS] =
|
||||
{
|
||||
5,
|
||||
#if INJ_NCHANNELS > 0
|
||||
13,
|
||||
#endif
|
||||
};
|
||||
|
||||
/* Configurations of pins used by ADC channel */
|
||||
|
||||
static const uint32_t g_pinlist1[DEV1_NCHANNELS] =
|
||||
{
|
||||
GPIO_ADC1_IN5, /* PA5 */
|
||||
#if INJ_NCHANNELS > 0
|
||||
GPIO_ADC1_IN13, /* PC3 */
|
||||
#endif
|
||||
};
|
||||
|
||||
static struct highpri_s g_highpri;
|
||||
|
||||
/****************************************************************************
|
||||
* Private Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: adc12_handler
|
||||
*
|
||||
* Description:
|
||||
* This is the handler for the high speed ADC interrupt.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#if !defined(CONFIG_STM32_ADC1_DMA) || defined(HIGHPRI_HAVE_INJECTED)
|
||||
void adc_handler(void)
|
||||
{
|
||||
FAR struct stm32_adc_dev_s *adc = g_highpri.adc1;
|
||||
float ref = ADC_REF_VOLTAGE;
|
||||
float bit = ADC_VAL_MAX;
|
||||
uint32_t pending;
|
||||
#ifdef HIGHPRI_HAVE_INJECTED
|
||||
int i = 0;
|
||||
#endif
|
||||
|
||||
/* Get pending ADC1 interrupts */
|
||||
|
||||
pending = ADC_INT_GET(adc);
|
||||
|
||||
if (g_highpri.lock == true)
|
||||
{
|
||||
goto irq_out;
|
||||
}
|
||||
|
||||
#ifndef CONFIG_STM32_ADC1_DMA
|
||||
/* Regular channel end of conversion */
|
||||
|
||||
if (pending & ADC_ISR_EOC)
|
||||
{
|
||||
/* Increase regular sequence counter */
|
||||
|
||||
g_highpri.cntr1 += 1;
|
||||
|
||||
/* Get regular data */
|
||||
|
||||
g_highpri.r_val[g_highpri.current] = ADC_REGDATA_GET(adc);
|
||||
|
||||
/* Do some floating point operations */
|
||||
|
||||
g_highpri.r_volt[g_highpri.current] = (float)g_highpri.r_val[g_highpri.current] * ref / bit;
|
||||
|
||||
if (g_highpri.current >= REG_NCHANNELS-1)
|
||||
{
|
||||
g_highpri.current = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
g_highpri.current += 1;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef HIGHPRI_HAVE_INJECTED
|
||||
/* Injected channel end of sequence */
|
||||
|
||||
if (pending & ADC_ISR_JEOC)
|
||||
{
|
||||
/* Increase injected sequence counter */
|
||||
|
||||
g_highpri.cntr2 += 1;
|
||||
|
||||
/* Get injected channels */
|
||||
|
||||
for (i = 0; i < INJ_NCHANNELS; i += 1)
|
||||
{
|
||||
g_highpri.j_val[i] = ADC_INJDATA_GET(adc, i);
|
||||
}
|
||||
|
||||
/* Do some floating point operations */
|
||||
|
||||
for (i = 0; i < INJ_NCHANNELS; i += 1)
|
||||
{
|
||||
g_highpri.j_volt[i] = (float)g_highpri.j_val[i] * ref / bit;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
irq_out:
|
||||
/* Clear ADC pending interrupts */
|
||||
|
||||
ADC_INT_ACK(adc, pending);
|
||||
}
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Name: dma2s0_handler
|
||||
*
|
||||
* Description:
|
||||
* This is the handler for the high speed ADC interrupt using DMA transfer.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_STM32_ADC1_DMA
|
||||
void dma2s0_handler(void)
|
||||
{
|
||||
float ref = ADC_REF_VOLTAGE;
|
||||
float bit = ADC_VAL_MAX;
|
||||
uint8_t pending;
|
||||
int i;
|
||||
|
||||
pending = stm32_dma_intget(DMA2, DMA_STREAM0);
|
||||
|
||||
if (g_highpri.lock == true)
|
||||
{
|
||||
goto irq_out;
|
||||
}
|
||||
|
||||
/* Increase regular sequence counter */
|
||||
|
||||
g_highpri.cntr1 += 1;
|
||||
|
||||
for (i = 0; i < REG_NCHANNELS; i += 1)
|
||||
{
|
||||
/* Do some floating point operations */
|
||||
|
||||
g_highpri.r_volt[i] = (float)g_highpri.r_val[i] * ref / bit;
|
||||
}
|
||||
|
||||
irq_out:
|
||||
/* Clear DMA pending interrupts */
|
||||
|
||||
stm32_dma_intack(DMA2, DMA_STREAM0, 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[])
|
||||
{
|
||||
#ifdef HIGHPRI_HAVE_TIM1
|
||||
struct stm32_pwm_dev_s *pwm1;
|
||||
#endif
|
||||
FAR struct adc_dev_s *adc1;
|
||||
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 */
|
||||
|
||||
adc1 = stm32_adcinitialize(DEV1_PORT, g_chanlist1, DEV1_NCHANNELS);
|
||||
if (adc1 == NULL)
|
||||
{
|
||||
aerr("ERROR: Failed to get ADC interface 1\n");
|
||||
ret = EXIT_FAILURE;
|
||||
goto errout;
|
||||
}
|
||||
|
||||
highpri->adc1 = (struct stm32_adc_dev_s *)adc1->ad_priv;
|
||||
|
||||
#ifdef HIGHPRI_HAVE_TIM1
|
||||
/* Initialize TIM1 */
|
||||
|
||||
pwm1 = (FAR struct stm32_pwm_dev_s *) stm32_pwminitialize(1);
|
||||
if (pwm1 == NULL)
|
||||
{
|
||||
printf("ERROR: Failed to get PWM1 interface\n");
|
||||
ret = EXIT_FAILURE;
|
||||
goto errout;
|
||||
}
|
||||
|
||||
highpri->pwm = pwm1;
|
||||
|
||||
/* Setup PWM device */
|
||||
|
||||
PWM_SETUP(pwm1);
|
||||
|
||||
/* Set timer frequency */
|
||||
|
||||
PWM_FREQ_UPDATE(pwm1, 1000);
|
||||
|
||||
#if ADC1_EXTSEL_VALUE == ADC1_EXTSEL_T1CC1
|
||||
/* Set CCR1 */
|
||||
|
||||
PWM_CCR_UPDATE(pwm1, 1, 0x0f00);
|
||||
|
||||
/* Enable TIM1 CHAN1 */
|
||||
|
||||
PWM_OUTPUTS_ENABLE(pwm1, STM32_CHAN1, true);
|
||||
#else
|
||||
# error T1CC1 only supported for now
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_DEBUG_PWM_INFO
|
||||
/* Print debug */
|
||||
|
||||
PWM_DUMP_REGS(pwm1);
|
||||
#endif
|
||||
|
||||
#endif /* HIGHPRI_HAVE_TIM1 */
|
||||
|
||||
#if !defined(CONFIG_STM32_ADC1_DMA) || defined(HIGHPRI_HAVE_INJECTED)
|
||||
/* Attach ADC ram vector if no DMA or injected channels support */
|
||||
|
||||
ret = up_ramvec_attach(STM32_IRQ_ADC, adc_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 ADC interrupt vector */
|
||||
|
||||
ret = up_prioritize_irq(STM32_IRQ_ADC, 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_ADC);
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_STM32_ADC1_DMA
|
||||
/* Attach DMA2 STREAM0 ram vector if DMA */
|
||||
|
||||
ret = up_ramvec_attach(STM32_IRQ_DMA2S0, dma2s0_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 DMA2 STREAM0 interrupt vector */
|
||||
|
||||
ret = up_prioritize_irq(STM32_IRQ_DMA2S0, 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_DMA2S0);
|
||||
#endif
|
||||
|
||||
/* Setup ADC hardware */
|
||||
|
||||
adc1->ad_ops->ao_setup(adc1);
|
||||
|
||||
#ifndef CONFIG_STM32_ADC1_DMA
|
||||
/* Enable ADC regular convertion interrupts if no DMA */
|
||||
|
||||
ADC_INT_ENABLE(highpri->adc1, ADC_IER_EOC);
|
||||
#else
|
||||
/* Note: ADC and DMA must be reset after overrun occurs.
|
||||
* For this example we assume that overrun will not occur.
|
||||
* This is true only if DMA and ADC trigger are properly configured.
|
||||
* DMA configuration must be done before ADC trigger starts!
|
||||
*/
|
||||
|
||||
/* Register ADC buffer for DMA transfer */
|
||||
|
||||
ADC_REGBUF_REGISTER(highpri->adc1, g_highpri.r_val, REG_NCHANNELS);
|
||||
#endif
|
||||
|
||||
#ifdef HIGHPRI_HAVE_INJECTED
|
||||
/* Enable ADC injected channels end of conversion interrupts */
|
||||
|
||||
ADC_INT_ENABLE(highpri->adc1, ADC_IER_JEOC);
|
||||
#endif
|
||||
|
||||
#ifdef HIGHPRI_HAVE_TIM1
|
||||
/* Enable timer counter after ADC and DMA configuration */
|
||||
|
||||
PWM_TIM_ENABLE(pwm1, true);
|
||||
#endif
|
||||
|
||||
while(1)
|
||||
{
|
||||
#ifndef CONFIG_STM32_ADC1_DMA
|
||||
/* Software trigger for regular sequence */
|
||||
|
||||
adc1->ad_ops->ao_ioctl(adc1, IO_TRIGGER_REG, 0);
|
||||
|
||||
usleep(100);
|
||||
#endif
|
||||
|
||||
#ifdef HIGHPRI_HAVE_INJECTED
|
||||
/* Software trigger for injected sequence */
|
||||
|
||||
adc1->ad_ops->ao_ioctl(adc1, IO_TRIGGER_INJ, 0);
|
||||
|
||||
usleep(100);
|
||||
#endif
|
||||
/* Lock global data */
|
||||
|
||||
g_highpri.lock = true;
|
||||
|
||||
#ifndef CONFIG_STM32_ADC1_DMA
|
||||
printf("%d [%d] %0.3fV\n", g_highpri.cntr1, g_highpri.current,
|
||||
g_highpri.r_volt[g_highpri.current]);
|
||||
#else
|
||||
printf("%d ", g_highpri.cntr1);
|
||||
|
||||
for (i = 0; i < REG_NCHANNELS; i += 1)
|
||||
{
|
||||
printf("r:[%d] %0.3fV, ", i, g_highpri.r_volt[i]);
|
||||
}
|
||||
|
||||
printf("\n");
|
||||
#endif
|
||||
|
||||
#ifdef HIGHPRI_HAVE_INJECTED
|
||||
/* Print data from injected channels */
|
||||
|
||||
printf("%d ", g_highpri.cntr2);
|
||||
|
||||
for (i = 0; i < INJ_NCHANNELS; i += 1)
|
||||
{
|
||||
printf("j:[%d] %0.3fV, ", i, g_highpri.j_volt[i]);
|
||||
}
|
||||
|
||||
printf("\n");
|
||||
#endif
|
||||
/* Unlock global data */
|
||||
|
||||
g_highpri.lock = false;
|
||||
|
||||
sleep(1);
|
||||
}
|
||||
|
||||
errout:
|
||||
return ret;
|
||||
}
|
||||
|
||||
#endif /* CONFIG_STM32F429I_DISCO_HIGHPRI */
|
Loading…
Reference in a new issue