This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

I2C Slave with TWI not sending all data

We have an nRF52840 setup as a slave to communicate with a motor controller. I connected a logic analyzer to the lines to confirm the data being sent across. There are 18 data points that get sent on a read request. I hard coded the values to be sent in order to confirm they are received on the other side. Only the first value sent is received, the rest come across as zeros.

We are using nRF Connect SDK V1.2.0 for board nrf52840_pca10056.

When NRFX_TWIS_EVT_READ_REQ is received in the twis_event_handler, we call a function we call I2C_requestEvent() that steps through each of the data points to send with the nrfx_twis_tx_prepare() function. After each data point called in a tx_prepare function I then serial print out the value to verify what should have been sent.

Here is the code section:

nrfx_err_t I2C_requestEvent()
{  
    nrfx_err_t err;
    volatile uint16_t zero = 0;

    err = nrfx_twis_tx_prepare(&m_twis, (void *)&MsgToPicolo.AM_Idle, sizeof(MsgToPicolo.AM_Idle));
    printk("Idle1= %d ", MsgToPicolo.AM_Idle);
    printk("err= %X\n",err);
    err = nrfx_twis_tx_prepare(&m_twis, (void *)&zero, sizeof(zero));
    printk("Idle2= %d ", MsgToPicolo.AM_Idle);
    printk("error= %X\n",err);

    err = nrfx_twis_tx_prepare(&m_twis, (void *)&MsgToPicolo.AM_BrakingStiffness, sizeof(MsgToPicolo.AM_BrakingStiffness));
    //err = nrfx_twis_tx_prepare(&m_twis, 0, 1);
    err = nrfx_twis_tx_prepare(&m_twis, (void *)&zero, sizeof(zero));
    printk("Braking: %d ", MsgToPicolo.AM_BrakingStiffness);
    printk("error= %X\n",err);
    
    err = nrfx_twis_tx_prepare(&m_twis, (void *)&MsgToPicolo.AM_StopRequest, sizeof(MsgToPicolo.AM_StopRequest));
    //err = nrfx_twis_tx_prepare(&m_twis, 0, 1);
    err = nrfx_twis_tx_prepare(&m_twis, (void *)&zero, 1);
    printk("Stop: %d ", MsgToPicolo.AM_StopRequest);
    printk("error= %X\n",err);

    err = nrfx_twis_tx_prepare(&m_twis, (void *)&MsgToPicolo.AM_TopSpeed, sizeof(MsgToPicolo.AM_TopSpeed));
    //err = nrfx_twis_tx_prepare(&m_twis, 0, 1);
    err = nrfx_twis_tx_prepare(&m_twis, (void *)&zero, 1);
    printk("TopSpeed: %d ", MsgToPicolo.AM_TopSpeed);
    printk("error= %X\n",err);

    err = nrfx_twis_tx_prepare(&m_twis, (void *)&MsgToPicolo.AM_AccelerationFactor, sizeof(MsgToPicolo.AM_AccelerationFactor));
    //err = nrfx_twis_tx_prepare(&m_twis, 0, 1);
    err = nrfx_twis_tx_prepare(&m_twis, (void *)&zero, 1);
    printk("Acceleration: %d ", MsgToPicolo.AM_AccelerationFactor);
    printk("error= %X\n",err);

    err = nrfx_twis_tx_prepare(&m_twis, (void *)&MsgToPicolo.AM_UserWeight, sizeof(MsgToPicolo.AM_UserWeight));
    //err = nrfx_twis_tx_prepare(&m_twis, 0, 1);
    err = nrfx_twis_tx_prepare(&m_twis, (void *)&zero, 1);
    printk("Userweight: %d ", MsgToPicolo.AM_UserWeight);
    printk("error= %X\n",err);

    err = nrfx_twis_tx_prepare(&m_twis, (void *)&MsgToPicolo.AM_DriveDuration, sizeof(MsgToPicolo.AM_DriveDuration));
    //err = nrfx_twis_tx_prepare(&m_twis, 0, 1);
    err = nrfx_twis_tx_prepare(&m_twis, (void *)&zero, 1);
    printk("DriveDuration: %d ", MsgToPicolo.AM_DriveDuration);
    printk("error= %X\n",err);

    err = nrfx_twis_tx_prepare(&m_twis, (void *)&MsgToPicolo.AM_GearUp, sizeof(MsgToPicolo.AM_GearUp));
    //err = nrfx_twis_tx_prepare(&m_twis, 0, 1);
    err = nrfx_twis_tx_prepare(&m_twis, (void *)&zero, 1);
    printk("GearUp: %d ", MsgToPicolo.AM_GearUp);
    printk("error= %X\n",err);

    err = nrfx_twis_tx_prepare(&m_twis, (void *)&MsgToPicolo.AM_GearDown, sizeof(MsgToPicolo.AM_GearDown));
    //err = nrfx_twis_tx_prepare(&m_twis, 0, 1);
    err = nrfx_twis_tx_prepare(&m_twis, (void *)&zero, 1);
    printk("GearDown: %d ", MsgToPicolo.AM_GearDown);
    printk("error= %X\n",err);
    printk("Finish transmission\n");
  

  return err;
}

On the Logic analyzer and the drive controller IC in debug mode, I see: 

I2C_Data_Sent

The bottom line is the clock signal, the top is the data. 

The serial print was:

NRFX_TWIS_EVT_WRITE_REQ

Op code 0

Received Event: 8

NRFX_TWIS_EVT_WRITE_DONE

Request event

 

Idle= 4 error= bad0000                             //4 gets sent

Braking: 1 error= bad0000                        //0 gets sent

Stop: 0 error= bad0000                             //0 gets sent

TopSpeed: 4 error= bad0000                    //0 gets sent

Acceleration: 5 error= bad0000                 //0 gets sent

Userweight: 1 error= bad0000                   //0 gets sent

DriveDuration: 6 error= bad0000               //0 gets sent

GearUp: 0 error= bad0000                         //0 gets sent

GearDown: 0 error= bad0000                    //0 gets sent

 

Finish transmission

NRFX_TWIS_EVT_READ_DONE

NRFX_TWIS_EVT_GENERAL_ERROR

The error bad0000 means no error.

I'm not sure what to do.

Related