PSoC5LP I2C Bootloader NACK on read command (bootloader resetting slave address)?

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

cross mob
KyTr_1955226
Level 6
Level 6
250 sign-ins 10 likes given 50 solutions authored

Hello all,

I'm running into a strange problem with bootloading a PSoC5LP device over I2C interface.

My bootloader host is a PC app using the cyusbserial.dll library.  During testing I was able to get this working, but there seems to be some funnies going on and I'd like to confirm a couple things.

What I'm finding is that I can jump to the bootloader from the application successfully, and then the "Enter Bootloader" packet is received and ACKed by the PSoC:

bootl_enter.JPG

Then about 13ms later, when the host sends the address(R), the PSoC NACKs:

bootl_read.JPG

My question is: does entering the bootloader reset the I2C Slave Address?

The reason I think this might be the case is that the design I am using has multiple PSoC devices on the I2C bus, and the slave addresses of each are determined at runtime via a switch on the PCB.  The switch controls a set address lines going to the PSoC devices, and the slave address of each is based on the reading from these pins, allowing each processor in the chain to have a unique address.  This is set on startup in both the application and bootloader projects like so:

#define I2C_BASE_ADDR = 0x40   //0x80 when left-justified

int main(void){

    SI2C_Start();

    SI2C_SlaveSetAddress(I2C_BASE_ADDR + ADR_Read());

    Bootloader_Start();

    for(;;)

    {

  

    }

}

The only reason I can think of where the enter_bootloader command would be ACKed, and the first read at the same address would be NACKed is that the entering the bootloader is changing the I2C Address after I'm setting it.  I'm having trouble figuring out where in code this might be happening.

SI2C_Start() definitely changes the address to the default set in the component as part of SI2C_Init(), but that's why I'm calling SI2C_SlaveSetAddress() afterward.  From what I can tell, SI2C_Init() should never be called again unless SI2C_Stop() is called first (SI2C_initVar gets reset to 0).

Can anyone confirm if this is the case?

Of course, if anyone has an idea as to what else the issue might be, I'm all ears.

Thanks!

0 Likes
1 Solution
KyTr_1955226
Level 6
Level 6
250 sign-ins 10 likes given 50 solutions authored

OK So I think I have this specific issue sorted out.

After some digging, I found that the failed read had to do with an error in entering the bootloader.

I only had SI2C_HwPrepareReadBuf_Callback() defined, so if the I2C transaction only contained a write from the master, my callback would never fire.

I am now properly entering the loader on command using SI2C_ISR_ExitCallback().

I also fixed the abnormally large ACKs when I came across this KBA:

Reduce Delay Observed During I2C Read Operations In USB-Serial – KBA227320

Now I'm running into a whole set of new issues, but that's a story for another thread.

Chalk this up to big user error.

View solution in original post

0 Likes
1 Reply
KyTr_1955226
Level 6
Level 6
250 sign-ins 10 likes given 50 solutions authored

OK So I think I have this specific issue sorted out.

After some digging, I found that the failed read had to do with an error in entering the bootloader.

I only had SI2C_HwPrepareReadBuf_Callback() defined, so if the I2C transaction only contained a write from the master, my callback would never fire.

I am now properly entering the loader on command using SI2C_ISR_ExitCallback().

I also fixed the abnormally large ACKs when I came across this KBA:

Reduce Delay Observed During I2C Read Operations In USB-Serial – KBA227320

Now I'm running into a whole set of new issues, but that's a story for another thread.

Chalk this up to big user error.

0 Likes