I am working with the PSoC 6 BLE module (CYBLE-416045-02) and am having a lot of trouble with the behavior of the I2C bus. Everything works great except for one error I am getting, but it is fatal when it happens. Luckily (and unluckily) I am able to reproduce it with my hardware easily.
I have a custom designed PCB, with a number of I2C peripherals attached. One of them is a familiar audio codec which is used by the cypress TFT shield (the ak4954a), but this happened with a different audio amp previously (for likely the same reason) and this particular device is causing some problems with the I2C bus which I cannot recover from.
The problem is that I keep the audio codec powered down in hardware, and then turn it on (with a gpio connected to an i2c controlled gpio expander) when it is needed.
About 20% of the time, when I power on this amp, my next I2C transaction gets a failure on I2C_MasterSendStart.
The return code on the first failure is always 11149316 (0x00aa2004). After this first failure, every single I2C transaction will receive a failure on I2C_MasterSendStart as well, but with error code 11149314 (0x00aa2002), which basically means the device can no longer function because the i2c bus is in an unusable state.
I am not 100% sure what those two errors mean, but from what I can tell, 0xaa refers to this being an error (CY_PDL_STATUS_ERROR), the 0x02 just indicates the SCB I2C ID (1<<13), and the 0x04 part of the first error is the important bit which indicates that it is a CY_SCB_I2C_MASTER_MANUAL_ADDR_NAK, which means:
"The slave NACKed the address."
After that first error, all of the other errors appear to be from: CY_SCB_I2C_MASTER_NOT_READY which means:
"The master is not ready to start a new transaction.
* Either the master is still processing a previous transaction or in the
* master-slave mode, the slave operation is in progress."
Simply doing a cpu reset, not even a power cycle, is sufficient to recover the device operation. Unfortunately that isn't a practical solution in production, so I am hoping to find a way to restart the i2c bus without restarting the CPU bus.
I believe the issue is ultimately caused because the amp is powering up during some other transaction, and causing some contention on the bus when it wakes up mid-transaction. Of course I can try to implement a locking system so that all other threads are locked out from i2c access until the amp is powered up, but I want to also solve the root issue in case this happens randomly.
I am using FreeRTOS on this particular build, and there are at least 4 threads with access to the i2c bus. I implemented a thread-safe i2c accessor method which is definitely sharing the bus safely, so I do not think that is related to the issue.
Thanks for any help!