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

nrf52832 Fatal error in the code, in order to read the TWI raw data

Hi, 

I have been working with the NRF52832, and trying to capture raw ADC data with the help of TWI bus. I have imported the necessary libraries (i'll attach the code below in order to make it more clear) and i'm stuck on the last part inside the int main(). Every other command is getting executed, apart from the last one where it says NRF_LOG_INFO("data received"). I have done some debugging and i found out, that the code above this part works well. It shows a fatal error,at the point of the "Data received" command. 

So, any help i get regarding the code will be helpful. 

}

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

#define TWI_INSTANCE 0


#define BNO_055  0x28  //the BNO_055 has two modes, one for read and one for write, i.e. 0x28 and 0x29//
#define QUA_Data_w_LSB  0x23   //this is the register data, which we are trying to send out// 
#define PWR_MODE 0x3E  // this specifies the mode in which the BNO_055 operates, i.e. Normal mode//

static volatile bool m_xfer_done = false;
static const nrf_drv_twi_t m_twi = NRF_DRV_TWI_INSTANCE(TWI_INSTANCE);

/* bufer for samples to read*/
static uint8_t m_data = 90; //random data, which will be overwritten with the data in the QUA_Data_w_LSB data//
static uint8_t OPERATION_MODE_ADD[1] = {0x3D};
static uint8_t NDOF_MODE[1] = {0x0C};

void BNO_handler(nrf_drv_twi_evt_t const *p_event, void *p_context )
{
	switch (p_event->type) //all the events, which could possobly take place//
	{
		case NRF_DRV_TWI_EVT_DONE:
			NRF_LOG_INFO("EVT DONE");
			m_xfer_done = true;
			break;
		case NRF_DRV_TWI_EVT_ADDRESS_NACK:
			NRF_LOG_INFO("ADDRESS NACK");
			NRF_LOG_FLUSH();
			break;
		case NRF_DRV_TWI_EVT_DATA_NACK:
			NRF_LOG_INFO("DATA NACK");
			NRF_LOG_FLUSH();
			break;
	}
}

void BNO_init()
{
	const nrf_drv_twi_config_t twi_config =
	{
		.scl = 26,
		.sda = 25,
		.frequency = NRF_DRV_TWI_FREQ_100K,
		.interrupt_priority = TWI_DEFAULT_CONFIG_IRQ_PRIORITY,
		.clear_bus_init = TWI_DEFAULT_CONFIG_CLR_BUS_INIT,
		.hold_bus_uninit = TWI_DEFAULT_CONFIG_HOLD_BUS_UNINIT
	};
	
	APP_ERROR_CHECK(nrf_drv_twi_init(&m_twi, &twi_config, BNO_handler, NULL));
	nrf_drv_twi_enable(&m_twi);
	//APP_ERROR_CHECK(nrf_drv_twi_rx(&m_twi,BNO_055, PWR_MODE, 1));
	APP_ERROR_CHECK(nrf_drv_twi_tx(&m_twi, BNO_055, OPERATION_MODE_ADD, 1, false));
	NRF_LOG_INFO("the data is being written into the BNO_055, into the operation mode register");
	NRF_LOG_FLUSH();
	while(!m_xfer_done);
	APP_ERROR_CHECK(nrf_drv_twi_tx(&m_twi, BNO_055, NDOF_MODE, 1, false));
	NRF_LOG_INFO("The data will now be sent with NDOF mode and all the sensors are activated");
	
	NRF_LOG_INFO("IMU data started");
	NRF_LOG_FLUSH();
	
}
	
int main()
{
	APP_ERROR_CHECK(NRF_LOG_INIT(NULL));
	NRF_LOG_DEFAULT_BACKENDS_INIT();
	
	NRF_LOG_INFO("TWI test started.");
	NRF_LOG_FLUSH();
	BNO_init();
	uint8_t accRegister[1] = {QUA_Data_w_LSB};

	while(!m_xfer_done);
	//Read byte from bno
	APP_ERROR_CHECK(nrf_drv_twi_tx(&m_twi, BNO_055, accRegister, 1, false));
    NRF_LOG_INFO("Data received test");
	APP_ERROR_CHECK(nrf_drv_twi_rx(&m_twi, BNO_055, &m_data, 8));
	nrf_delay_ms(1000);
	NRF_LOG_INFO("data received: %X", &m_data);
	NRF_LOG_FLUSH();
	
	while (true);
}

Parents
  • Hi,

    You have configured the TWI driver to work in non-blocking mode. My guess is that when you call nrf_drv_twi_tx() and nrf_drv_twi_rx() right after one another at line 84 and 86, the first TX is not able to complete before you start the RX and nrf_drv_twi_rx() returns the error NRF_ERROR_BUSY. In your BNO_init() function, you are correctly waiting for the first transfer to finish before you start the next one with this line of code: while(!m_xfer_done).

    You can either implement a similar wait loop in main(), or you can configure the TWI driver in blocking mode. The latter might be easier, but requires more current and your application will not be able to do anything useful while the TWI transfers are ongoing. 

  • Hi Martin,

    I tried implementing a while loop, in order to wait for the transmission to finish, but it shows the same error i.e. "Fatal error" and then "System reset". But it wasn't working either.

    Could you help me what is the command or where do i need to make changes in order to change it to the blocking mode. I will take care about the power management later, first i need some raw ADC data coming out of it.

Reply
  • Hi Martin,

    I tried implementing a while loop, in order to wait for the transmission to finish, but it shows the same error i.e. "Fatal error" and then "System reset". But it wasn't working either.

    Could you help me what is the command or where do i need to make changes in order to change it to the blocking mode. I will take care about the power management later, first i need some raw ADC data coming out of it.

Children
Related