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

TWI Garbage Data

Hi everyone,

I am having problems in getting the twi peripheral to work properly with the accelerometer I am using ( NXP MM8653FC).

I am getting some wierd issues, firstly I can't store the result from the TWI_RX in a local variable

for example

static void MM8653_deviceID()
{
		
		m_xfer_done = false;
		ret_code_t err_code;
		uint8_t reg[1] = {WHO_AM_I};
		uint8_t rx_buff;
    
		err_code = nrf_drv_twi_tx(&m_twi, MM8653FC, reg, 1, true);
    APP_ERROR_CHECK(err_code);	
		while(!m_xfer_done)
		{
			__WFE();
		}
		
		err_code = nrf_drv_twi_rx(&m_twi, MM8653FC, &rx_buff, 1);
    APP_ERROR_CHECK(err_code);
		
		while(!m_xfer_done)
		{
			__WFE();
		}
		NRF_LOG_INFO("ID: %X \r\n", rx_buff[0]);
		NRF_LOG_FLUSH();
}

Does not work, as the value of rx_buff doesnt get updated unless I move into outside of the function as a global variable or delcare it as static.

I understand this is to do with the local variable being out of scope but I can't see how as the function does not exit until the TWI operation has finished through

checking the !m_xfer_done flag.

My other problem is this, if I put 

memset(rx_buf, 0, sizeof(rx_buf));
  just before twi_rx is called, then rx_buff ( uint8_t array) is always 0 and doesnt get updated, which I am finding trouble to understand why.

Finally I can't call two seperate twi_rx functions back to back, I get a fatal error. If I put a delay of 500ms, I get garbage data, ie instead of getting 5A for the id I get 4?? 

int main(void)
{
    APP_ERROR_CHECK(NRF_LOG_INIT(NULL));

    NRF_LOG_INFO("\r\nTWI sensor example\r\n");
    NRF_LOG_FLUSH();
    twi_init();
		nrf_delay_ms(500);	
	  MM8653_init();
    MM8653_deviceID();  
    while (true)
    {
				nrf_delay_ms(1000);
				MM8653_readData();
				nrf_delay_ms(1000);
				MM8653_deviceID();
        NRF_LOG_FLUSH();
    }
}

ReadData function

static void MM8653_readData()
{
		m_xfer_done = false;
		ret_code_t err_code;
		uint8_t reg[1] ={OUT_X_MSB};

		err_code = nrf_drv_twi_tx(&m_twi,MM8653FC, reg, 1, true);
    APP_ERROR_CHECK(err_code);	
		while(!m_xfer_done)
		{
			__WFE();
		}
		
		err_code = nrf_drv_twi_rx(&m_twi, MM8653FC, rx_buff, 1);
    APP_ERROR_CHECK(err_code);
		
		while(!m_xfer_done)
		{
			__WFE();
		}
		NRF_LOG_INFO("X: %d , Y: %d , Z: %d \r\n", rx_buff[0],rx_buff[1],rx_buff[2]);
		NRF_LOG_FLUSH();
}

Whole Program Code

#include <stdio.h>
#include "boards.h"
#include "app_util_platform.h"
#include "app_error.h"
#include "nrf_drv_twi.h"
#include "nrf_delay.h"

#define NRF_LOG_MODULE_NAME "APP"
#include "nrf_log.h"
#include "nrf_log_ctrl.h"

/* TWI instance ID. */
#define TWI_INSTANCE_ID     0

/* Acclerometer registers */
#define MM8653FC 0x1D

#define CTRL_REG1 0x2A
#define OUT_X_MSB 0x01
#define OUT_Y_MSB 0x03
#define OUT_Z_MSB 0x05

#define WHO_AM_I 0x0D 



/* Indicates if operation on TWI has ended. */
static volatile bool m_xfer_done = false;

/* TWI instance. */
static const nrf_drv_twi_t m_twi = NRF_DRV_TWI_INSTANCE(TWI_INSTANCE_ID);

/* Buffer for samples read from temperature sensor. */
static uint8_t m_sample;
static uint8_t rx_buff[24]= {0}; 



/**
 * @brief TWI events handler.
 */
void twi_handler(nrf_drv_twi_evt_t const * p_event, void * p_context)
{
    switch (p_event->type)
    {
        case NRF_DRV_TWI_EVT_DONE:
            
            m_xfer_done = true;
            break;
        default:
            break;
    }
}

/**
 * @brief UART initialization.
 */
void twi_init (void)
{
    ret_code_t err_code;

    const nrf_drv_twi_config_t twi_config = {
       .scl                = TWI_SCL_PIN,
       .sda                = TWI_SDA_PIN,
       .frequency          = NRF_TWI_FREQ_100K,
       .interrupt_priority = APP_IRQ_PRIORITY_HIGH,
       .clear_bus_init     = false
    };

    err_code = nrf_drv_twi_init(&m_twi, &twi_config, twi_handler, NULL);
    APP_ERROR_CHECK(err_code);

    nrf_drv_twi_enable(&m_twi);
}



static void MM8653_deviceID()
{
		
		m_xfer_done = false;
		ret_code_t err_code;
		uint8_t reg[1] = {WHO_AM_I};
		
		err_code = nrf_drv_twi_tx(&m_twi, MM8653FC, reg, 1, true);
    APP_ERROR_CHECK(err_code);	
		while(!m_xfer_done)
		{
			__WFE();
		}
		
		err_code = nrf_drv_twi_rx(&m_twi, MM8653FC, rx_buff, 1);
    APP_ERROR_CHECK(err_code);
		
		while(!m_xfer_done)
		{
			__WFE();
		}
		NRF_LOG_INFO("ID: %X \r\n", rx_buff[0]);
		NRF_LOG_FLUSH();
}

static void MM8653_init()
{
		m_xfer_done = false;
		ret_code_t err_code;
		uint8_t reg[2] = {CTRL_REG1, 0xFF};
		err_code = nrf_drv_twi_tx(&m_twi, MM8653FC, reg, sizeof(reg), false);
    APP_ERROR_CHECK(err_code);	
		while(!m_xfer_done)
		{
			__WFE();
		}	
}

static void MM8653_readData()
{
		m_xfer_done = false;
		ret_code_t err_code;
		uint8_t reg[1] ={OUT_X_MSB};

		err_code = nrf_drv_twi_tx(&m_twi,MM8653FC, reg, 1, true);
    APP_ERROR_CHECK(err_code);	
		while(!m_xfer_done)
		{
			__WFE();
		}
		
		err_code = nrf_drv_twi_rx(&m_twi, MM8653FC, rx_buff, 1);
    APP_ERROR_CHECK(err_code);
		
		while(!m_xfer_done)
		{
			__WFE();
		}
		NRF_LOG_INFO("X: %d , Y: %d , Z: %d \r\n", rx_buff[0],rx_buff[1],rx_buff[2]);
		NRF_LOG_FLUSH();
}

/**
 * @brief Function for main application entry.
 */
int main(void)
{
    APP_ERROR_CHECK(NRF_LOG_INIT(NULL));

    NRF_LOG_INFO("\r\nTWI sensor example\r\n");
    NRF_LOG_FLUSH();
    twi_init();
		nrf_delay_ms(500);	
	  MM8653_init();
    MM8653_deviceID();  
    while (true)
    {
				nrf_delay_ms(1000);
				MM8653_readData();
				nrf_delay_ms(1000);
				MM8653_deviceID();
        NRF_LOG_FLUSH();
    }
}

Thank you so muhc for the help, much appreicated!

Rgs,

Bryan Hsieh

------------------------------------------------------------------------------------

UPDATE: 21/05/18

Problem solved, it turns out that I forgot to set m_xfer_done to false before the second the transaction causing unpredictable behavior.

Parents Reply Children
No Data
Related