[EDIT] Fixed the problem. Turns out I needed to enable the SION bit in the IOMUX configuration.
/* FIXED */
Got my custom i.MXRT1051 board up and running (600 MHz, Rev. A1 silicon) and now troubleshooting LPI2C1 configured on pins GPIO_AD_B1_00 (SCL) and GPIO_AD_B1_01 (SDA).
The problem is that after issuing the start bit, the device's I2C address is not sent. The I2C clock continues indefinitely but the 4 octet FIFO never shifts out data. The device's I2C address has been verified to make its way through the function calls and is indeed a part of the MTDR register (verified by copying to a 32-bit intermediate register and snooping with the debugger before being written to MTDR).
Baud rate is programmed to be 100 kbps and actual rate comes in at about 98 kbps, so the baud rate and divisors appear to be working properly.
Upon issue of the first programming command for the CODEC, the LPI2C1 module (MCUXpresso) issues a start condition on the I2C line. The SDA line drops for one bit time and then returns high, and the SCL clock line continues ad infinitum--no device address is sent out the SDA line following the I2C start bit.
Tracking through the code with the debugger shows propagation through the I2C state machines until we get to the
LPI2C_MasterStop function at which time the stop bit never is issued. Status code from LPI2C_MasterGetStatus() is 0x3000000 which is BBF | MBF flags. Stop is waiting for 0x200 flag. I've turned on a timeout mechanism so that my code doesn't get hung up.
In general, the FIFO doesn't transmit data out, so after two such calls the 4-octet FIFO becomes full and then no further state machine propagation happens. But for the first two (2-byte) transactions, the SCL line repeats forever and the only bit visible on SDA is the initial start bit, then SDA remains HIGH while SCL toggles.
My LPI2C_MasterGetDefaultConfig initializer is configured as:
masterConfig->enableMaster = true;
masterConfig->debugEnable = true;
masterConfig->enableDoze = true;
masterConfig->ignoreAck = false;
masterConfig->pinConfig = kLPI2C_2PinOpenDrain;
masterConfig->baudRate_Hz = 100000U;
masterConfig->busIdleTimeout_ns = 0;
masterConfig->pinLowTimeout_ns = 0;
masterConfig->sdaGlitchFilterWidth_ns = 0;
masterConfig->sclGlitchFilterWidth_ns = 0;
masterConfig->hostRequest.enable = false;
masterConfig->hostRequest.source = kLPI2C_HostRequestExternalPin;
masterConfig->hostRequest.polarity = kLPI2C_HostRequestPinActiveHigh;
The initializer code automatically negates the enableDoze flag to make it 0 when putting it in the configuration register. I'm only using two-wire I2C mode.
FWIW code is copied from Flash into ITCM and DTCM memories. Also, I've disabled both ITCM and DTCM caches (although only DTCM cache I disabled if I'm not using the debugger). The variables are all stored in DTCM and appear to be working properly.
Can anyone think of why the device I2C address won't get set on the initial push of the start bit or why the FIFO won't transmit any data out? I think I've enabled the clock gates as expected. Also, my clock source is USB1PLL and has been configured for 10 MHz for I2C. The divisor in the clock_config is originally 0 (/1) and the prescaler is /8 giving an I2C base clock of 60 MHz if I don't override the divisor to 6 yielding a 10 MHz I2C base clock. I've also tried using a 60 MHz base clock with exactly the same results.
Thoughts? Thanks in advance.
--Scott Thompson, TC Helicon
Hi Scott Thompson,
-> I've turned on a timeout mechanism so that my code doesn't get hung up.
Will you please explain this?
I got the following error,
LPI2C_MasterStop status: 0x3000000 , kLPI2C_MasterStopDetectFlag: 0x200, kLPI2C_MasterTxReadyFlag: 0x1
LPI2C_MasterStop status: 0x3000000 , kLPI2C_MasterStopDetectFlag: 0x200, kLPI2C_MasterTxReadyFlag: 0x1
LPI2C_MasterStop status: 0x3000400 , kLPI2C_MasterStopDetectFlag: 0x200, kLPI2C_MasterTxReadyFlag: 0x1
BOARD_LPI2C_Send LPI2C_MasterStop call failed for base: 0x57247000
Error: Failed to init the LCD panel
Thank You,
Vinoth S,
Hello,
vinothkumar s wrote:
-> I've turned on a timeout mechanism so that my code doesn't get hung up.
Will you please explain this?
Boy this was an eternity ago... IIRC because the status bit was never getting set properly the I2C module would just hang here. I added a piece of breakout code so that the loop wouldn't continue forever (I2C would fail but it wouldn't hang my program). It was only used for testing.
Once I found that I needed to set the SION bit in the IOMUX the I2C module worked exactly as expected and I didn't need to do anything else. I can't explain why you're getting errors; I'm quite removed from this now but if you're having issues with I2C and your code perhaps you can start a different thread (this one has been marked as answered) so that an ongoing discussion can be made specific to your needs.
Best,
Scott
Thanks, Scott. Your help was extremely useful to solve the very same issue.
I really can't understand why neither the latest MCUXpressoIDE (11.3 in this moment) or the latest Pin Tool don't automatically set the SION bit in the configuration.
Giuseppe
Hello Scott Thompson,
Thank you for updating this thread, I'm sure it will help other Community users.
Regards,