The last couple of days, I just started using the LPI2C SDK projects for KL28Z-based target-custom board we are developing. The only examples are labeled b&b (board-to-board).
The KL28Z MCU is the master and the slave device is the PCA8561 LCD display driver IC and they are both mounted on the same custom board we are developing. These 2 IC's are the only 2 devices talking with each other on our custom board.
I think I have setup all device address, sub-address (registers), buffer, count and all other pertinent parameters in order to complete an I2C transmit message.
I've tried adapting both polling_master and interrupt_master SDK code - to transmit from KL28 MCU to a slave device which is NXP PCA8561 LCD display driver IC.
I need to transmit control settings & data to the LCD driver in order for it to display to our 6 character x 7 segment LCD.
When I do breakpoint tracing inside MCUXpresso, all parts of the message from START command & payload "succeed" in getting to the LPI2C 4-word "FIFO". (Not sure if they went out the bus because the PC-based logic analyzer I'm using does not trigger on any signal, whether rising, falling, or low or high signal.)
However, the code hangs on "STOP" (auto-stop has been disabled in the SDK code). Even when I tried enabling STOP right before the STOP command is put on FIFO, it just hangs. Based on the comments on the code, it the "master remains busy so it can't detect the stop".
Even without touching any of the original code except changing the ports & pins pinmux.c values to use those on our custom board, the code hangs on "STOP". The original code has 33 bytes to transmit. I have 12 bytes to send to the LCD driver. I reduced the byte count to only 1 thinking it might be the size of the FIFO that's causing trouble. Still the STOP command not detected persists so the transmission "hangs".
So I'm not sure if the SDK code example I'm using is correct, or if I'm missing to setup something else besides what's on the base code.
I'm not sure if the slave driver IC is hosed if that's what's causing the MCU to not send out something & I'm not detecting any trigger on the logic analyzer PC-tool.
I have to admit, I have not thoroughly read through all the LPI2C control & status registers settings so I am ignorant to most of those bits. Can someone please tell me where to look or investigate in order to know how I can fix this problem?
Thank you very much for the help.
Dear Felipe and Mark,
As always, you are great responders with good answers to questions.
In this case though, it is all my fault.
Your answers do not apply, because the mistake in setup is mine.
I apologize for this delay, but I was able to transmit I2C message properly since Monday but didn't have a chance to go back here until now.
My main & only mistake was in pinmux.c setup of ALT# :-(.
When I was reviewing & re-reviewing everything from the start, I know all port assignments are correct but as far as the
ALT# function operation was it was not setup for I2C.
Again I apologize for my error & for wasting your time to help figure this out for me.
I'll do my best to really review everything first before I post the question. I guess I thought I set everything correctly & I just lost hope so I turned to the forum.
Thank you very much for your research, questions & help.
If you are not detecting the STOP condition it may be because you are not sending the STOP correctly or something on the bus is holding signals in a state that doesn't allow it to be generated (it doesn't matter if the slave doesn't ACK since the stop condition transmission is not dependent on the slave) - check the transmission with an analyser to see whether the STOP is seen or not.
Check that on the final transmitted or received byte the stop detect interrupt is being enabled and the stop condition is being sent.
As reference from the uTasker LPI2C driver:
ptrLPI2C->LPI2C_MIER = LPI2C_MIER_SDIE; // disable transmit/receive interrupts and enable stop detect interrupt
ptrLPI2C->LPI2C_MTDR = LPI2C_MTDR_CMD_STOP; // send stop condition
In case of firmware difficulties try the uTasker project (it is free and supported) and contains fool-proof I2C (with the advantage that it has only one compatible driver that works on any Kinetis part, with either LPI2C, single or double buffered designs so no code rewrites or other libraries are needed when re-using code in other products.
It also allows I2C simulation and will even simulate I2C slave parts to allow complete development, testing and debugging without the need for HW (and greatly improved product development speed).
See also the following which discusses undocumented LPI2C bugs that were found when the uTasker I2C driver implementation was originally developed (be careful with the use or AUTOSTOP settings....): LPI2C Bug?
Complete Kinetis solutions for professional needs, training and support:http://www.utasker.com/kinetis.html
uTasker: supporting >1'000 registered Kinetis users get products faster and cheaper to market
Have you connected the pull-up resistors to your SCL and SDA lines?
Are you able to see the ACK by the slave in your communication? According to the PCA8561 datasheet, the I2C trace should look like the following when writing to a register.