Hi everyone and thanks in advance.
I'm new to the NRF52 SDK enviroment and I've been having some trouble with the I2C/TWI configuration. The SDK we are using in the v12.3.0 and I've use the TWI_sensor example and modifying it to suit my application.
The code is this:
#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 // MPU9250 Addresses definition #define MPU9250_ADDRESS 0x68 #define MAG_ADDRESS 0x0C #define ACC_CONF 28 #define GYRO_FULL_SCALE_250_DPS 0x00 #define GYRO_FULL_SCALE_500_DPS 0x08 #define GYRO_FULL_SCALE_1000_DPS 0x10 #define GYRO_FULL_SCALE_2000_DPS 0x18 #define ACC_FULL_SCALE_2_G 0x00 #define ACC_FULL_SCALE_4_G 0x08 #define ACC_FULL_SCALE_8_G 0x10 #define ACC_FULL_SCALE_16_G 0x18 #define ACC_SCALE ACC_FULL_SCALE_16_G /* 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_INLINE void data_handler(uint8_t temp) { NRF_LOG_INFO("Temperature: %d Celsius degrees.\r\n", temp); } /** * @brief TWI events handler. */ void print_errorcode(uint32_t error_code) { /* No human readable form found */ NRF_LOG_INFO("\r\nFunction return code: (%x)", error_code); } void twi_handler(nrf_drv_twi_evt_t const * p_event, void * p_context) { switch (p_event->type) { case NRF_DRV_TWI_EVT_DONE: if (p_event->xfer_desc.type == NRF_DRV_TWI_XFER_RX) { data_handler(m_sample); } 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_lm75b_config = { .scl = ARDUINO_SCL_PIN, .sda = ARDUINO_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_lm75b_config, twi_handler, NULL); APP_ERROR_CHECK(err_code); nrf_drv_twi_enable(&m_twi); NRF_LOG_INFO("\r I2C configurado \r\n"); NRF_LOG_INFO("\r \r\n"); } /** * @brief Function for reading data from temperature sensor. */ void initmpu9250(void) { ret_code_t err_code; uint8_t reg[2] = {0x1C,ACC_SCALE}; //NRF_LOG_INFO("\r Valor registro %x %x\r \n",reg[0], reg[1]); //NRF_LOG_FLUSH(); err_code = nrf_drv_twi_tx(&m_twi,MPU9250_ADDRESS, reg, 2, false); APP_ERROR_CHECK(err_code); //print_errorcode(err_code); while (m_xfer_done == false); } uint32_t nrf_drv_mpu_read_registers(uint8_t reg, uint8_t * p_data, uint32_t length) { uint32_t err_code; //uint32_t timeout = MPU_TWI_TIMEOUT; //uint8_t buf[6]; err_code = nrf_drv_twi_tx(&m_twi, MPU9250_ADDRESS, ®, 1, false); if(err_code != NRF_SUCCESS) return err_code; err_code = nrf_drv_twi_rx(&m_twi, MPU9250_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; } /** * @brief Function for main application entry. */ int main(void) { APP_ERROR_CHECK(NRF_LOG_INIT(NULL)); NRF_LOG_INFO("\r Inicio programa\r \n"); NRF_LOG_FLUSH(); twi_init(); initmpu9250(); NRF_LOG_INFO("\r MPU init done\r \n"); NRF_LOG_FLUSH(); while (true) { NRF_LOG_INFO("\r loop \r\n"); NRF_LOG_FLUSH(); nrf_delay_ms(500); /* do { __WFE(); }while (m_xfer_done == false); */ //read_sensor_data(); } } /** @} */
The code is quite simple, but I can not capture any TWI/I2C frame. Clock line is Pull-up but seems to be not working and SDA generating the same pulses, here is a screenshot:
Also, the code stop working right after enters the initmpu9250() function, so that's why I think is something wrong in my initialization rutine.
Do you see any error in the code?
Thanks, Borja.