3 Replies Latest reply on Oct 14, 2020 1:45 AM by user_2581831

    PSoc as I2C Master and ST as I2C Slave

    user_2581831

      Hi,

      I want to implement I2C communication between PSOC and ST.

      I've configured PSoc as I2C Master and ST as I2C Slave. I've succesfully transferred data from PSoc to ST but I'couldn't read data from ST.

       

      Here's the details about my implemention.

       

      When I use I2C_Write_Data function on PSoc side, I didn't encounter a problem about the data transmission to ST from PSoC

       

      I'didnt implement I2C Slave on ST side before. I may have used wrong APIs or made some configuration mistakes.

      I've attached the images about the implementation. (Codes and Configuration). I'll be appreciated if you illuminate me about this problem. This is my second post on this web site so that please ignore my faults about this topic that I have )

       

      Have a nice day..

       

      1- ST I2C Slave Code

      ST_I2C_Code.PNG

      2- St CubeMx I2C Slave Configuration

      ST_CubeMx_I2C_Conf.PNG

      3- Cypress I2C Master Functions

       

      Cypress_I2C_Code.PNG

      4- Cypress I2C Configuration

       

      Cypress_I2C_Conf.PNG

        • 1. Re: PSoc as I2C Master and ST as I2C Slave
          GaneshD_41

          Hi,

           

          Can you please follow the recommended firmware flow for I2C_Write and I2C_Read from PSoC?

           

          uint8 WriteCommandPacket(uint8 command)

          {

              uint8 errorStatus = 0;

              uint8 status = TRANSFER_ERROR;

             

              /* Create packet to send to slave */

              CreateCommandPacketBuffer(command);

             

              /* Send start condition */

              if(0u == mI2C_I2CMasterSendStart(I2C_SLAVE_ADDR, mI2C_I2C_WRITE_XFER_MODE, I2C_TIMEOUT))

              { 

                  /* Write bytes from the write buffer to the Slave */

                  uint8 cnt = 0;

                  do

                  {

                      /* Write byte and recieve ACK/NACK */

                      errorStatus = mI2C_I2CMasterWriteByte(buffer[cnt], I2C_TIMEOUT);

                      ++cnt;

                  }   

                  while((errorStatus == mI2C_I2C_MSTR_NO_ERROR) && (cnt < WR_BUFFER_SIZE));

              }

             

              /* Transfer succeeds send stop and return Success */

              if((errorStatus == mI2C_I2C_MSTR_NO_ERROR)      ||

                 (errorStatus == mI2C_I2C_MASTER_CMD_M_NACK))

              {

                  if(mI2C_I2CMasterSendStop(I2C_TIMEOUT) == mI2C_I2C_MSTR_NO_ERROR)

                  {

                      status = TRANSFER_CMPLT;

                  }

              }

             

              return(status);

          }   

           

           

          static uint8 ReadStatusPacket(void)

          {  

              uint8 errorStatus;

              uint8 status = TRANSFER_ERROR;

             

              /* Send start condition and store read bytes in rdBuffer[] until end of buffer is reached */

              errorStatus = mI2C_I2CMasterSendStart(I2C_SLAVE_ADDR, mI2C_I2C_READ_XFER_MODE, I2C_TIMEOUT);

              if(errorStatus == mI2C_I2C_MSTR_NO_ERROR)

              {

                  uint8 cnt = 0;

                  uint8 cmd = mI2C_I2C_ACK_DATA;

                 

                  do

                  {

                      if (cnt == (RD_BUFFER_SIZE - 1U))

                      {

                          /* Send NACK on last byte */

                          cmd = mI2C_I2C_NAK_DATA;

                      }

                      /* Read data from slave and store in rdBuffer[] */

                      errorStatus = mI2C_I2CMasterReadByte(cmd, rdBuffer + cnt, I2C_TIMEOUT);

                      ++cnt;

                  }

                  while ((errorStatus == mI2C_I2C_MSTR_NO_ERROR) && (cnt < RD_BUFFER_SIZE));

              }

             

              /* If read succeeds, send stop condition and return success */

              if ((errorStatus == mI2C_I2C_MSTR_NO_ERROR)     ||

                  (errorStatus == mI2C_I2C_MASTER_CMD_M_NACK))

              {

                  if (mI2C_I2CMasterSendStop(I2C_TIMEOUT) == mI2C_I2C_MSTR_NO_ERROR)

                  {

                      /* Check that data read from the slave is correct */

                      if ((BUFFER_SOP == rdBuffer[RD_BUFFER_SOP_POS]) &&

                          (BUFFER_EOP == rdBuffer[RD_BUFFER_EOP_POS]) &&

                          (STS_CMD_DONE == rdBuffer[RD_BUFFER_STS_POS]))

                      {

                          status = TRANSFER_CMPLT;

                      }

                  }   

              }

              return(status);

          }

           

          The above code is taken from the attached I2C_Master Low level code example. Please refer it once.

           

          Also, please create the post in ST's Forum also so that you can get support from their community also

           

          Thanks

          Ganesh

          • 2. Re: PSoc as I2C Master and ST as I2C Slave
            user_2581831

            Hi,

             

            Thanks for replying my question, but I've tried the example I2C project on the attachment and it didn't work for me. I think there's some kind of synchronization problem occuring between master and slave device when reading data from slave device on master side. I still couldn't figure out how to solve problem.

             

            Have a nice day.

            Thanks.

            • 3. Re: PSoc as I2C Master and ST as I2C Slave
              user_2581831

              Hi,

               

              I've solved the problem by increasing the timeout values of I2C functions both on PSoC and ST side and changing I2CM_I2C_ACK_DATA to I2CM_I2C_NAK_DATA on PSoC side..I've updated the timeout values as 0xFF instead of 200 on both side. and I've set up the data rate of  communication  as 400khz as fast mode. Here's the functions that I have used for proper operation.

               

              //PSoC I2C Master //

              //Functions and Definitions//

              #define I2C_TIMEOUT 0xFF

              #define SLAVE_ADDR 0x43

              void I2C_Write_Data(uint8_t Slave_Address, uint8_t I2C_Data)

              {

                   I2CM_I2CMasterSendStart(Slave_Address, I2CM_I2C_WRITE_XFER_MODE,I2C_TIMEOUT);

                   I2CM_I2CMasterWriteByte(I2C_Data, I2C_TIMEOUT);

                   I2CM_I2CMasterSendStop(I2C_TIMEOUT);

              }

              uint8_t I2C_Read_Data(uint8_t Slave_Address)

              {

                   uint8_t I2C_BUFFER = 0;

                   I2CM_I2CMasterSendStart(Slave_Address, I2CM_I2C_READ_XFER_MODE,I2C_TIMEOUT);

                   I2CM_I2CMasterReadByte(I2CM_I2C_NAK_DATA, &I2C_BUFFER, I2C_TIMEOUT);

                   I2CM_I2CMasterSendStop(I2C_TIMEOUT);

                   return I2C_BUFFER;

              }

              //Main_Function//

              I2C_Write_Data(SLAVE_ADDR, 0xA0);

              uint8_t I2C_RECEIVE_BUF = I2C_Read_Data(SLAVE_ADDR); // Returns the same data that's sent to the ST Slave. 0xA0.

               

               

              //ST I2C Slave - Main Function//

              uint8_t I2C_BUFFER = 0;

              while(HAL_I2C_GetState(&hi2cs) != HAL_I2C_STATE_READY);

              HAL_I2C_Slave_Receive(&hi2cs, &I2C_BUFFER, 1, HAL_MAX_DELAY);

               

              switch(I2C_BUFFER)

              {

                   case 0xA0:

                        uint8_t I2C_TRANSMIT_BUFFER = 0xA0;

                        HAL_I2C_Slave_Transmit(&hi2cs, &I2C_TRANSMIT_BUFFER,1,HAL_MAX_DELAY);

                   break;

              }