Incorrect frames in non blocking TWI TX xfer

Hi,

I am using the non blocking TWI on the nrf 52840 with the following code:

void hal_drv_charger_set_current_768mA(void)
{   

    uint8_t frame[5] = {0x0F, 0xF0, 0x0F, 0xF0, 0x0F};
    
    // Transfer type
    m_hal_drv_charger.xfer.twi_xfer.type = NRF_DRV_TWI_XFER_TX;

    // Length 
    m_hal_drv_charger.xfer.twi_xfer.primary_length = 5;

    // Copy the frame pointer
    m_hal_drv_charger.xfer.twi_xfer.p_primary_buf = &frame[0];
    
    //nrf_delay_ms(100);

    // Add i2c xfer
    hal_drv_pwr_i2c_add_xfer(&m_hal_drv_charger.xfer);
}

The xfer is handled like this:

static void launch_xfer_state(void) {
    
    NRF_LOG_INFO("Launch xfer");

    //We are not in wait xfer state
    if(m_hal_drv_pwr_i2c.state != WAIT_XFER_PWR_I2C_ST)
    {

      // If the XFER queue contains XFERs
      if (!nrf_queue_is_empty(&pwr_i2c_xfer_queue)) 
      {

        // Get the XFER from the XFER queue
        if(nrf_queue_pop(&pwr_i2c_xfer_queue, &m_hal_drv_pwr_i2c.xfer) == NRF_SUCCESS)
        {

          if (m_hal_drv_pwr_i2c.xfer.twi_xfer.type == NRF_DRV_TWI_XFER_TXRX)
          { 
            //Catch the return data pointer
            preturn = m_hal_drv_pwr_i2c.xfer.twi_xfer.p_secondary_buf;
          }
          
          // Performs the XFER call on the PWR_I2C TWI instance
          memcpy(sent_buff, m_hal_drv_pwr_i2c.xfer.twi_xfer.p_primary_buf, 5);
          xfer_desc = m_hal_drv_pwr_i2c.xfer.twi_xfer;
          primary_length = m_hal_drv_pwr_i2c.xfer.twi_xfer.primary_length;
          //m_hal_drv_pwr_i2c.xfer.twi_xfer.primary_length = 4;

          NRF_LOG_INFO("First byte sent is : %d", sent_buff[0]);
          NRF_LOG_INFO("Second byte sent is : %d", sent_buff[1]);
          NRF_LOG_INFO("Third byte sent is : %d", sent_buff[2]);
          NRF_LOG_INFO("4 byte sent is : %d", sent_buff[3]);
          NRF_LOG_INFO("5 byte sent is : %d", sent_buff[4]);
          NRF_LOG_INFO("Frame length is : %d", primary_length);

          // Performs the XFER call on the PWR_I2C TWI instance
          result = nrf_drv_twi_xfer(&i2c_twi, &m_hal_drv_pwr_i2c.xfer.twi_xfer, 0);//NRF_DRV_TWI_FLAG_NO_XFER_EVT_HANDLER
          m_hal_drv_pwr_i2c.state = WAIT_XFER_PWR_I2C_ST;
          run_xfer_fsm();
        }

        else 
        {
        //error handler if you can't get the XFER from the XFER queue
        }

      }

      else //If the XFER queue is empty
      {
		  // Goes to IDLE state
		  m_hal_drv_pwr_i2c.state = IDLE_PWR_I2C_ST;
		  run_xfer_fsm();
      }

    }
	
    else //We are in wait state
    {
            //Do nothing
    }
}

TWI config is

static void init_state(void) {

    // On state transition
    if (m_hal_drv_pwr_i2c.state != m_hal_drv_pwr_i2c.prev_state) {

        // Set the entry phase done
        m_hal_drv_pwr_i2c.prev_state = m_hal_drv_pwr_i2c.state;

        // Initialize the TWI driver
        ret_code_t err_code = nrf_drv_twi_init(&i2c_twi, &i2c_twi_config, twi_event_handler, NULL);//twi_event_handler
        //herat
        APP_ERROR_CHECK(err_code);
        nrf_drv_twi_enable(&i2c_twi);

        // Reset the XFER queue
        nrf_queue_reset(&pwr_i2c_xfer_queue);

        // Goes to IDLE state
        m_hal_drv_pwr_i2c.state = IDLE_PWR_I2C_ST;
    }
}

and

static nrf_drv_twi_config_t i2c_twi_config =
{                                                                                
    .frequency          = (nrf_drv_twi_frequency_t)NRF_DRV_TWI_FREQ_100K, 
    .scl                = SCL_PWR_PIN,                                                    
    .sda                = SDA_PWR_PIN,                                                    
    .interrupt_priority = TWI_DEFAULT_CONFIG_IRQ_PRIORITY,                       
    .clear_bus_init     = TWI_DEFAULT_CONFIG_CLR_BUS_INIT,                       
    .hold_bus_uninit    = TWI_DEFAULT_CONFIG_HOLD_BUS_UNINIT,                    
};

The twi_event_handler is empty.

Here is what I see on RTT:

The result on oscilloscope is good for the first byte, but then its only 0 ..: (slave address is 0x6A):

Thanks

Parents
  • Hi again,

    I think the debugger is tricking with me... even if the breakpoint is before all the send, I don't get errors in normal mode (slave reacts as I expect..).

    Sorry for the bother !

  • Hello again,

    I am not sure that I understand your last message here - are you no longer seeing the issue when you change the debugger breakpoints? I am not sure that I have understood what you meant correctly.

    Another reason for your issue  I could think of for this inconsistent behavior is that your frame array is not static, and so it will fall out of scope when the non-blocking function completes, which in turns frees the memory up for use elsewhere, which could lead to erratic values in the buffer. Please add the static keyword to your declaration to avoid this being an issue.

    Best regards,
    Karl

Reply
  • Hello again,

    I am not sure that I understand your last message here - are you no longer seeing the issue when you change the debugger breakpoints? I am not sure that I have understood what you meant correctly.

    Another reason for your issue  I could think of for this inconsistent behavior is that your frame array is not static, and so it will fall out of scope when the non-blocking function completes, which in turns frees the memory up for use elsewhere, which could lead to erratic values in the buffer. Please add the static keyword to your declaration to avoid this being an issue.

    Best regards,
    Karl

Children
Related