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

Connectivity nrf52840 with BMA400 (accelerometer) via I2C bus

Hi,

I start to work on the NRF52840 and I would like to read register of BMA400 in burst mode (I mean possibility to read further register in one sequence)

I am novice in C language :-)

Currently, I can read a register but only one

I use the following function to do it

//read byte from register
char I2cReadReg8(const nrf_drv_twi_t *twi_handle, uint8_t address, uint8_t sub_address){   
        ret_code_t err_code;
        uint8_t data; // `data` will store the register data     
        err_code = nrf_drv_twi_tx(twi_handle, address, &sub_address, sizeof(sub_address), true);
        if (NRF_SUCCESS == err_code)
            err_code = nrf_drv_twi_rx(twi_handle, address, &data, sizeof(data));
        APP_ERROR_CHECK(err_code);
        return data;
}

below is the function use on the previous function

__STATIC_INLINE
ret_code_t nrf_drv_twi_tx(nrf_drv_twi_t const * p_instance,
                          uint8_t               address,
                          uint8_t const *       p_data,
                          uint8_t               length,
                          bool                  no_stop)
{
    ret_code_t result = 0;
    if (NRF_DRV_TWI_USE_TWIM)
    {
        result = nrfx_twim_tx(&p_instance->u.twim,
                                address, p_data, length, no_stop);
    }
    else if (NRF_DRV_TWI_USE_TWI)
    {
        result = nrfx_twi_tx(&p_instance->u.twi,
                               address, p_data, length, no_stop);
    }
    return result;
}

I don't know how to perform a burst mode by using this function.Below an extract of the datasheet of the BMA in order to be clear :-)

thanks in advance

regards

Parents
  • Hello,

    I think the problem is that you are currently passing length=1 to nrf_drv_twi_rx(), which tells the driver to only receive one byte. I suggest you try to define 'data' as an array instead. The size of the array should reflect the number bytes you expect to receive in response to the command you are sending.

    uint8_t data [<number of bytes you expect to receive>];

    SDK driver documentation for reference: TWI master

    Best regards,

    Vidar

  • Hi

    Thanks for your reply.

    I tried to use an array as you propose to me, but it doesn't work.

    I think that my current function I2CReagReg8 doesn't respect the datasheet of BMA400 or BNO055 (see extract on my frist post). This function is done only to read one register.

    As shown on the datasheet, I need a function to perform a multiple read in one sequence.

    I just start to program in C. I am surprised to see that there is not already a function to perform that. It is used on BNO055, BMA400 and I think more others. I found many programs to read values of sensors, but they do a loop, so it is not a multiple read in one sequence, but multiple sequence to read n registers.

    regards

  • ciramor said:
    I tried to use an array as you propose to me, but it doesn't work.

    What didn't work? Do you have a logic analyzer trace that show what happened?

    How did you declare data and length when passed to nrf_drv_twi_rx()?

    When using twi with EasyDMA you are not intended to evaluate transfers on byte level, instead you prepare the write and read with the appropriate number of bytes that should be written and/or read, and then wait for the callback handler indicating the transfer is finished (if you not using callback handler then you simply wait for each call to return). This is the most CPU and power efficient approach.

    Here is an example I could find on devzone that show reading 1 byte and several bytes:
    https://devzone.nordicsemi.com/f/nordic-q-a/11032/i2c-how-do-i-specify-a-register-address-to-read-from-when-calling-nrf_drv_twi_rx 

    Kenneth

  • Hello,

    I checked my program and it seems to work now. Actually, I have no logic analyzer so I can't check that I am in burst mode . Below is my program

        ret_code_t err_code;
        uint8_t sample_data;
        uint8_t nSlaveAddr;
        uint8_t nRegAddr_L;
        uint8_t nRegAddr_M;
        uint16_t Acc_X;
        uint16_t Acc_Y;
        uint16_t Acc_Z;
        nRegAddr_L = 0x04;
        nSlaveAddr = BMA400_I2C_ADDRESS;
     
        
        uint8_t data[6]; // `data` will store the register data     
        err_code = nrf_drv_twi_tx(&m_twi, nSlaveAddr, &nRegAddr_L, sizeof(nRegAddr_L), true);
        if (NRF_SUCCESS == err_code)
           err_code = nrf_drv_twi_rx(&m_twi, nSlaveAddr, &data, sizeof(data));
        APP_ERROR_CHECK(err_code);


        Acc_X = (data[1] << 8) + data[0];
        Acc_Y = (data[3] << 8) + data[2];
        Acc_Z = (data[5] << 8) + data[4];


        NRF_LOG_INFO("Acc_X %d.", Acc_X)
        NRF_LOG_FLUSH();
        NRF_LOG_INFO("Acc_Y %d.", Acc_Y)
        NRF_LOG_FLUSH();
        NRF_LOG_INFO("Acc_Z %d.", Acc_Z)
        NRF_LOG_FLUSH();

    When I move my board, values change so it is a good news. Now i have to find how to convert data in float  with the signe (if you have an idea :-) ) !! and check that  values are relevant !!

    thanks

  • hello,

    I'm also working on sensor BMA400 and my task is the "How to count continue steps count ?"

    and interfacing with nRF52 MCU. In that I got all axis output but now I have to do step counting  and that data I have to shear with user smart phone using BLE. And in a day it's reset the sensor.

    If u solve the problem then please help me to sort out this problem.....

    Thank you, 

Reply Children
No Data
Related