I am using K20 running MQX4.2 connected to the I2C bus in slave mode (and always in slave mode).
My application requires the I2C master to send the device address and a control byte, the K20 responds with 20 bytes.
If the master sends an I2C write, the K20 sees the control byte (fread(..)). If the master sends I2C read, the K20 never returns from the fread(...) (I'm expecting the fread to return the Control byte) and thus never sends it data (fwrite(...)).
I suspect the MQX4.2 slave I2C code does not support the I2C control byte, which is base I2C protocol.
I have tried to send the control byte in one I2C transaction (write), then the I2C read transaction. The read transaction doesn't work either.
K20:
....ioctl(..., IO_IOCTL_I2C_SLAVE_MODE, ...);
...ioctl(...,IO_IOCTL_I2C_SET_STATION_ADDRESS);
...ioctl(...,IO_IOCTL_SET_RX_REQUEST, 1);
loop:
...fread(...); // looking for the control byte
...ioctrl(...., IO_IOCTL_I2C_STOP); // done
...fwrite(...); // data to send to the master.
...ioctrl(...., IO_IOCTL_I2C_STOP); // done
Hi Mark, I Have A solution for this behavior,at least it works for me.
I defined a polled mode (not interrupt)
then, in function "_ki2c_polled_rx_tx" there is a Do {} while() at the very beginning.
i changed it to:
do | |
{ | |
i2csr = i2c_ptr->S; | |
if (0 == (i2c_ptr->C1 & I2C_C1_MST_MASK)) | |
{ | |
if (i == length) | |
{ | |
return i; | |
} | |
if ((io_info_ptr->OPERATION & I2C_OPERATION_STARTED) && (0 == (i2csr & I2C_S_BUSY_MASK))) | |
{ | |
/* Addressed as slave */ | |
if (I2C_MODE_SLAVE == io_info_ptr->MODE) | |
{ | |
/* Transmit requested */ | |
if (i2csr & I2C_S_SRW_MASK) | |
{ | |
io_info_ptr->STATE = I2C_STATE_ADDRESSED_AS_SLAVE_TX; | |
if (0 == (io_info_ptr->OPERATION & I2C_OPERATION_READ)) | |
{ | |
if (i < length) | |
{ | |
i2c_ptr->C1 |= I2C_C1_TX_MASK; | |
i2c_ptr->S |= I2C_S_IICIF_MASK; | |
i2c_ptr->D = *buffer++; /* transmit data */ | |
io_info_ptr->STATISTICS.TX_PACKETS++; | |
} | |
} | |
else | |
{ | |
length = i; | |
} | |
} | |
} | |
else | |
{ | |
io_info_ptr->OPERATION = 0; | |
io_info_ptr->RX_REQUEST = 0; | |
io_info_ptr->STATE = I2C_STATE_FINISHED; | |
return i; | |
} | |
} | |
} | |
_time_delay(5); | |
} while (0 == (i2csr & I2C_S_IICIF_MASK)); |
and then i recompiled the BSP.
Hope It Helps
Adir
Hi, im curently experiencing the same issue as mark.
I recieve all data Ok.
When i get a "read" from the master something gets stuck in transmit routine, the data line gets from 1 to 0 and thats it.
Im using mqx 4.2 with the i2c slave example supplied by mqx.
Any help?
Hi Mark:
Not sure understand you correctly.
According to K20P100M72 reference manual, when master sends I2C read, master should send the address to slave, and the slave should prepare the data and write it to master.
There is a I2C slave demo under this folder.
C:\Freescale\Freescale_MQX_4_2\mqx\examples\i2c_slave
Regards
Daniel
I do believe I understand. I have looked at the project you called out, but didn't find it very helpful. It worked sometimes, but not all the time.
The MQX I2C driver (slave mode) sometimes to hangs up in an infinite loop waiting for the I2C to not be busy. But, the I2C bus is idle. Further, while sometimes, I can get some I2C communications, it proves unreliable. I suspect that the MQX controls (e.g. fopen, fread, fwrite, IOCTL) easily gets out of sync with the I2C bus.
I would appreciate some insight on how to make the MQX controls work reliability (i.e. all the time).
Hi Mark:
Thank you for your feedback about i2c slave demo. could you change the baud rate to see whether it works?
There exists an alternative MQX i2c driver, if you would like to give it a try, check the application note AN4652 and a patch for it on https://community.freescale.com/message/313948#313948
Regards
Daniel