I2C bootloader communication

Tip / Sign in to post questions, reply, level up, and achieve exciting badges. Know more

cross mob
pderocco
Level 3
Level 3
25 sign-ins 10 replies posted 5 questions asked

I'm trying to bootload a 4100S from a 4200BLE over I2C, as described in AN86526, using the standard commands included in the Bootloader component in the 4100, and the cybootloaderutils that came with PSoC Creator 4.4 in the 4200. The I2C works fine in normal operation--I originally had the two devices communicating with just a simple application in the 4100--but I'm now trying to make the 4100S upgradable.

The problem I'm having is that there doesn't seem to be any flow control across the I2C. For quick commands like Enter Bootloader, there is no issue, but when I send a Get Metadata command, it takes some time to prepare the response, during which time reading the response returns all FFs. Retrying it a few times eventually returns the correct response.

But when I issue a Program Row command, which takes a very long time, and attempt to read back the result before it's finished, it reads back a copy of the beginning of the Program Row command I just sent it. Bootloader.c uses the same buffer for reading and writing, but I would think that the slave I2C wouldn't respond with any data until the response had been prepared and Bootloader_WritePacket was called, at the end of the Bootloader_HostLink loop.

So question is: why is the slave returning the data I just sent it, instead of FFs? Since a valid packet always starts with 01, that would be an acceptable way to know when the response was valid. Has anyone else seen this behavior, and found a way to deal with it?

0 Likes
1 Solution
pderocco
Level 3
Level 3
25 sign-ins 10 replies posted 5 questions asked

Yes, I did, and that other thread matches what I've found. But I've found more, thanks to a logic analyzer.

When doing a time-consuming operation like Get Metadata (which checks the checksum on the app), I read FFs, so I simply repeat the read until it succeeds, which usually takes a total of three tries. That's fine. But when doing an operation that disables interrupts, like Program Row, it stretches the clock when I attempt to read the result until the programming is complete. But it still returns FFs once, so I have to repeat the read, which slows down the bootload process somewhat, given that there are hundreds of rows to program.

When I was receiving a copy of what I sent, it turned out that the I2C clock was being stretched not the usual 18ms for programming, but for a little over a second. My code has its own timeout, so it had long since given up, and what was sent was still in the buffer (which the receive would have overwritten). I haven't figured out what caused that, but after fixing a bunch of other bugs, it's not happening any more, so it's not worth trying to make it fail just to figure out why it used to fail.

Bottom line, everything is working now.

View solution in original post

0 Likes
2 Replies
ncbs
Moderator
Moderator
Moderator
500 replies posted 50 likes received 250 sign-ins

Hi @pderocco,

Have you created the bootloader host project as mentioned in section 2.3.3 Steps to Create an I2C Bootloader Host Project of AN86526?

This thread might explain why you receive FFs and how you are avoiding the same: https://community.infineon.com/t5/PSoC-5-3-1/PSOC5LP-Bootloader-i2c-Delay-After-Write/td-p/364666

Regards,
Nikhil

0 Likes
pderocco
Level 3
Level 3
25 sign-ins 10 replies posted 5 questions asked

Yes, I did, and that other thread matches what I've found. But I've found more, thanks to a logic analyzer.

When doing a time-consuming operation like Get Metadata (which checks the checksum on the app), I read FFs, so I simply repeat the read until it succeeds, which usually takes a total of three tries. That's fine. But when doing an operation that disables interrupts, like Program Row, it stretches the clock when I attempt to read the result until the programming is complete. But it still returns FFs once, so I have to repeat the read, which slows down the bootload process somewhat, given that there are hundreds of rows to program.

When I was receiving a copy of what I sent, it turned out that the I2C clock was being stretched not the usual 18ms for programming, but for a little over a second. My code has its own timeout, so it had long since given up, and what was sent was still in the buffer (which the receive would have overwritten). I haven't figured out what caused that, but after fixing a bunch of other bugs, it's not happening any more, so it's not worth trying to make it fail just to figure out why it used to fail.

Bottom line, everything is working now.

0 Likes