PSOC4 BLE Module - I2C write buffer not working

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

cross mob
JiWa_1379161
Level 3
Level 3
5 sign-ins 10 replies posted 5 replies posted

I am trying to write several bytes to an eeprom over I2C. It seems the library has changed because previous code I have done this with no problem using the same module. I just cut and pasted the code and now everything stopped working. The old library version was 3.20, the new is 4.0

If I use the write byte or read byte as shown that works.

    int x;

    buffer[0] = 0xf8;       //node address

 

    I2C_1_I2CMasterSendStart(I2C_SLAVE_ADDR,0,1000);

    I2C_1_I2CMasterWriteByte(buffer[0],1000);  //data address

    I2C_1_I2CMasterSendRestart(I2C_SLAVE_ADDR,1,1000);

    for (x=0; x<7; x++)

    {

      I2C_1_I2CMasterReadByte(I2C_1_I2C_ACK_DATA,buffer,1000);

      deviceAddress=buffer[0];

    }

    I2C_1_I2CMasterReadByte(I2C_1_I2C_NAK_DATA,buffer,1000);

    deviceAddress=buffer[0];

    I2C_1_I2CMasterSendStop(1000);

If I want to write using a buffer as shown, no data is transferred. I have a I2C sniffer that shows all transactions on the line and all I get is the slave address sent. Nothing else, no data, no ACK, no stop.

  buffer[0]=0x02;//eeprom location for delayTime

  buffer[1]=delayTime>>8;

  buffer[2]=delayTime&0x00ff;

  i2cError = I2C_1_I2CMasterWriteBuf(I2C_SLAVE_ADDR, buffer, 3, I2C_1_I2C_MODE_COMPLETE_XFER);

The i2cError returned = 0;

Problem only occurs with write or read buffers, not write or read bytes.

CyGlobalIntEnable is called before any I2C requests.

Am I missing something?

0 Likes
1 Solution
MotooTanaka
Level 9
Level 9
Distributor - Marubun (Japan)
First comment on blog Beta tester First comment on KBA

Hi,

> I would like to know from Cypress why their library isnt working or if it is just a simple command I am missing.

OK, then you are on your own.

> even the code you provided will no longer work as is.

> You need to add an extra value to each function which is a timeout value.

BTW, in the same source file with the above code, I had lower level API onion skins, too,

which you don't have to care, though.

==================

uint32_t i2c_SendStart(uint8_t rw)

{

    return(I2C_I2CMasterSendStart(i2c_slave_address, (uint32_t)rw, TIMEOUT_MSEC));

}

uint32_t i2c_SendRestart(uint32_t bitRnW)

{

    return(I2C_I2CMasterSendRestart(i2c_slave_address, bitRnW, TIMEOUT_MSEC));

}

uint32_t i2c_SendStop(void)

{

    return(I2C_I2CMasterSendStop(TIMEOUT_MSEC));

}

uint8_t  i2c_readByte(uint32_t acknak) /* 6-Mar-2018 acknak added */

{

    uint8_t data ;

    (void)I2C_I2CMasterReadByte(acknak, &data, TIMEOUT_MSEC) ;  /* ignore error */

    return( data ) ;

}

uint8_t  i2c_readReg(uint8_t addr)

{

    uint8_t data ;

    i2c_SendStart(0u) ; /* for write */

    i2c_writeByte(addr) ;

    i2c_SendRestart(0x1u) ; /* for read */

    CyDelay(1) ;

    data = i2c_readByte(I2C_I2C_NAK_DATA) ;

    i2c_SendStop() ;

    return( data ) ;

}

....

========================

moto

View solution in original post

0 Likes
3 Replies
MotooTanaka
Level 9
Level 9
Distributor - Marubun (Japan)
First comment on blog Beta tester First comment on KBA

Hi,

This may depending on the slave device, but in my sample below

MCU Tester, a Swiss Army Knife for PSoC (CY8CKIT-044 version)

I implemented i2c_readRegs() something like

======================

void i2c_readRegs(uint8_t addr, uint8_t *data, int len)

{

    int i ;

    i2c_SendStart(0u) ; /* for write */

    i2c_writeByte(addr) ;

    i2c_SendRestart(0x1u) ; /* for read */

    for (i = 0 ; i < len-1 ; i++ ) {

        CyDelayUs(i2c_delay) ;       

        data = i2c_readByte(I2C_I2C_ACK_DATA) ;

    }

        CyDelayUs(100) ;

    data = i2c_readByte(I2C_I2C_NAK_DATA) ;

    i2c_SendStop() ;

}

======================

I needed add CyDelayUs(i2_delay) after restart,

not sure if I need it for all bytes, though.

Some device worked with i2c_delay = 30,

but some required more .

So I added delay command which can change "i2c_delay".

moto

0 Likes

Hi Moto

Your way is an alternative. My issue is I have several projects all with the same code using the writeBuffer command. I really dont want to go back to each one and change the code as a work around. I would like to know from Cypress why their library isnt working or if it is just a simple command I am missing.

even the code you provided will no longer work as is. You need to add an extra value to each function which is a timeout value.

0 Likes
MotooTanaka
Level 9
Level 9
Distributor - Marubun (Japan)
First comment on blog Beta tester First comment on KBA

Hi,

> I would like to know from Cypress why their library isnt working or if it is just a simple command I am missing.

OK, then you are on your own.

> even the code you provided will no longer work as is.

> You need to add an extra value to each function which is a timeout value.

BTW, in the same source file with the above code, I had lower level API onion skins, too,

which you don't have to care, though.

==================

uint32_t i2c_SendStart(uint8_t rw)

{

    return(I2C_I2CMasterSendStart(i2c_slave_address, (uint32_t)rw, TIMEOUT_MSEC));

}

uint32_t i2c_SendRestart(uint32_t bitRnW)

{

    return(I2C_I2CMasterSendRestart(i2c_slave_address, bitRnW, TIMEOUT_MSEC));

}

uint32_t i2c_SendStop(void)

{

    return(I2C_I2CMasterSendStop(TIMEOUT_MSEC));

}

uint8_t  i2c_readByte(uint32_t acknak) /* 6-Mar-2018 acknak added */

{

    uint8_t data ;

    (void)I2C_I2CMasterReadByte(acknak, &data, TIMEOUT_MSEC) ;  /* ignore error */

    return( data ) ;

}

uint8_t  i2c_readReg(uint8_t addr)

{

    uint8_t data ;

    i2c_SendStart(0u) ; /* for write */

    i2c_writeByte(addr) ;

    i2c_SendRestart(0x1u) ; /* for read */

    CyDelay(1) ;

    data = i2c_readByte(I2C_I2C_NAK_DATA) ;

    i2c_SendStop() ;

    return( data ) ;

}

....

========================

moto

0 Likes