I am working on the I2C master mode and I2C slave mode using edma and interrupt method on K64F MCU.
I connect two k64F devices to test the I2C mode for master and slave.
The master I2C us used the edma to read 5 bytes data on slave address 0x50, subaddress 0x01.
The slave responds the 5 bytes data are 0xF0, 0xF0, 0xF0, 0xF0, and 0xF0.
In fact, the real dates are 0xF0, 0xF0, 0xF0, 0xF0 and 0xB0
Even the dates are 0xFF, 0xFF, 0xFF, 0xFF, and 0xFF and the master receive 0xFF, 0xFF, 0xFF, 0xFF and 0xBF.
It seems the Bit 6 is set as Low Bit on the last bytes and the wave form is shown as below,
I have no idea what is going on ?
The master code is below,
uint8_t len = 5;
masterXfer.slaveAddress = 0x50; //SlaveAddr_7BIT
masterXfer.direction = kI2C_Read;
masterXfer.subaddress = (uint32_t) 0x01;
masterXfer.subaddressSize = 1;
masterXfer.data = rxBuff;
masterXfer.dataSize = len;
masterXfer.flags = kI2C_TransferDefaultFlag;
result = I2C_MasterTransferEDMA(I2C2, &I2C2_eDMA_Handle, &masterXfer);
On the slave side (another device), it responds the dates when the mater requests.
An I2C slave interrupt method is used to be as slave device and the IRQHandler code is below,
#define I2C_SLAVE_BASEADDR I2C2
uint8_t status = I2C_SlaveGetStatusFlags(I2C_SLAVE_BASEADDR);
I2C_SLAVE_BASEADDR->S = kI2C_IntPendingFlag;
if (status & kI2C_AddressMatchFlag) //0x40
if(status & kI2C_TransferDirectionFlag)
/* Change direction to send data. */
I2C_SLAVE_BASEADDR->C1 |= I2C_C1_TX_MASK;
/* Start to send data in tx buffer. */
g_slaveTxIndex = 0;
g_SlaveDirationFlag = true;
if (g_SlaveDirationFlag == true) //slave send data
I2C_SLAVE_BASEADDR->D = 0xF0; //0xFF
if((g_slaveTxIndex -1) == 5)
/* Switch to receive mode. */
I2C_SLAVE_BASEADDR->C1 &= ~(I2C_C1_TX_MASK | I2C_C1_TXAK_MASK);
/* Read dummy to release bus. */
g_SlaveDirationFlag = false;
g_slaveTxIndex = 0;
/* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F
Store immediate overlapping exception return operation might vector to incorrect interrupt. */
#if defined __CORTEX_M && (__CORTEX_M == 4U)
Can I ask why are you asking for a scope picture from the slave - shouldn't it be identical to the waveform that andyhsu put in his post?
andyhsu, can I make a suggestion in your debugging? Rather than load the TX register with a set value, could you set up an array with differing values or generate the values algoithmically (simply incrementing a variable would do) and pass that to I2C_SLAVE_BASEADDR->D? I'm wondering if the interrupt handler isn't loading the TX register in time for the read and you're getting a previous/invalid value or something is getting copied into the register when you do the dummy read to release the bus. By replying with differing values, you should see if this is happening.
Sorry, I don't have any experience with coding an I2C slave device (I swing more towards the master side of things) but based on my experience in debugging sent blocks of the same data, I would be suspicious that you're sending the data that you think you are in the first place. That should be verified first to see if you have a problem with the last byte sent or there's a problem right from the start.