- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi,
I'm wondering because I have a problem with I2C Write operation during bootloader mode from I2C Master (another MCU) to I2C Slave (cypress). On bootloader-level, I'm using I2C, and on app-level I'm using EZI2C (here write commands works fine). I know EZI2C is more High-Level API and has two additional checkboxes "Accept matching address in RX FIFO" and "Accept general call address". There is some bigger difference which can prevent proper working?
Solved! Go to Solution.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi PaBr_4578176,
I understand the issue. Looks like since the master can not handle clock stretching and the slave is not getting enough time to ACK within the next clock pulse.
Some mitigation steps
1. Run the PSoC device in the max clock speed possible so that I2C ISR gets executed faster
2. Make the I2C interrupt priority as the highest so that it is not preempted by another ISR causing a delay in ACKing/ ACKing
3. This step could involve modifying the existing I2C source files:
Presently the component ACKs / NACKs in ISR. It can be made to ACK/ NACK completely in hardware by using the I2C_CTRL register.
By default the I2C_Start() sets [8:15] as 0x08. You can it to 0xF8 to make sure that the addr ack/ nack and data ready ack/ nack happens in hardware. But this might involve you to modify the i2c slave ISR to remove the software acking / nacking (<i2c_component>_I2C_INT.c)
Regards,
Bragadeesh
Bragadeesh
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi,
Can you let us know what is the difficulty you are facing with I2C slave and why you need EZI2C slave?
EZI2C is particularly useful when you have a fixed buffer, now in case of bootloader, depending on the command, the no of bytes will vary.
You can refer to the below app note for I2C bootloader
https://www.cypress.com/documentation/application-notes/an86526-psoc-4-i2c-bootloader
Regards
Alakananda
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
The problem I'm facing is that sometimes during write operation form I2C Master e.g. sending the "Enter bootloader" command (8 bytes with address), I get 1 NACK and 7 ACK, but sometimes the entire command is OK (ACK). When I want to read the response then I'm receiving 0xFF or 0x00 in all response.
I'm thinking about "The EZI2C Slave is a unique implementation of an I2C slave in that all communication between the master and slave is handled in the ISR (Interrupt Service Routine) and requires no interaction with the main program flow.". Is that can be significant in terms of my bootloader? What is more, I2C Master contains simplified the implementation of I2C, so maybe that is why not working with regular I2C but only with EZI2C?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi,
Can you send the screenshot of the waveform with us so that we can help you better.
Can you also share the project with us so that we can debug the issue at our end.
Regards
Alakananda
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I'm starting an analysis using an oscilloscope. I've observed something interesting:
Skipping the fact there is one byte too many on the right screen, I'm wondering what means that "breaks" (change to low for SCL and change to high for SDA) between bytes. (On the left is a test using bridge control panel and on the right test using custom microcontroller and cypress. When I use BCP everything works properly.
I attach also other screens. In the oscilloscope_test folder using the desirable solution. In the oscilloscope_test - BCP - Cypress folder using Bridge Control Panel.
https://drive.google.com/open?id=1K6oqsLz3s2VM-VeTQJi0cKKV4AYR7xUl
https://drive.google.com/open?id=13lnSs5zzUw-D9VC1fwznuk9g6gNRhZke
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi PaBr_4578176,
1. If it works fine with BCP then it looks like the slave implementation should be okay.
2. EZI2C doesn't fit the bootloading application since it has a fixed buffer size and requires an offset for operation.
We highly recommend you to share your project files so that we can try to debug the issue at our end for faster resolution.
Also, are you using PSoC as the host controller to bootload?
Did you check this app note on how to use an embedded host to perform bootloading? The app note uses UART communication but can be easily ported to I2C master.
https://www.cypress.com/file/45171/download
Regards,
Bragadeesh
Bragadeesh
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi PaBr_4578176,
The waveform for BCP looks fine. But I dont think the waveform of host controller looks good. As far from what I see, the slave looks to be NACKing even for address match. Please confirm. Would you be able to share the project with us for debugging?
Regards,
Bragadeesh
Bragadeesh
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Unfortunately, I would like to not share these projects, because this is a commercial solution.
As the Host controller used Renesas 78K0R.
In the documentation of this microcontroller we can read:
"11.1.3 Simplified I2C (IIC11, IIC20)
This is a clocked communication function to communicate with two or more devices by using two lines: serial clock
(SCL) and serial data (SDA). This simplified I2C is designed for single communication with a device such as EEPROM,
flash memory, or A/D converter, and therefore, it functions only as a master and does not have a function to detect wait
states"
.
I'm worried about this problem may be connected with clock stretching...
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
After waveform analysis, I confirm that also on the app-level commands are not exchanging properly. I would like to just read 4 bytes with data rate 20ms but sometimes the signal is ending after an address like on the screen below:
The signal is a little bit noisy because of not the ideal connection with probes.
I guess after address byte there is ACK, but a very short.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi PaBr_4578176,
I understand the issue. Looks like since the master can not handle clock stretching and the slave is not getting enough time to ACK within the next clock pulse.
Some mitigation steps
1. Run the PSoC device in the max clock speed possible so that I2C ISR gets executed faster
2. Make the I2C interrupt priority as the highest so that it is not preempted by another ISR causing a delay in ACKing/ ACKing
3. This step could involve modifying the existing I2C source files:
Presently the component ACKs / NACKs in ISR. It can be made to ACK/ NACK completely in hardware by using the I2C_CTRL register.
By default the I2C_Start() sets [8:15] as 0x08. You can it to 0xF8 to make sure that the addr ack/ nack and data ready ack/ nack happens in hardware. But this might involve you to modify the i2c slave ISR to remove the software acking / nacking (<i2c_component>_I2C_INT.c)
Regards,
Bragadeesh
Bragadeesh
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Kindly thank you for the great tips! I have taken the following steps:
1. Run the PSoC device in the max clock speed possible so that I2C ISR gets executed faster
2. Set the I2C interrupt priority as the highest so that it is not preempted by another ISR causing a delay in ACKing/ NACKing.
And I’ve observed the problem with NACK after the address byte on the app-level (EZI2C) seems to be resolved.
Now, the problem is with a bad response from the bootloader… The data in the bootloader are still exchanging incorrectly.
So, now my clock on the bootloader-level is setting like on the screen below:
I would like to just write enter bootload command, then 20ms delay and read response from the bootloader. On the screen below we can observe something weird, after send first write byte address SDA is pulled and stuck to low:
Do you know what is going on here? Do you think I should introduce also a 3.?