diff options
Diffstat (limited to 'ports/stm32/dma.c')
-rw-r--r-- | ports/stm32/dma.c | 91 |
1 files changed, 81 insertions, 10 deletions
diff --git a/ports/stm32/dma.c b/ports/stm32/dma.c index df8a408cbf..c252770740 100644 --- a/ports/stm32/dma.c +++ b/ports/stm32/dma.c @@ -81,7 +81,7 @@ typedef union { struct _dma_descr_t { #if defined(STM32F4) || defined(STM32F7) || defined(STM32H7) DMA_Stream_TypeDef *instance; - #elif defined(STM32F0) || defined(STM32G0) || defined(STM32G4) || defined(STM32H5) || defined(STM32L0) || defined(STM32L1) || defined(STM32L4) || defined(STM32WB) || defined(STM32WL) + #elif defined(STM32F0) || defined(STM32G0) || defined(STM32G4) || defined(STM32H5) || defined(STM32L0) || defined(STM32L1) || defined(STM32L4) || defined(STM32N6) || defined(STM32WB) || defined(STM32WL) DMA_Channel_TypeDef *instance; #else #error "Unsupported Processor" @@ -93,7 +93,7 @@ struct _dma_descr_t { // Default parameters to dma_init() shared by spi and i2c; Channel and Direction // vary depending on the peripheral instance so they get passed separately -#if defined(STM32H5) +#if defined(STM32H5) || defined(STM32N6) static const DMA_InitTypeDef dma_init_struct_spi_i2c = { .Request = 0, // set by dma_init_handle .BlkHWRequest = DMA_BREQ_SINGLE_BURST, @@ -157,7 +157,7 @@ static const DMA_InitTypeDef dma_init_struct_i2s = { }; #endif -#if ENABLE_SDIO && !defined(STM32H5) && !defined(STM32H7) +#if ENABLE_SDIO && !defined(STM32H5) && !defined(STM32H7) && !defined(STM32N6) // Parameters to dma_init() for SDIO tx and rx. static const DMA_InitTypeDef dma_init_struct_sdio = { #if defined(STM32F4) || defined(STM32F7) @@ -735,9 +735,13 @@ const dma_descr_t dma_SPI_1_RX = { GPDMA1_Channel0, GPDMA1_REQUEST_SPI1_RX, dma_ const dma_descr_t dma_SPI_1_TX = { GPDMA1_Channel1, GPDMA1_REQUEST_SPI1_TX, dma_id_1, &dma_init_struct_spi_i2c }; const dma_descr_t dma_SPI_2_RX = { GPDMA1_Channel2, GPDMA1_REQUEST_SPI2_RX, dma_id_2, &dma_init_struct_spi_i2c }; const dma_descr_t dma_SPI_2_TX = { GPDMA1_Channel3, GPDMA1_REQUEST_SPI2_TX, dma_id_3, &dma_init_struct_spi_i2c }; +const dma_descr_t dma_SPI_3_RX = { GPDMA1_Channel4, GPDMA1_REQUEST_SPI3_RX, dma_id_4, &dma_init_struct_spi_i2c }; +const dma_descr_t dma_SPI_3_TX = { GPDMA1_Channel5, GPDMA1_REQUEST_SPI3_TX, dma_id_5, &dma_init_struct_spi_i2c }; +const dma_descr_t dma_SPI_4_RX = { GPDMA1_Channel6, GPDMA1_REQUEST_SPI4_RX, dma_id_6, &dma_init_struct_spi_i2c }; +const dma_descr_t dma_SPI_4_TX = { GPDMA1_Channel7, GPDMA1_REQUEST_SPI4_TX, dma_id_7, &dma_init_struct_spi_i2c }; #if MICROPY_HW_ENABLE_DAC -const dma_descr_t dma_DAC_1_TX = { GPDMA1_Channel4, GPDMA1_REQUEST_DAC1_CH1, dma_id_4, &dma_init_struct_dac }; -const dma_descr_t dma_DAC_2_TX = { GPDMA1_Channel5, GPDMA1_REQUEST_DAC1_CH2, dma_id_5, &dma_init_struct_dac }; +const dma_descr_t dma_DAC_1_TX = { GPDMA2_Channel0, GPDMA1_REQUEST_DAC1_CH1, dma_id_8, &dma_init_struct_dac }; +const dma_descr_t dma_DAC_2_TX = { GPDMA2_Channel1, GPDMA1_REQUEST_DAC1_CH2, dma_id_9, &dma_init_struct_dac }; #endif static const uint8_t dma_irqn[NSTREAM] = { @@ -826,6 +830,46 @@ static const uint8_t dma_irqn[NSTREAM] = { DMA2_Stream7_IRQn, }; +#elif defined(STM32N6) + +#define NCONTROLLERS (1) +#define NSTREAMS_PER_CONTROLLER (16) +#define NSTREAM (NCONTROLLERS * NSTREAMS_PER_CONTROLLER) + +#define DMA_SUB_INSTANCE_AS_UINT8(dma_channel) (dma_channel) + +#define DMA1_ENABLE_MASK (0xffff) // Bits in dma_enable_mask corresponding to GPDMA1 + +const dma_descr_t dma_SPI_1_RX = { GPDMA1_Channel0, GPDMA1_REQUEST_SPI1_RX, dma_id_0, &dma_init_struct_spi_i2c }; +const dma_descr_t dma_SPI_1_TX = { GPDMA1_Channel1, GPDMA1_REQUEST_SPI1_TX, dma_id_1, &dma_init_struct_spi_i2c }; +const dma_descr_t dma_SPI_2_RX = { GPDMA1_Channel2, GPDMA1_REQUEST_SPI2_RX, dma_id_2, &dma_init_struct_spi_i2c }; +const dma_descr_t dma_SPI_2_TX = { GPDMA1_Channel3, GPDMA1_REQUEST_SPI2_TX, dma_id_3, &dma_init_struct_spi_i2c }; +const dma_descr_t dma_SPI_3_RX = { GPDMA1_Channel4, GPDMA1_REQUEST_SPI3_RX, dma_id_4, &dma_init_struct_spi_i2c }; +const dma_descr_t dma_SPI_3_TX = { GPDMA1_Channel5, GPDMA1_REQUEST_SPI3_TX, dma_id_5, &dma_init_struct_spi_i2c }; +const dma_descr_t dma_SPI_4_RX = { GPDMA1_Channel6, GPDMA1_REQUEST_SPI4_RX, dma_id_6, &dma_init_struct_spi_i2c }; +const dma_descr_t dma_SPI_4_TX = { GPDMA1_Channel7, GPDMA1_REQUEST_SPI4_TX, dma_id_7, &dma_init_struct_spi_i2c }; +const dma_descr_t dma_SPI_5_RX = { GPDMA1_Channel8, GPDMA1_REQUEST_SPI5_RX, dma_id_8, &dma_init_struct_spi_i2c }; +const dma_descr_t dma_SPI_5_TX = { GPDMA1_Channel9, GPDMA1_REQUEST_SPI5_TX, dma_id_9, &dma_init_struct_spi_i2c }; + +static const uint8_t dma_irqn[NSTREAM] = { + GPDMA1_Channel0_IRQn, + GPDMA1_Channel1_IRQn, + GPDMA1_Channel2_IRQn, + GPDMA1_Channel3_IRQn, + GPDMA1_Channel4_IRQn, + GPDMA1_Channel5_IRQn, + GPDMA1_Channel6_IRQn, + GPDMA1_Channel7_IRQn, + GPDMA1_Channel8_IRQn, + GPDMA1_Channel9_IRQn, + GPDMA1_Channel10_IRQn, + GPDMA1_Channel11_IRQn, + GPDMA1_Channel12_IRQn, + GPDMA1_Channel13_IRQn, + GPDMA1_Channel14_IRQn, + GPDMA1_Channel15_IRQn, +}; + #endif static DMA_HandleTypeDef *dma_handle[NSTREAM] = {NULL}; @@ -849,6 +893,10 @@ volatile dma_idle_count_t dma_idle; #define __HAL_RCC_DMA2_CLK_ENABLE __HAL_RCC_GPDMA2_CLK_ENABLE #define __HAL_RCC_DMA1_CLK_DISABLE __HAL_RCC_GPDMA1_CLK_DISABLE #define __HAL_RCC_DMA2_CLK_DISABLE __HAL_RCC_GPDMA2_CLK_DISABLE +#elif defined(STM32N6) +#define DMA1_IS_CLK_ENABLED() (__HAL_RCC_GPDMA1_IS_CLK_ENABLED()) +#define __HAL_RCC_DMA1_CLK_ENABLE __HAL_RCC_GPDMA1_CLK_ENABLE +#define __HAL_RCC_DMA1_CLK_DISABLE __HAL_RCC_GPDMA1_CLK_DISABLE #else #define DMA1_IS_CLK_ENABLED() ((RCC->AHB1ENR & RCC_AHB1ENR_DMA1EN) != 0) #define DMA2_IS_CLK_ENABLED() ((RCC->AHB1ENR & RCC_AHB1ENR_DMA2EN) != 0) @@ -1181,10 +1229,11 @@ void DMA2_Channel8_IRQHandler(void) { } #endif -#elif defined(STM32H5) +#elif defined(STM32H5) || defined(STM32N6) #define DEFINE_IRQ_HANDLER(periph, channel, id) \ void GPDMA##periph##_Channel##channel##_IRQHandler(void) { \ + MP_STATIC_ASSERT(GPDMA##periph##_Channel##channel##_IRQn > 0); \ IRQ_ENTER(GPDMA##periph##_Channel##channel##_IRQn); \ if (dma_handle[id] != NULL) { \ HAL_DMA_IRQHandler(dma_handle[id]); \ @@ -1200,6 +1249,7 @@ DEFINE_IRQ_HANDLER(1, 4, dma_id_4) DEFINE_IRQ_HANDLER(1, 5, dma_id_5) DEFINE_IRQ_HANDLER(1, 6, dma_id_6) DEFINE_IRQ_HANDLER(1, 7, dma_id_7) +#if defined(STM32H5) DEFINE_IRQ_HANDLER(2, 0, dma_id_8) DEFINE_IRQ_HANDLER(2, 1, dma_id_9) DEFINE_IRQ_HANDLER(2, 2, dma_id_10) @@ -1208,6 +1258,16 @@ DEFINE_IRQ_HANDLER(2, 4, dma_id_12) DEFINE_IRQ_HANDLER(2, 5, dma_id_13) DEFINE_IRQ_HANDLER(2, 6, dma_id_14) DEFINE_IRQ_HANDLER(2, 7, dma_id_15) +#else +DEFINE_IRQ_HANDLER(1, 8, dma_id_8) +DEFINE_IRQ_HANDLER(1, 9, dma_id_9) +DEFINE_IRQ_HANDLER(1, 10, dma_id_10) +DEFINE_IRQ_HANDLER(1, 11, dma_id_11) +DEFINE_IRQ_HANDLER(1, 12, dma_id_12) +DEFINE_IRQ_HANDLER(1, 13, dma_id_13) +DEFINE_IRQ_HANDLER(1, 14, dma_id_14) +DEFINE_IRQ_HANDLER(1, 15, dma_id_15) +#endif #elif defined(STM32L0) @@ -1420,7 +1480,7 @@ void dma_init_handle(DMA_HandleTypeDef *dma, const dma_descr_t *dma_descr, uint3 dma->Instance = dma_descr->instance; dma->Init = *dma_descr->init; dma->Init.Direction = dir; - #if defined(STM32G0) || defined(STM32G4) || defined(STM32H5) || defined(STM32H7) || defined(STM32L0) || defined(STM32L4) || defined(STM32WB) || defined(STM32WL) + #if defined(STM32G0) || defined(STM32G4) || defined(STM32H5) || defined(STM32H7) || defined(STM32L0) || defined(STM32L4) || defined(STM32N6) || defined(STM32WB) || defined(STM32WL) dma->Init.Request = dma_descr->sub_instance; #else #if !defined(STM32F0) && !defined(STM32L1) @@ -1428,7 +1488,7 @@ void dma_init_handle(DMA_HandleTypeDef *dma, const dma_descr_t *dma_descr, uint3 #endif #endif - #if defined(STM32H5) + #if defined(STM32H5) || defined(STM32N6) // Configure src/dest settings based on the DMA direction. if (dir == DMA_MEMORY_TO_PERIPH) { dma->Init.SrcInc = DMA_SINC_INCREMENTED; @@ -1459,13 +1519,24 @@ void dma_init(DMA_HandleTypeDef *dma, const dma_descr_t *dma_descr, uint32_t dir dma_enable_clock(dma_id); - #if defined(STM32G0) || defined(STM32G4) || defined(STM32H5) || defined(STM32H7) || defined(STM32L0) || defined(STM32L1) || defined(STM32L4) || defined(STM32WB) || defined(STM32WL) + #if defined(STM32G0) || defined(STM32G4) || defined(STM32H5) || defined(STM32H7) || defined(STM32L0) || defined(STM32L1) || defined(STM32L4) || defined(STM32N6) || defined(STM32WB) || defined(STM32WL) // Always reset and configure the H7 and G0/G4/H7/L0/L4/WB/WL DMA peripheral // (dma->State is set to HAL_DMA_STATE_RESET by memset above) // TODO: understand how L0/L4 DMA works so this is not needed HAL_DMA_DeInit(dma); dma->Parent = data; // HAL_DMA_DeInit may clear Parent, so set it again HAL_DMA_Init(dma); + + #if defined(STM32N6) + // Configure security attributes. + HAL_DMA_ConfigChannelAttributes(dma, DMA_CHANNEL_PRIV | DMA_CHANNEL_SEC | DMA_CHANNEL_SRC_SEC | DMA_CHANNEL_DEST_SEC); + // Configure data handling. + DMA_DataHandlingConfTypeDef config; + config.DataExchange = DMA_EXCHANGE_NONE; + config.DataAlignment = DMA_DATA_RIGHTALIGN_ZEROPADDED; + HAL_DMAEx_ConfigDataHandling(dma, &config); + #endif + NVIC_SetPriority(IRQn_NONNEG(dma_irqn[dma_id]), IRQ_PRI_DMA); #else // if this stream was previously configured for this channel/request and direction then we @@ -1736,7 +1807,7 @@ void dma_nohal_start(const dma_descr_t *descr, uint32_t src_addr, uint32_t dst_a dma->CCR |= DMA_CCR_EN; } -#elif defined(STM32G0) || defined(STM32WB) || defined(STM32WL) +#elif defined(STM32G0) || defined(STM32N6) || defined(STM32WB) || defined(STM32WL) // These functions are currently not implemented or needed for this MCU. |