Hello,
I'm working on a Kinetis KL17 microcontroller with KDS 3.2.0 and Kinetis SDK 2.0.
I would like to offload reception of I²C data to DMA for improved performance.
The initialization code looks as follows:
DMAMUX_Init(DMAMUX0); DMAMUX_SetSource(DMAMUX0, 0, (uint8_t)kDmaRequestMux0I2C0); DMAMUX_EnableChannel(DMAMUX0, 0); DMA_Init(DMA0); DMA_CreateHandle(dma_handle, DMA0, 0); DMA_SetCallback(dma_handle, dma_cb, ctx); I2C_SlaveGetDefaultConfig(&slave_config); slave_config.slaveAddress = BOARD_I2C_SLAVE_ADDR; I2C_SlaveInit(I2C0, &slave_config); DMA_CreateHandle(dma_handle, DMA0, 0); DMA_SetCallback(dma_handle, dma_cb, ctx); I2C_SlaveTransferCreateHandle(I2C0, i2c_handle, i2c_slave_cb, ctx); I2C_SlaveTransferNonBlocking(I2C0, i2c_handle, kI2C_SlaveAllEvents);
The DMA is configured in the registered I²C callback function (called by I2C_SlaveTransferHandleIRQ() from interrupt context - when the received address matches the slave address).
The length of the received data is unknown beforehand, so a large enough buffer is allocated (32 bytes in this example).
The DMA transfer is aborted when the stop condition is detected.
static void i2c_slave_cb(I2C_Type *base, i2c_slave_transfer_t *xfer, void *data) { ... switch (xfer->event) { ... case kI2C_SlaveAddressMatchEvent: DMA_PrepareTransfer(&transfer_config, &I2C0->D, sizeof(I2C0->D), ctx->buf, sizeof(*ctx->buf), ctx->len, kDMA_PeripheralToMemory); DMA_SubmitTransfer(&ctx->dma_handle, &transfer_config, kDMA_EnableInterrupt); DMA_StartTransfer(&ctx->dma_handle); I2C_EnableDMA(I2C0, true); break; ... case kI2C_SlaveCompletionEvent: I2C_EnableDMA(I2C0, false); DMA_AbortTransfer(&ctx->dma_handle); break; ... }
As is visible in the first attachment, the length of the received data is 5 bytes in this example.
When the data is printed on LPUART0 in the application the last byte seems to be duplicated (second attachment).
Investigation of the DMA BCR register shows that the initial value of 0x20 (32 bytes) is decremented to 0x1a (26 bytes).
This seems to indicate that the DMA got 6 requests to transfer a byte to the destination memory.
It's unclear to me how this behaviour is triggered. Did I misconfigure the DMA/I²C modules? Something else?
Kind regards,
Serge
Hi, Serge,
I am sorry for the delay, have you solved your issue?
BR
Xiangjun Rong
Hello Xiangjun,
I have not yet resolved the issue at hand.
Kind regards,
Serge