Hi! I am trying to setup a simple I2C slave driver on the Imx8QM. At this moment I have a driver that receives the address that I have set in the SAMR->ADDR0 register. I can read this value from the SASR->RADDR register just fine when the status register bitfield adress valid flag SSR->AVF is set.
I am using the ACKSTALL bit in the first configuration register SCFGR1->ACSTALL, to give the SW driver time to read the address and data, before sending out a ACK/NACK using STAR->TXNACK.
After the SSR->RDF (receive data flag) is set high I try to read the slave receive data register (SRDR) and then transmit another ACK. Physically, this works as the RDF flag is set high the receive data register is read to clear the RDF flag, and the ack is transmitted. Confirmed by measuring the signals. The problem is that anytime the Slave Receive Data register SRDR is read, I only get 0. It never changes.. So it seems like the slave receives data, reacts to it, but the data register is not set.
The flow of the driver is as follows:
1. Reset fifos/data registers and slave peripheral
2. Disable slave peripheral
3. Set ackstall
4. set slave address0
5. enable slave peripheral
6. wait for adress valid flag
7. read RADDR bitfield and transmit ack-> gives correct address
8. Wait for Receive data flag to be set
9. Read slave receive data register and transmit ack-> always returns 0
I have based this design on the I.MX 8QuadMax Application Processor Reference Manual Reference Rev. 0, 9/2021. Chapter 17.6
Hello,
I don’t know if you are working on either the Cortex-A or the Cortex-M side, so whichever you are using you may use our driver as an example.
For Cortex-A please refer to the Linux driver:
https://github.com/nxp-imx/linux-imx/blob/lf-6.1.y/drivers/i2c/busses/i2c-imx-lpi2c.c
For Cortex-M please refer to the SDK driver:
https://github.com/nxp-mcuxpresso/mcux-sdk/tree/main/drivers/lpi2c
Saludos,
Aldo.
Thanks for your reply @AldoG!
I am using the A-cores with linux. From a quick glance, without testing anything, I see that there is one additional register in the c-driver which is the "LPI2C_SRDROR 0x178 /* i2c slave receive data read only */", and the use of interrupts. Do you know if interrupts and/or dma is required by the slave to get or transmit data? Or is it possible to do with polling the flags that are in the SSR register?
Hello,
it is not mandatory to do it this way, but please note that using polling in a Cortex-A slow peripheral is not recommended.
Saludos,
Aldo.