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

BNO080 SH-2 over TWIM

Hi

Has anyone developed or worked with a BNO080 using Hilcrest's SH-2 Protocol over TWIM? I'm having real challenges getting consistent responses. I've developed (based on what I can find on the internet) the basics of a library. But every time I run even even the simplest of requests 50% I get NRF_ERROR_TIMEOUT. The other 50% of the time if receive NRFX_TWIM_EVT_DONE and NRFX_TWIM_XFER_TX.

My other question is related to my lack of experience. How do I know (without interrupt) that data is ready to be ready from TWIM?

bno080-twim.h

#define MPU_TWI_SCL_PIN 11
#define MPU_TWI_SDA_PIN 8

#define MPU_TWI_BUFFER_SIZE     	32
#define MPU_TWI_TIMEOUT 			15000
#define BNO080_TWI_ADDRESS          0x4B 
#define MPU_ADDRESS     			0x68
#define MPU_AK89XX_MAGN_ADDRESS     0x0C

//Registers
#define CHANNEL_COMMAND         0
#define CHANNEL_EXECUTABLE      1
#define CHANNEL_CONTROL         2
#define CHANNEL_REPORTS         3
#define CHANNEL_WAKE_REPORTS    4
#define CHANNEL_GYRO            5

//All the ways we can configure or talk to the BNO080, figure 34, page 36 reference manual
//These are used for low level communication with the sensor, on channel 2
#define SHTP_REPORT_COMMAND_RESPONSE 0xF1
#define SHTP_REPORT_COMMAND_REQUEST 0xF2
#define SHTP_REPORT_FRS_READ_RESPONSE 0xF3
#define SHTP_REPORT_FRS_READ_REQUEST 0xF4
#define SHTP_REPORT_PRODUCT_ID_RESPONSE 0xF8
#define SHTP_REPORT_PRODUCT_ID_REQUEST 0xF9
#define SHTP_REPORT_BASE_TIMESTAMP 0xFB
#define SHTP_REPORT_SET_FEATURE_COMMAND 0xFD

//All the different sensors and features we can get reports from
//These are used when enabling a given sensor
#define SENSOR_REPORTID_ACCELEROMETER 0x01
#define SENSOR_REPORTID_GYROSCOPE 0x02
#define SENSOR_REPORTID_MAGNETIC_FIELD 0x03
#define SENSOR_REPORTID_LINEAR_ACCELERATION 0x04
#define SENSOR_REPORTID_ROTATION_VECTOR 0x05
#define SENSOR_REPORTID_GRAVITY 0x06
#define SENSOR_REPORTID_GAME_ROTATION_VECTOR 0x08
#define SENSOR_REPORTID_GEOMAGNETIC_ROTATION_VECTOR 0x09
#define SENSOR_REPORTID_TAP_DETECTOR 0x10
#define SENSOR_REPORTID_STEP_COUNTER 0x11
#define SENSOR_REPORTID_STABILITY_CLASSIFIER 0x13
#define SENSOR_REPORTID_RAW_ACCELEROMETER 0x14
#define SENSOR_REPORTID_RAW_GYROSCOPE 0x15
#define SENSOR_REPORTID_RAW_MAGNETOMETER 0x16
#define SENSOR_REPORTID_PERSONAL_ACTIVITY_CLASSIFIER 0x1E

//Record IDs from figure 29, page 29 reference manual
//These are used to read the metadata for each sensor type
#define FRS_RECORDID_ACCELEROMETER 0xE302
#define FRS_RECORDID_GYROSCOPE_CALIBRATED 0xE306
#define FRS_RECORDID_MAGNETIC_FIELD_CALIBRATED 0xE309
#define FRS_RECORDID_ROTATION_VECTOR 0xE30B

//Command IDs from section 6.4, page 42
//These are used to calibrate, initialize, set orientation, tare etc the sensor
#define COMMAND_ERRORS 1
#define COMMAND_COUNTER 2
#define COMMAND_TARE 3
#define COMMAND_INITIALIZE 4
#define COMMAND_DCD 6
#define COMMAND_ME_CALIBRATE 7
#define COMMAND_DCD_PERIOD_SAVE 9
#define COMMAND_OSCILLATOR 10
#define COMMAND_CLEAR_DCD 11

#define CALIBRATE_ACCEL 0
#define CALIBRATE_GYRO 1
#define CALIBRATE_MAG 2
#define CALIBRATE_PLANAR_ACCEL 3
#define CALIBRATE_ACCEL_GYRO_MAG 4
#define CALIBRATE_STOP 5

#define MAX_PACKET_SIZE 28 // Size of TWi Buffer 32-4=28 for the header  //128 //Packets can be up to 32k but we don't have that much RAM.
#define MAX_METADATA_SIZE 9 //This is in words. There can be many but we mostly only care about the first 9 (Qs, range, etc)

// TWI (with transaction manager) initialization.
uint32_t twi_config(void);
uint32_t twi_scanner();
uint32_t bno080_init();

bno080-twim.c

#include <stdbool.h>
#include <stdint.h>
#include <string.h>
#include <stdlib.h>
#include "nrf_log.h"
#include "nrfx_twim.h"
#include "nrf_delay.h"

#include "bno080-twim.h"

uint8_t sequenceNumber[6] = {0, 0, 0, 0, 0, 0}; //There are 6 com channels. Each channel has its own seqnum
uint8_t commandSequenceNumber = 0;				//Commands have a seqNum as well. These are inside command packet, the header uses its own seqNum per channel

//#define TWI_INSTANCE_ID             0
//#define MAX_PENDING_TRANSACTIONS    5
//NRF_TWI_MNGR_DEF(m_nrf_twi_mngr, MAX_PENDING_TRANSACTIONS, TWI_INSTANCE_ID);

static const nrfx_twim_t m_twi_instance = NRFX_TWIM_INSTANCE(0);
volatile static bool twi_tx_done = false;
volatile static bool twi_rx_done = false;

uint8_t twi_tx_buffer[MPU_TWI_BUFFER_SIZE];

static void twi_event_handler(nrfx_twim_evt_t const * p_event, void * p_context)
{
    switch(p_event->type)
    {
        case NRFX_TWIM_EVT_DONE:
            NRF_LOG_INFO("NRFX_TWIM_EVT_DONE");
            switch(p_event->xfer_desc.type)
            {
                case NRFX_TWIM_XFER_TX:
                    NRF_LOG_INFO("NRFX_TWIM_XFER_TX");
                    twi_tx_done = true;
                    break;
                case NRFX_TWIM_XFER_TXTX:
                    NRF_LOG_INFO("NRFX_TWIM_XFER_TXTX");
                    twi_tx_done = true;
                    break;
                case NRFX_TWIM_XFER_RX:
                    NRF_LOG_INFO("NRFX_TWIM_XFER_RX");
                    twi_rx_done = true;
                    break;
                case NRFX_TWIM_XFER_TXRX:
                    NRF_LOG_INFO("NRFX_TWIM_XFER_TXRX");
                    twi_rx_done = true;
                    break;
                default:
                    break;
            }
            break;
        case NRFX_TWIM_EVT_ADDRESS_NACK:
            break;
        case NRFX_TWIM_EVT_DATA_NACK:
            break;
        default:
            break;
    }
}

// TWI (with transaction manager) initialization.
uint32_t twi_config(void)
{
    uint32_t err_code;
    
    const nrfx_twim_config_t twi_mpu_config = {
        .scl                = MPU_TWI_SCL_PIN,
        .sda                = MPU_TWI_SDA_PIN,
        .frequency          = NRF_TWIM_FREQ_400K,
        .interrupt_priority = APP_IRQ_PRIORITY_HIGHEST,
        .hold_bus_uninit    = true
    };
    
    err_code = nrfx_twim_init(&m_twi_instance, &twi_mpu_config, twi_event_handler, NULL);
    if(err_code != NRF_SUCCESS) {return err_code;}

    nrf_delay_ms(1);
        
    nrfx_twim_enable(&m_twi_instance);
	
	return NRF_SUCCESS;

}

uint32_t twi_scanner()
{
    uint32_t err_code;
    uint8_t address;
    uint8_t sample_data;

    for (address = 1; address <= 127; address++)
    {
        err_code = nrfx_twim_rx(&m_twi_instance, address, &sample_data, sizeof(sample_data));
        if (err_code == NRF_SUCCESS)
        {
            NRF_LOG_INFO("TWI device detected at address 0x%x.", address);
        }
    }

    return NRF_SUCCESS;

}

uint32_t  bno080_init()
{
    uint32_t err_code;
    uint32_t timeout = MPU_TWI_TIMEOUT;

    uint16_t packetLength = 6;
    uint8_t * txbuffer = malloc(packetLength);       //setup the data paxket to send
    txbuffer[0] = packetLength & 0xFF;              //SHTP Header - Byte 0 - Packet Length LSB
    txbuffer[1] = packetLength >> 8;                //SHTP Header - Byte 1 - Packet Length MSB
    txbuffer[2] = CHANNEL_CONTROL;                    //SHTP Header - Byte 2 - Channel Number
    txbuffer[3] = sequenceNumber[CHANNEL_CONTROL]++;  //SHTP Header - Byte 3 - Sequence Number
    txbuffer[4] = SHTP_REPORT_PRODUCT_ID_REQUEST;   //SHTP Header - Byte 4 - SHTP_REPORT_PRODUCT_ID_REQUEST
    txbuffer[5] = 0x0;                              //SHTP Header - Byte 5 - Reserved
     
    // Setting up transfer
    nrfx_twim_xfer_desc_t xfer_desc;
    xfer_desc.address = BNO080_TWI_ADDRESS;
    xfer_desc.type = NRFX_TWIM_XFER_TX;
    xfer_desc.primary_length = packetLength;
    xfer_desc.p_primary_buf = txbuffer;

    // Transferring  
    err_code = nrfx_twim_xfer(&m_twi_instance, &xfer_desc, 0);

    while((!twi_tx_done) && --timeout);
    if(!timeout) return NRF_ERROR_TIMEOUT;
    twi_tx_done = false;

    return err_code;
}

TWI/TWIM Settings in SDK:


#define NRFX_TWIM_ENABLED 1
#define NRFX_TWIM0_ENABLED 1

#define NRFX_TWIS_ENABLED 0

#define NRFX_TWI_ENABLED 0

#define TWIS_ENABLED 0

#define TWI_ENABLED 1

#define NRF_TWI_SENSOR_ENABLED 0

#define NRF_TWI_MNGR_ENABLED 0

Thanks, been bogged down with this for a few days.

Related