Unable to Read or write MMA8652 registers using TWI

saiteja gravatar image

asked 2017-04-19 06:47:08 +0100

updated 2017-04-22 15:43:23 +0100

[https://drive.google.com/open?id=0Byj...]

hi i am working on MMA8652 i am working on mma7660 twi example in sdk11 for nrf52. i have changed the registers as the same way the MMA8652 need. here is my read and write functions

to read data:-

#define MMA8652_I2C_ADDR                (0x1D)

uint8_t W_reg = MMA8652_REG_WHO_AM_I;

    err_code=nrf_drv_twi_tx(&m_twi_mma_8652, MMA8652_I2C_ADDR, &W_reg, sizeof(W_reg), false);

    APP_ERROR_CHECK(err_code);

    nrf_delay_ms(5);

    err_code = nrf_drv_twi_rx(&m_twi_mma_8652, MMA8652_I2C_ADDR, &W_reg, sizeof(W_reg));

    APP_ERROR_CHECK(err_code);

when i am going to run this the application is going to stuck.

and also i have one doubt. in sdk twi example there is one function for reading, in that example in twi handler directly reading from device address. and the result is going to structure instance with x,y,x,tilt.

here is that function

typedef struct

{

    elem_t  x;

    elem_t  y;

    elem_t  z;

    uint8_t tilt;


} sample;

err_code = nrf_drv_twi_rx(&m_twi_mma_8652, MMA8652_I2C_ADDR, (uint8_t*)&sample, sizeof(sample));

how it is possible to read directly from MMA8652_I2C_ADDR(0X1D)

if i am using same procedure i am getting x value is always 0 and y, z values are varying. is this procedure is correct to read x,y,z data from the accelerometer.

EDIT:-------

void twi_handler(nrf_drv_twi_evt_t const * p_event, void * p_context) { ret_code_t err_code; static sample_t m_sample;

switch(p_event->type)
{
case NRF_DRV_TWI_EVT_DONE:
    //string_send("1twirxsuc\r\n");
    if ((p_event->type == NRF_DRV_TWI_EVT_DONE) &&
            (p_event->xfer_desc.type == NRF_DRV_TWI_XFER_TX))
    {
        if(m_set_mode_done != true)
        {
            m_set_mode_done  = true;
            return;
        }
        m_xfer_done = false;
        err_code = nrf_drv_twi_rx(&m_twi_mma_8652, 0X1D, (uint8_t*)&m_sample, sizeof(m_sample));
        if(err_code == NRF_SUCCESS){
            string_send("rx Done\r\n");
        }
        else
            string_send("rxfail\r\n");

        APP_ERROR_CHECK(err_code);
        if(err_code == NRF_SUCCESS){
            //string_send("2twi rx suc\r\n");
        }
    }
    else
    {
        //string_send("elsetwirx\r\n");
        read_data(&m_sample);
        m_xfer_done = true;

    }
    break;
default:
    break;
}

}

edit retag flag offensive close delete report spam

Comments

In the first code snippet, where does the program get "stuck"? Does nrf_drv_twi_tx or nrf_drv_twi_rx return an error code? If you do not tell the MMA8652 from which register address you're going to read from by performing a nrf_drv_twi_tx() before nrf_drv_twi_rx, then it will just start reading from register 0x00. If you take a look in the MMA8652 Datasheet, found here, you'll see that the OUT_X_MSB data starts from 0x01 and not 0x00 like the MMA7660. Register 0x00 is default set to 0x00 in the MMA8652, so thats probably why the x value stays zero. Thus, the first method is the better choice.

Bjørn Spockeli ( 2017-04-19 14:46:58 +0100 )editconvert to answer

the code stuck at nrf_drv_twi_tx

saiteja ( 2017-04-19 14:49:18 +0100 )editconvert to answer

is salve address for all MMA8652FC is 0X1D?

saiteja ( 2017-04-19 14:50:07 +0100 )editconvert to answer

Does nrf_drv_twi_tx return an error code? I do not understand what you mean by "is salve address for all MMA8652FC is 0X1D?"

Bjørn Spockeli ( 2017-04-19 16:43:13 +0100 )editconvert to answer

Hi, the error code is NRF_ERROR_BUSY

saiteja ( 2017-04-20 07:31:21 +0100 )editconvert to answer

If you take a look at the documentation of nrf_drv_twi_tx you'll see that nrf_drv_twi_tx returns NRF_ERROR_BUSY if there is a transfer on going. Like the TWI sensor example you have to wait for the previous transfer to finish by waiting for the m_xfer_done to be set in the twi event handler, i.e.

while(m_xfer_done == false);
err_code=nrf_drv_twi_tx(&m_twi_mma_8652, MMA8652_I2C_ADDR, &W_reg, sizeof(W_reg), false);
APP_ERROR_CHECK(err_code);
m_xfer_done = false;

while(m_xfer_done == false);
err_code = nrf_drv_twi_rx(&m_twi_mma_8652, MMA8652_I2C_ADDR, &W_reg, sizeof(W_reg));
APP_ERROR_CHECK(err_code);
m_xfer_done = false;
Bjørn Spockeli ( 2017-04-20 10:37:40 +0100 )editconvert to answer

i am getting NRF_SUCCESS after nrf_drv_twi_tx but now i am getting NRF_BUSY for nrf_drv_twi_rx.

saiteja ( 2017-04-20 18:54:03 +0100 )editconvert to answer

i have one doubt if i want to read data from register i need to TX register address and Then i need to read. here my MMA8652_I2C_ADDR is 0X1D but in the mma8652 documentation, it is saying that use 0X3A for tx and 0X3B for rx operation. but i am unable to get register data even if done both methods. and also i am getting NRF_SUCCESS return code. i s there any simple application to just read and write from MMA8652FC. thank you. and also did i need to put the MMA8652 in standby and Active for both tx and rx operations.

saiteja ( 2017-04-21 07:33:30 +0100 )editconvert to answer

I afraid that we do not have any example for communicating with the MMA8652FC. Can you post the twi_event_handler function?

Bjørn Spockeli ( 2017-04-21 09:13:15 +0100 )editconvert to answer

updated my Question? with twi_event_handler function, please find it. EDIT:--

saiteja ( 2017-04-21 09:56:44 +0100 )editconvert to answer

Could you try to just set the m_xfer_done flag in the twi handler and nothing else, i.e.

case NRF_DRV_TWI_EVT_DONE:
    //string_send("1twirxsuc\r\n");
    if ((p_event->type == NRF_DRV_TWI_EVT_DONE) &&
            (p_event->xfer_desc.type == NRF_DRV_TWI_XFER_TX))
    {
        if(m_set_mode_done != true)
        {
            m_set_mode_done  = true;
            return;
        }
        m_xfer_done = true;
    }
Bjørn Spockeli ( 2017-04-21 11:31:19 +0100 )editconvert to answer

hi i have tried with that, it is showing NRF_SUCCESS on both TX andRX operation. but i am getting empty value on reg_read buffer.

saiteja ( 2017-04-21 14:08:57 +0100 )editconvert to answer

Atleast the TWI operations are returning NRF_SUCCESS. Can you verify that you're writing to the correct register? Do you have a logic analyzer or similar so that you can perform a logic trace?

Bjørn Spockeli ( 2017-04-21 14:16:38 +0100 )editconvert to answer

i do not have logic analyzer

saiteja ( 2017-04-21 14:20:40 +0100 )editconvert to answer

Ok, try reading other registers and see if you get any thing other than zeroes. If you still get zeroes and you are sure that the addresses are correct, then the only thing I can suggest is that you need to check if the connections are correct.

Bjørn Spockeli ( 2017-04-21 14:23:35 +0100 )editconvert to answer

@saiteja: Did you try my suggestions?

Bjørn Spockeli ( 2017-04-26 14:37:15 +0100 )editconvert to answer

yes but it is not working. so that i am using twi_master example it is working fine and i able to read and write to the registers.

saiteja ( 2017-04-26 16:39:40 +0100 )editconvert to answer

but in SDK it is showing that twi_master is deprecated.

saiteja ( 2017-04-26 16:40:33 +0100 )editconvert to answer

Yes, the twi_master driver is deprecated in favor of the new nrf_drv_twi.c driver. Unfortunately, I do not have a MMA8652 that I can test against. I modified the twi_sensor example in SDK v11.0.0 so that its more inline with the snippets I've put in the comments. It first does a nrf_drv_twi_tx to tell the MMA7660 which register it should read from, in this case MMA7660_REG_XOUT. Then it reads 3 bytes which is MMA7660_REG_XOUT, MMA7660_REG_YOUT and MMA7660_REG_ZOUT and prints it to the uart. Here is the main file: main.c

Bjørn Spockeli ( 2017-04-27 15:40:20 +0100 )editconvert to answer