HI,
I am working on the interface between the nrf52832 and the MPU9250 IMU.
I have communication working fine with using nrfx_twi, but I have the following error when I try to use nrfx_twim :
<error> app: ASSERTION FAILED at /Users/slareau/nrf52_development/nRF5_SDK_16/modules/nrfx/drivers/src/nrfx_twim.c:561
I can get WHOIAM working indicating that the communication between the NRF52 and the IMU is working.
The error occur when I call the IMU self-test.
Looking nrfx_twim.c line 561 is : p_xfer_desc->secondary_length)) from the following code:
nrfx_err_t nrfx_twim_xfer(nrfx_twim_t const * p_instance,
nrfx_twim_xfer_desc_t const * p_xfer_desc,
uint32_t flags)
{
NRFX_ASSERT(TWIM_LENGTH_VALIDATE(p_instance->drv_inst_idx,
p_xfer_desc->primary_length,
p_xfer_desc->secondary_length));
nrfx_err_t err_code = NRFX_SUCCESS;
I have include the init / read / write driver below. Those came from an old exemple (SDK12) that I have modernize as I could - I don't have a lot of experience and nrfx TWI and TWIM exemple are rare... As I mention, the nrfx_twi version work fine (except for a compass calibration issue - might be related to communication issue or not).
To create the TWIM version, i have juste replace TWI by TWIM in appropriate place, and change the SDK_config setting.
How can I fix this ? Your help is always greatly appreciate.
Regards,
/*
* The library is not extensively tested and only
* meant as a simple explanation and for inspiration.
* NO WARRANTY of ANY KIND is provided.
*/
#if defined(MPU_USES_TWI) // Use TWI drivers
#include <stdbool.h>
#include <stdint.h>
#include <string.h>
#include "nrfx_twim.h"
#include "nrf_drv_mpu.h"
#include "app_util_platform.h"
#include "nrf_gpio.h"
#include "nrf_delay.h"
#include "nrf_log.h"
/* Pins to connect MPU. Pinout is different for nRF51 DK and nRF52 DK
* and therefore I have added a conditional statement defining different pins
* for each board. This is only for my own convenience.
*/
/*
#if defined BOARD_PCA10040
#define MPU_TWI_SDA_PIN 26
#define MPU_TWI_SCL_PIN 27
# elif BOARD_HOL18008
#define MPU_TWI_SDA_PIN 11 // HOL18008
#define MPU_TWI_SCL_PIN 12
#endif
*/
//#define MPU_TWI_SDA_PIN 26
//#define MPU_TWI_SCL_PIN 27 // HOL18008 + MPU9255 ext
#define MPU_TWI_SDA_PIN 22
#define MPU_TWI_SCL_PIN 24 // Ebyte73 + MPU9255 ext
#define MPU_TWI_BUFFER_SIZE 14 // 14 byte buffers will suffice to read acceleromter, gyroscope and temperature data in one transmission.
#define MPU_TWI_TIMEOUT 15000 //10000 SL
#define MPU_ADDRESS 0x68
#define MPU_AK89XX_MAGN_ADDRESS 0x0C
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:
switch(p_event->xfer_desc.type)
{
case NRFX_TWIM_XFER_TX:
twi_tx_done = true;
break;
case NRFX_TWIM_XFER_TXTX:
twi_tx_done = true;
break;
case NRFX_TWIM_XFER_RX:
twi_rx_done = true;
break;
case 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;
}
}
/**
* @brief TWI initialization.
* Just the usual way. Nothing special here
*/
uint32_t nrf_drv_mpu_init(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,
//.clear_bus_init = false
};
err_code = nrfx_twim_init(&m_twi_instance, &twi_mpu_config, twi_event_handler, NULL);
if(err_code != NRF_SUCCESS)
{
return err_code;
}
nrfx_twim_enable(&m_twi_instance);
return NRF_SUCCESS;
}
// The TWI driver is not able to do two transmits without repeating the ADDRESS + Write bit byte
// Hence we need to merge the MPU register address with the buffer and then transmit all as one transmission
static void merge_register_and_data(uint8_t * new_buffer, uint8_t reg, uint8_t * p_data, uint32_t length)
{
new_buffer[0] = reg;
memcpy((new_buffer + 1), p_data, length);
}
uint32_t nrf_mpu_write(uint8_t slave_addr, uint8_t reg_addr, uint8_t length, uint8_t * p_data)
//uint32_t Sensors_I2C_WriteRegister(uint8_t slave_addr, uint8_t reg_addr, uint8_t length, uint8_t * p_data)
{
// This burst write function is not optimal and needs improvement.
// The new SDK 11 TWI driver is not able to do two transmits without repeating the ADDRESS + Write bit byte
uint32_t err_code;
uint32_t timeout = MPU_TWI_TIMEOUT;
uint8_t twi_tx_buffer[length+1];
twi_tx_buffer[0] = reg_addr;
memcpy(&twi_tx_buffer[1], p_data, length);
// Merging MPU register address and p_data into one buffer.
//merge_register_and_data(twi_tx_buffer, reg_addr, p_data, length);
// Setting up transfer
nrfx_twim_xfer_desc_t xfer_desc;
xfer_desc.address = MPU_ADDRESS;
xfer_desc.type = NRFX_TWIM_XFER_TX;
xfer_desc.primary_length = length + 1;
xfer_desc.p_primary_buf = twi_tx_buffer;
// 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;
}
uint32_t nrf_mpu_read(uint8_t slave_addr, uint8_t reg_addr, uint8_t length, uint8_t * p_data)
//uint32_t Sensors_I2C_ReadRegister(uint8_t slave_addr, uint8_t reg_addr, uint8_t length, uint8_t * p_data)
{
uint32_t err_code;
uint32_t timeout = MPU_TWI_TIMEOUT;
//NRF_LOG_INFO("Read twi");
err_code = nrfx_twim_tx(&m_twi_instance, MPU_ADDRESS, ®_addr, 1, false);
if(err_code != NRF_SUCCESS) return err_code;
//nrf_delay_ms(1); does not help
//NRF_LOG_INFO("Read twi");
while((!twi_tx_done) && --timeout);
if(!timeout) return NRF_ERROR_TIMEOUT;
twi_tx_done = false;
err_code = nrfx_twim_rx(&m_twi_instance, MPU_ADDRESS, p_data, length);
if(err_code != NRF_SUCCESS) return err_code;
timeout = MPU_TWI_TIMEOUT;
while((!twi_rx_done) && --timeout);
if(!timeout) return NRF_ERROR_TIMEOUT;
twi_rx_done = false;
return err_code;
}
#endif // Use TWI drivers
/**
@}
*/
<error> app: ASSERTION FAILED at /Users/slareau/nrf52_development/nRF5_SDK_16/modules/nrfx/drivers/src/nrfx_twim.c:561