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

cross mob
LuBe_4654241
Level 4
Level 4
50 sign-ins 25 replies posted 25 sign-ins

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

0 Likes
1 Solution

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;
}

View solution in original post

0 Likes
4 Replies
LuBe_4654241
Level 4
Level 4
50 sign-ins 25 replies posted 25 sign-ins

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.

 

0 Likes
LuBe_4654241
Level 4
Level 4
50 sign-ins 25 replies posted 25 sign-ins

Hi,

Can Cypress engineer answer ?

Best regards

LB

0 Likes
Alakananda_BG
Moderator
Moderator
Moderator
50 likes received 250 sign-ins 250 replies posted

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

Alakananda
0 Likes

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;
}

0 Likes