diff --git a/stmhal/dma.c b/stmhal/dma.c index 93c35d61d6..77474b7676 100644 --- a/stmhal/dma.c +++ b/stmhal/dma.c @@ -52,6 +52,23 @@ static const uint8_t dma_irqn[NSTREAM] = { DMA2_Stream7_IRQn, }; +// Default parameters to dma_init() shared by spi and i2c; Channel and Direction +// vary depending on the peripheral instance so they get passed separately +const DMA_InitTypeDef dma_init_struct_spi_i2c = { + .Channel = 0, + .Direction = 0, + .PeriphInc = DMA_PINC_DISABLE, + .MemInc = DMA_MINC_ENABLE, + .PeriphDataAlignment = DMA_PDATAALIGN_BYTE, + .MemDataAlignment = DMA_MDATAALIGN_BYTE, + .Mode = DMA_NORMAL, + .Priority = DMA_PRIORITY_LOW, + .FIFOMode = DMA_FIFOMODE_DISABLE, + .FIFOThreshold = DMA_FIFO_THRESHOLD_FULL, + .MemBurst = DMA_MBURST_INC4, + .PeriphBurst = DMA_PBURST_INC4 +}; + static DMA_HandleTypeDef *dma_handle[NSTREAM] = {NULL}; static uint32_t dma_last_channel[NSTREAM]; @@ -80,7 +97,7 @@ static int get_dma_id(DMA_Stream_TypeDef *dma_stream) { } } -void dma_init(DMA_HandleTypeDef *dma, DMA_Stream_TypeDef *dma_stream, uint32_t dma_channel, uint32_t direction, void *data) { +void dma_init(DMA_HandleTypeDef *dma, DMA_Stream_TypeDef *dma_stream, const DMA_InitTypeDef *dma_init, uint32_t dma_channel, uint32_t direction, void *data) { int dma_id = get_dma_id(dma_stream); //printf("dma_init(%p, %p(%d), 0x%x, 0x%x, %p)\n", dma, dma_stream, dma_id, (uint)dma_channel, (uint)direction, data); @@ -90,9 +107,11 @@ void dma_init(DMA_HandleTypeDef *dma, DMA_Stream_TypeDef *dma_stream, uint32_t d // set global pointer for IRQ handler dma_handle[dma_id] = dma; - // initialise critical parameters + // initialise parameters dma->Instance = dma_stream; + dma->Init = *dma_init; dma->Init.Direction = direction; + dma->Init.Channel = dma_channel; // half of __HAL_LINKDMA(data, xxx, *dma) // caller must implement other half by doing: data->xxx = dma @@ -105,19 +124,6 @@ void dma_init(DMA_HandleTypeDef *dma, DMA_Stream_TypeDef *dma_stream, uint32_t d } dma_last_channel[dma_id] = dma_channel; - // set DMA parameters (these are only used by HAL_DMA_Init) - dma->Init.Channel = dma_channel; - dma->Init.PeriphInc = DMA_PINC_DISABLE; - dma->Init.MemInc = DMA_MINC_ENABLE; - dma->Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE; - dma->Init.MemDataAlignment = DMA_MDATAALIGN_BYTE; - dma->Init.Mode = DMA_NORMAL; - dma->Init.Priority = DMA_PRIORITY_LOW; - dma->Init.FIFOMode = DMA_FIFOMODE_DISABLE; - dma->Init.FIFOThreshold = DMA_FIFO_THRESHOLD_FULL; - dma->Init.MemBurst = DMA_MBURST_INC4; - dma->Init.PeriphBurst = DMA_PBURST_INC4; - // enable clock for needed DMA peripheral if (dma_id <= 7) { __DMA1_CLK_ENABLE(); diff --git a/stmhal/dma.h b/stmhal/dma.h index fc651ff151..d4f7b6cae2 100644 --- a/stmhal/dma.h +++ b/stmhal/dma.h @@ -24,6 +24,8 @@ * THE SOFTWARE. */ -void dma_init(DMA_HandleTypeDef *dma, DMA_Stream_TypeDef *dma_stream, uint32_t dma_channel, uint32_t direction, void *data); +extern const DMA_InitTypeDef dma_init_struct_spi_i2c; + +void dma_init(DMA_HandleTypeDef *dma, DMA_Stream_TypeDef *dma_stream, const DMA_InitTypeDef *dma_init, uint32_t dma_channel, uint32_t direction, void *data); void dma_deinit(DMA_HandleTypeDef *dma); void dma_invalidate_channel(DMA_Stream_TypeDef *dma_stream, uint32_t dma_channel); diff --git a/stmhal/i2c.c b/stmhal/i2c.c index 72faf50507..4f6e74245e 100644 --- a/stmhal/i2c.c +++ b/stmhal/i2c.c @@ -471,7 +471,7 @@ STATIC mp_obj_t pyb_i2c_send(mp_uint_t n_args, const mp_obj_t *pos_args, mp_map_ // if IRQs are enabled then we can use DMA DMA_HandleTypeDef tx_dma; if (query_irq() == IRQ_STATE_ENABLED) { - dma_init(&tx_dma, self->tx_dma_stream, self->tx_dma_channel, DMA_MEMORY_TO_PERIPH, self->i2c); + dma_init(&tx_dma, self->tx_dma_stream, &dma_init_struct_spi_i2c, self->tx_dma_channel, DMA_MEMORY_TO_PERIPH, self->i2c); self->i2c->hdmatx = &tx_dma; self->i2c->hdmarx = NULL; } @@ -545,7 +545,7 @@ STATIC mp_obj_t pyb_i2c_recv(mp_uint_t n_args, const mp_obj_t *pos_args, mp_map_ // if IRQs are enabled then we can use DMA DMA_HandleTypeDef rx_dma; if (query_irq() == IRQ_STATE_ENABLED) { - dma_init(&rx_dma, self->rx_dma_stream, self->rx_dma_channel, DMA_PERIPH_TO_MEMORY, self->i2c); + dma_init(&rx_dma, self->rx_dma_stream, &dma_init_struct_spi_i2c, self->rx_dma_channel, DMA_PERIPH_TO_MEMORY, self->i2c); self->i2c->hdmatx = NULL; self->i2c->hdmarx = &rx_dma; } @@ -639,7 +639,7 @@ STATIC mp_obj_t pyb_i2c_mem_read(mp_uint_t n_args, const mp_obj_t *pos_args, mp_ status = HAL_I2C_Mem_Read(self->i2c, i2c_addr, mem_addr, mem_addr_size, (uint8_t*)vstr.buf, vstr.len, args[3].u_int); } else { DMA_HandleTypeDef rx_dma; - dma_init(&rx_dma, self->rx_dma_stream, self->rx_dma_channel, DMA_PERIPH_TO_MEMORY, self->i2c); + dma_init(&rx_dma, self->rx_dma_stream, &dma_init_struct_spi_i2c, self->rx_dma_channel, DMA_PERIPH_TO_MEMORY, self->i2c); self->i2c->hdmatx = NULL; self->i2c->hdmarx = &rx_dma; status = HAL_I2C_Mem_Read_DMA(self->i2c, i2c_addr, mem_addr, mem_addr_size, (uint8_t*)vstr.buf, vstr.len); @@ -703,7 +703,7 @@ STATIC mp_obj_t pyb_i2c_mem_write(mp_uint_t n_args, const mp_obj_t *pos_args, mp status = HAL_I2C_Mem_Write(self->i2c, i2c_addr, mem_addr, mem_addr_size, bufinfo.buf, bufinfo.len, args[3].u_int); } else { DMA_HandleTypeDef tx_dma; - dma_init(&tx_dma, self->tx_dma_stream, self->tx_dma_channel, DMA_MEMORY_TO_PERIPH, self->i2c); + dma_init(&tx_dma, self->tx_dma_stream, &dma_init_struct_spi_i2c, self->tx_dma_channel, DMA_MEMORY_TO_PERIPH, self->i2c); self->i2c->hdmatx = &tx_dma; self->i2c->hdmarx = NULL; status = HAL_I2C_Mem_Write_DMA(self->i2c, i2c_addr, mem_addr, mem_addr_size, bufinfo.buf, bufinfo.len); diff --git a/stmhal/spi.c b/stmhal/spi.c index 38e49b4215..c9c853326f 100644 --- a/stmhal/spi.c +++ b/stmhal/spi.c @@ -458,7 +458,7 @@ STATIC mp_obj_t pyb_spi_send(mp_uint_t n_args, const mp_obj_t *pos_args, mp_map_ status = HAL_SPI_Transmit(self->spi, bufinfo.buf, bufinfo.len, args[1].u_int); } else { DMA_HandleTypeDef tx_dma; - dma_init(&tx_dma, self->tx_dma_stream, self->tx_dma_channel, DMA_MEMORY_TO_PERIPH, self->spi); + dma_init(&tx_dma, self->tx_dma_stream, &dma_init_struct_spi_i2c, self->tx_dma_channel, DMA_MEMORY_TO_PERIPH, self->spi); self->spi->hdmatx = &tx_dma; self->spi->hdmarx = NULL; status = HAL_SPI_Transmit_DMA(self->spi, bufinfo.buf, bufinfo.len); @@ -511,12 +511,12 @@ STATIC mp_obj_t pyb_spi_recv(mp_uint_t n_args, const mp_obj_t *pos_args, mp_map_ DMA_HandleTypeDef tx_dma, rx_dma; if (self->spi->Init.Mode == SPI_MODE_MASTER) { // in master mode the HAL actually does a TransmitReceive call - dma_init(&tx_dma, self->tx_dma_stream, self->tx_dma_channel, DMA_MEMORY_TO_PERIPH, self->spi); + dma_init(&tx_dma, self->tx_dma_stream, &dma_init_struct_spi_i2c, self->tx_dma_channel, DMA_MEMORY_TO_PERIPH, self->spi); self->spi->hdmatx = &tx_dma; } else { self->spi->hdmatx = NULL; } - dma_init(&rx_dma, self->rx_dma_stream, self->rx_dma_channel, DMA_PERIPH_TO_MEMORY, self->spi); + dma_init(&rx_dma, self->rx_dma_stream, &dma_init_struct_spi_i2c, self->rx_dma_channel, DMA_PERIPH_TO_MEMORY, self->spi); self->spi->hdmarx = &rx_dma; status = HAL_SPI_Receive_DMA(self->spi, (uint8_t*)vstr.buf, vstr.len); @@ -604,9 +604,9 @@ STATIC mp_obj_t pyb_spi_send_recv(mp_uint_t n_args, const mp_obj_t *pos_args, mp status = HAL_SPI_TransmitReceive(self->spi, bufinfo_send.buf, bufinfo_recv.buf, bufinfo_send.len, args[2].u_int); } else { DMA_HandleTypeDef tx_dma, rx_dma; - dma_init(&tx_dma, self->tx_dma_stream, self->tx_dma_channel, DMA_MEMORY_TO_PERIPH, self->spi); + dma_init(&tx_dma, self->tx_dma_stream, &dma_init_struct_spi_i2c, self->tx_dma_channel, DMA_MEMORY_TO_PERIPH, self->spi); self->spi->hdmatx = &tx_dma; - dma_init(&rx_dma, self->rx_dma_stream, self->rx_dma_channel, DMA_PERIPH_TO_MEMORY, self->spi); + dma_init(&rx_dma, self->rx_dma_stream, &dma_init_struct_spi_i2c, self->rx_dma_channel, DMA_PERIPH_TO_MEMORY, self->spi); self->spi->hdmarx = &rx_dma; status = HAL_SPI_TransmitReceive_DMA(self->spi, bufinfo_send.buf, bufinfo_recv.buf, bufinfo_send.len); if (status == HAL_OK) {