- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi,
I have the issue with my Cypress CYC4145FNI and EEPROM NV24C04LV: if during the communication with EEPROM (I2C) happen a reset the EEPROM keeps the SDA line to 0V and MCU can't access to EEPROM, all I2C functions don't work beacuse the peripheral is in busy state. What's the solution for unblocking the peripheral ?
Best regards
LB
Solved! Go to Solution.
- Labels:
-
PSoC 4 MCU
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi,
solved:
void I2cmBusClear( uint8 Rst )
{
uint32 RegVal;
uint32 RegValtemp;
uint8 Cnt;
uint8 Esc;
uint8 Err;
Err = FALSE;
if ( I2C_sda_Read() == 0 )
{
Esc = FALSE;
for ( Cnt = 0; Cnt < I2CM_BUS_CLEAR_CYC_MAX && Esc == FALSE; Cnt++ )
{
RegVal = CY_GET_REG32(I2C_scl__0__HSIOM);
RegValtemp = RegVal;
RegValtemp &= ~I2C_scl__0__HSIOM_MASK;
RegValtemp = CY_SET_REG32(I2C_scl__0__HSIOM, RegValtemp |(I2C_scl__0__HSIOM_GPIO << I2C_scl__0__HSIOM_SHIFT));
I2C_scl_SetDriveMode(I2C_scl_DM_STRONG);
I2C_scl_Write(I2C_I2C_SCL_LOW);
CyDelayUs(10);
I2C_scl_Write(I2C_I2C_SCL_HIGH);
CyDelayUs(10);
RegVal = CY_SET_REG32(I2C_scl__0__HSIOM, RegVal);
if ( I2C_sda_Read() )
Esc = TRUE;
}
if ( Rst )
{
I2C_I2CMasterSendStop(100);
I2C_I2CMasterClearStatus();
I2C_I2CMasterClearReadBuf();
I2C_I2CMasterClearWriteBuf();
}
if ( Esc == FALSE )
Err = TRUE;
}
return Err;
}
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi, on semiconductor has done an application note about this issue (https://www.onsemi.com/pub/Collateral/AND9472-D.PDF): the solution is send 9bits on clock, but the I2C peripheral is always busy, so no data can send out.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi,
Can Cypress engineer answer ?
Best regards
LB
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi,
You have to send 9 clock pulses by toggling the SCL line manually since the SCB cannot do it .
You can make the pin SW controlled pin, then toggle it by sending 9 clock pulses.
Regards
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi,
solved:
void I2cmBusClear( uint8 Rst )
{
uint32 RegVal;
uint32 RegValtemp;
uint8 Cnt;
uint8 Esc;
uint8 Err;
Err = FALSE;
if ( I2C_sda_Read() == 0 )
{
Esc = FALSE;
for ( Cnt = 0; Cnt < I2CM_BUS_CLEAR_CYC_MAX && Esc == FALSE; Cnt++ )
{
RegVal = CY_GET_REG32(I2C_scl__0__HSIOM);
RegValtemp = RegVal;
RegValtemp &= ~I2C_scl__0__HSIOM_MASK;
RegValtemp = CY_SET_REG32(I2C_scl__0__HSIOM, RegValtemp |(I2C_scl__0__HSIOM_GPIO << I2C_scl__0__HSIOM_SHIFT));
I2C_scl_SetDriveMode(I2C_scl_DM_STRONG);
I2C_scl_Write(I2C_I2C_SCL_LOW);
CyDelayUs(10);
I2C_scl_Write(I2C_I2C_SCL_HIGH);
CyDelayUs(10);
RegVal = CY_SET_REG32(I2C_scl__0__HSIOM, RegVal);
if ( I2C_sda_Read() )
Esc = TRUE;
}
if ( Rst )
{
I2C_I2CMasterSendStop(100);
I2C_I2CMasterClearStatus();
I2C_I2CMasterClearReadBuf();
I2C_I2CMasterClearWriteBuf();
}
if ( Esc == FALSE )
Err = TRUE;
}
return Err;
}