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

I2C in nrf51 SDK

I want to interface ADXl345 with nrf51 SDK. suppoose my device address is 0x53 and register address is 0x2D and i want to write value 8. now nordic i2c has function nrf_drv_twi_tx with attributes nrf_drv_twi_t const *const p_instance, uint8_t address, uint8_t const * p_data, uint32_t length, bool xfer_pending

now here my address is 0x53, length is 6. now can you tell me where to write register address? where to write data??

Parents
  • This should do it (includes the setup):

    //global variables
    static uint8_t data[2] = {0x2D, 8};    //contains register + data to be written to register
    #define ADXL345_ADDR        0x53U
    
    //local code
    uint32_t ret_code;
    static const nrf_drv_twi_t           p_twi_instance = NRF_DRV_TWI_INSTANCE(0);
    
    const nrf_drv_twi_config_t p_twi_config = {
       .scl                = SCL_PIN,
       .sda                = SDA_PIN,
       .frequency          = NRF_TWI_FREQ_400K,
       .interrupt_priority = APP_IRQ_PRIORITY_LOW
    };
    
    //Initiate twi driver with instance and configuration values
    ret_code = nrf_drv_twi_init(&p_twi_instance, &p_twi_config, twi_handler, NULL); 
    APP_ERROR_CHECK(ret_code); // Check for errors in return value
    
    nrf_drv_twi_enable(&p_twi_instance); // Enable the TWI instance
    
    ret_code = nrf_drv_twi_tx(&p_twi_instance, ADXL345_ADDR, data, sizeof(data), false);
    
  • You need to wait for the transfer to finish before returning the data and the data array needs to be globally declared. For example the read data should be like this:

    uint8_t tx_data[2];
    
    uint16_t read_data(nrf_drv_twi_t const * const  m_twi_adxl_345,uint8_t i2cAddress, uint8_t reg) 
    {
    
        uint32_t           err_code;
        uint8_t data[2] = {0, 0};
        uint8_t value;
    
        tx_done = false;
        //Use xfer_pending true for repeated start (no need to send start condition and address again)
        err_code = nrf_drv_twi_tx(m_twi_adxl_345,ADXL345_ADDR , data, sizeof(data), true);
        APP_ERROR_CHECK(err_code);
        
        while(tx_done == false);  //wait for TX transfer to be done
        rx_done = false;
        err_code =  nrf_drv_twi_rx(m_twi_adxl_345,ADXL345_ADDR,data,sizeof(data),false);
        APP_ERROR_CHECK(err_code);
    
        while(rx_done == false);  //wait for RX transfer to be done
        value = (data[0] << 8) | data[1];
        return value;
    }
    

    This is not efficient code as it busy-waits, but it should work. rx_done and tx_done should be set to true respectively in the twi_handler function.

Reply
  • You need to wait for the transfer to finish before returning the data and the data array needs to be globally declared. For example the read data should be like this:

    uint8_t tx_data[2];
    
    uint16_t read_data(nrf_drv_twi_t const * const  m_twi_adxl_345,uint8_t i2cAddress, uint8_t reg) 
    {
    
        uint32_t           err_code;
        uint8_t data[2] = {0, 0};
        uint8_t value;
    
        tx_done = false;
        //Use xfer_pending true for repeated start (no need to send start condition and address again)
        err_code = nrf_drv_twi_tx(m_twi_adxl_345,ADXL345_ADDR , data, sizeof(data), true);
        APP_ERROR_CHECK(err_code);
        
        while(tx_done == false);  //wait for TX transfer to be done
        rx_done = false;
        err_code =  nrf_drv_twi_rx(m_twi_adxl_345,ADXL345_ADDR,data,sizeof(data),false);
        APP_ERROR_CHECK(err_code);
    
        while(rx_done == false);  //wait for RX transfer to be done
        value = (data[0] << 8) | data[1];
        return value;
    }
    

    This is not efficient code as it busy-waits, but it should work. rx_done and tx_done should be set to true respectively in the twi_handler function.

Children
No Data
Related