Problem with I2C and DMA on XMC4500

Tip / Sign in to post questions, reply, level up, and achieve exciting badges. Know more

cross mob
User15069
Level 1
Level 1
Hello

I wrote a simple code to communicate between an XMC an a 24FC512 EEPROM using DMA. DMA has been configured using DAVE.

In Step 1, two data bytes are written.
in Step 2, two data bytes are read back

The code works fine if I only run Step 1 or Step 2 of the program (comment out).

If I run the total program code, then the the program stucks in in the while loop "while (I2C_MASTER_IsRxBusy(&I2C_MASTER_0));"
after calling I2C_MASTER_StartReceiveDMA(&I2C_MASTER_0, 2, rx_buf); The interrupt is not called. Also a Stop bit is created although the program stucks in the loop.


int main(void)
{
DAVE_STATUS_t init_status;
uint8_t tx_buf[128];
uint8_t Adr_buf[128];
uint32_t i;

init_status = DAVE_Init();
if(init_status == DAVE_STATUS_SUCCESS)
{
// Step 1: write some bytes to I2C EEPROM------------------------------------------------------------------------------
tx_buf[0] = 0; // addr hi
tx_buf[1] = 0; // adr lo
tx_buf[2] = 0xAB; // data byte 1
tx_buf[3] = 0xCD; // data byte 2


I2C_MASTER_SendStart(&I2C_MASTER_0, SLAVE_ADDRESS, XMC_I2C_CH_CMD_WRITE);
while(I2C_MASTER_GetFlagStatus(&I2C_MASTER_0, XMC_I2C_CH_STATUS_FLAG_ACK_RECEIVED) == 0U)
{
// wait for ACK
}
I2C_MASTER_ClearFlag(&I2C_MASTER_0,XMC_I2C_CH_STATUS_FLAG_ACK_RECEIVED);

I2C_MASTER_StartTransmitDMA(&I2C_MASTER_0, 4, &tx_buf[0]);
while(I2C_MASTER_IsTxBusy(&I2C_MASTER_0));
I2C_MASTER_SendStop(&I2C_MASTER_0);
for (i=0;i<200000;i++); // wait a little bit until data has been saved inside EEPROM

// Step 2: read back 2 bytes from I2C EEPROM --------------------------------------------------------------------
I2C_MASTER_SendStart(&I2C_MASTER_0, SLAVE_ADDRESS, XMC_I2C_CH_CMD_WRITE);
while(I2C_MASTER_GetFlagStatus(&I2C_MASTER_0, XMC_I2C_CH_STATUS_FLAG_ACK_RECEIVED) == 0U)
{
// wait for ACK
}
I2C_MASTER_ClearFlag(&I2C_MASTER_0,XMC_I2C_CH_STATUS_FLAG_ACK_RECEIVED);
// select address
Adr_buf[0] = 0; // hi byte of start address to read
Adr_buf[1] = 0; // lo byte of start address to read
I2C_MASTER_StartTransmitDMA(&I2C_MASTER_0, 2, &Adr_buf[0]); // set address
while (I2C_MASTER_IsTxBusy(&I2C_MASTER_0));

I2C_MASTER_SendRepeatedStart(&I2C_MASTER_0, SLAVE_ADDRESS, XMC_I2C_CH_CMD_READ);
while(I2C_MASTER_GetFlagStatus(&I2C_MASTER_0, XMC_I2C_CH_STATUS_FLAG_ACK_RECEIVED) == 0U)
{
// wait for ACK
}
I2C_MASTER_ClearFlag(&I2C_MASTER_0,XMC_I2C_CH_STATUS_FLAG_ACK_RECEIVED);

I2C_MASTER_StartReceiveDMA(&I2C_MASTER_0, 2, rx_buf);
while (I2C_MASTER_IsRxBusy(&I2C_MASTER_0)); // programs stucks in while loop, rx interrupt from DMA not triggered
I2C_MASTER_SendStop(&I2C_MASTER_0);
}
else
{
XMC_DEBUG("main: Application initialization failed");
}
while(1U)
{
}
return 1U;
}


Attached also the logic analysis of the read operation. One time when it fails and one time when it is OK.

Thank you for your hints

Geri
0 Likes
0 Replies