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