Hi nxp. First time poster here.
I have successfully used the fsl_i2c module to do blocking calls to I2C reads.
That is all working.
I would like to iterate on this to get EDMA working.
I did not see any examples with EDMA + I2C.
FWIW, EDMA + SPI is working nicely and I was hoping I2C would be just as easy.
Here is the code I'm using.
I based it on the API docs in the Kinetis SDK 2.0 manual, and my functioning EDMA SPI example.
The failure mode is that the I2C_MasterUserCallbackis not firing.
// I2C init
i2c_master_config_t masterConfig;
I2C_MasterGetDefaultConfig(&masterConfig);
masterConfig.enableHighDrive = 0;
I2C_MasterInit(I2C0, &masterConfig, CLOCK_GetFreq(I2C0_CLK_SRC));// EDMA init
uint32_t i2cChannel == 19U;
edma_config_t userConfig;NVIC_SetPriority(DMA3_DMA19_IRQn, DMA0_INTERRUPT_PRIORITY);
DMAMUX_Init(DMAMUX);
DMAMUX_SetSource(DMAMUX, i2cChannel, kDmaRequestMux0I2C0);
DMAMUX_EnableChannel(DMAMUX, i2cChannel);EDMA_GetDefaultConfig(&userConfig);
EDMA_Init(DMA0, &userConfig);// Clear handles. Is an intermediary handle needed.
memset(&(i2cEdmaHandle), 0, sizeof(i2cEdmaHandle));
EDMA_CreateHandle(&(i2cEdmaHandle), DMA0, i2cChannel);I2C_MasterCreateEDMAHandle(I2C0, &i2c_edma_m_handle, I2C_MasterUserCallback, NULL, &i2cEdmaHandle);
// transfer init
masterXfer.slaveAddress = 0x48;
masterXfer.direction = kI2C_Read;
masterXfer.subaddress = 0;
masterXfer.subaddressSize = 1;
masterXfer.data = masterRxData;
masterXfer.dataSize = 2;
masterXfer.flags = kI2C_TransferDefaultFlag;// in my main loop, requesting data from I2C0
status = I2C_MasterTransferEDMA(I2C0, &i2c_edma_m_handle, &masterXfer);
if ((status != kStatus_Success) && (status != kStatus_DSPI_Busy))
{
I2C_MasterTransferAbortEDMA(I2C0, &i2c_edma_m_handle);
// do things to handle fault}
// blocking wait for the callback to fire
// callback definition
static void I2C_MasterUserCallback(I2C_Type *base, i2c_master_edma_handle_t *handle, status_t status, void *userData)
{
if (status == kStatus_Success) {// do stuff with results
}}
Hi Mike,
So the callback is not being called, but do you see I2C traffic on the bus (physically see it on a scope or logic analyzer)?
~Chris
Thanks Chris!
The transaction on the wire (with DMA) does not look good to say the least.
Both clk and data are held low after, and it seems as if the data length is short by one byte.
This is the non DMA capture
My guess is that I need to better define the transfer.
I'll give that a shot.
I decided to change the non-DMA approach to use the same transfer objects that I defined above.
I wanted to verify that my masterXfer is defined properly.
OLD CODE :
I2C_MasterStart(I2C0, slave_addr, kI2C_Read);
while(!((status = I2C_MasterGetStatusFlags(I2C0)) & kI2C_IntPendingFlag));
result = I2C_MasterReadBlocking(I2C0, masterRxData, 2);
I2C_MasterStop(I2C0);
NEW CODE:
result = I2C_MasterTransferBlocking(I2C0, &masterXfer);
The new code works without DMA, which should validate that my masterXfer is set up properly
masterXfer.slaveAddress = 0x48;
masterXfer.direction = kI2C_Read;
masterXfer.subaddress = 0;
masterXfer.subaddressSize = 0;
masterXfer.data = masterRxData;
masterXfer.dataSize = 2;
masterXfer.flags = kI2C_TransferDefaultFlag;
I get the same failure mode when using DMA.
Changing DMA channel from 19 to 3 seems to have fixed my problem.
It looks like I was using the wrong mux group.
oops.
Thanks!
Hi Mike,
Ah! Glad to hear it is resolved. :smileyhappy:
Regards,
Chris
BTW - the return value for I2C_MasterTransferEDMA is 0x00