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

TWI Troubles With nRF51 DK and MMA8452 Accelerometer

I have an accelerometer that utilizes IC2 (NXP MMA8452Q) that I am trying to integrate with the nRF51 DK. The accelerometer is on a breakout board, and is wired up very simply using the SCL, SDA, and the power supply pins. I am basing the implementation on the BLE Central - BLE App UART example, as I am using that for another part of the project. The SDK is 12.1. I do not have a logic analyzer or scope.

The problem that I am seeing is that I'm not receiving any TWI events after using the nrf_drv_twi_rx() function. Sometimes, when I call this function, the nRF51 DK stalls or resets. Also, curisously, I am seeing two NRF_DRV_TWI_EVT_DONE events after calling the nrf_drv_twi_tx() function to wake and setup the accelerometer.

At this point, I would like to "wake" the accelerometer by writing 0x33 to the CTRL_REG1 register. After that, I would like to read the WHO_AM_I register to verify I2C/TWI operation. I should receive back a known byte value. So far, I have not seen any rx events.

I have tried both (0x1DU) and (0x1DU >> 1) for the acceleromter address.

Below is a typical printf log, and code is attached with some BLE central functions taken out for readability. What am I doing wrong?

Start TWI
TWI Initialized
twi_handler event.
NRF_DRV_TWI_EVT_DONE:
MMA8452 Setup and Wake Complete.
twi_handler event.
NRF_DRV_TWI_EVT_DONE:
WHO_AM_I Tx
twi_handler event.
NRF_DRV_TWI_EVT_DONE:
WHO_AM_I Tx
read_data() done

main_TWI_sample.c

Parents
  • I found the problem and got it working. In the nrf_drv_twi_tx call inside the data_read() function, I had the no_stop parameter set to false. When I set it to true, I was receiving the correct WHO_AM_I response.

    Below is the updated function for those who come across the same problem.

    /**
     * @brief Function for reading data from the accelerometer.
     */
    static void read_data()
    {
    		ret_code_t err_code;
    		uint8_t addr8 = WHO_AM_I;
    	
    		printf("WHO_AM_I Tx\r\n");
    
            m_xfer_done = false;
    		err_code = nrf_drv_twi_tx(&m_twi, MMA8452_ADDR, &addr8, 1, true);
    		printf("tx err_code is %d\r\n", err_code);
    		while (m_xfer_done == false);	
    
    		printf("WHO_AM_I Rx\r\n");
    	
    		m_xfer_done = false;
    		err_code = nrf_drv_twi_rx(&m_twi, MMA8452_ADDR, &m_sample, 1);
    		APP_ERROR_CHECK(err_code);
    		printf("rx err_code is %d\r\n", err_code);
    
    		while (m_xfer_done == false);	
    	
    		printf("read_data() done\r\n");
    }
    
Reply
  • I found the problem and got it working. In the nrf_drv_twi_tx call inside the data_read() function, I had the no_stop parameter set to false. When I set it to true, I was receiving the correct WHO_AM_I response.

    Below is the updated function for those who come across the same problem.

    /**
     * @brief Function for reading data from the accelerometer.
     */
    static void read_data()
    {
    		ret_code_t err_code;
    		uint8_t addr8 = WHO_AM_I;
    	
    		printf("WHO_AM_I Tx\r\n");
    
            m_xfer_done = false;
    		err_code = nrf_drv_twi_tx(&m_twi, MMA8452_ADDR, &addr8, 1, true);
    		printf("tx err_code is %d\r\n", err_code);
    		while (m_xfer_done == false);	
    
    		printf("WHO_AM_I Rx\r\n");
    	
    		m_xfer_done = false;
    		err_code = nrf_drv_twi_rx(&m_twi, MMA8452_ADDR, &m_sample, 1);
    		APP_ERROR_CHECK(err_code);
    		printf("rx err_code is %d\r\n", err_code);
    
    		while (m_xfer_done == false);	
    	
    		printf("read_data() done\r\n");
    }
    
Children
Related