Skip to content
Snippets Groups Projects
Commit c5175526 authored by blmorris's avatar blmorris Committed by Damien George
Browse files

stmhal/dma.c: Modify dma_init() to accept init struct as an argument

This removes hard-coded DMA init params from dma_init(), instead defining
these parameters in a DMA_InitTypeDef struct that gets passed as an
argument to dma_init()
This makes dma_init more generic so it can be used for I2S and SD Card,
which require different initialization parameters.
parent 3299f687
Branches
No related tags found
No related merge requests found
......@@ -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();
......
......@@ -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);
......@@ -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);
......
......@@ -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) {
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment