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

TWI/I2C communication with custom nrf52832 board doesn't work

My pcb is nrf52832 based, with SPI interfacing ICM20649 sensor.

- Nordic SDK 11.0

- Softdevice 2.0

I am able to flash example code of SPI based  ble_peripheral and mpu and advertise, but the same code doesn't advertise with TWI example code. I also flashed TWI scanner with, but no results on RTT viewer.

pin configuration

#if defined(BOARD_PCA10040)
#define MPU_TWI_SCL_PIN 4
#define MPU_TWI_SDA_PIN 27

on pcb SPI configuration is :

SCL-- P0.04

SDA-- P0.27

SDI-- P0.26

NCS-- P0.05

  • Hi,

    Have you tried debugging the application, to see if any error codes are reported?

    Can you post code snippets showing how you configure TWI? TWI scanner example is not available in SDK 11, which SDK did you use that from?

    Best regards,
    Jørgen

  • After your suggestion i ran a debug and found error code 0x0000000D

    I used TWI scanner from SDK 13.0.

    Using example from https://github.com/Martinsbl/nrf5-mpu-examples

     /*
      * The library is not extensively tested and only
      * meant as a simple explanation and for inspiration.
      * NO WARRANTY of ANY KIND is provided.
      */
    
    #include <stdbool.h>
    #include <stdint.h>
    #include <string.h>
    #include "app_mpu_20648.h"
    #include "nrf_gpio.h"
    #include "nrf_drv_mpu.h"
    #include "nrf_error.h"
    #include "nrf_drv_config.h"
    
    
    
    uint32_t mpu_config(mpu_config_t * config)
    {
        uint8_t *data;
        data = (uint8_t*)config;
        return nrf_drv_mpu_write_registers(ICM20648_REG_GYRO_SMPLRT_DIV , data, 4);
    }
    
    
    
    uint32_t mpu_int_cfg_pin(mpu_int_pin_cfg_t *cfg)
    {
        uint8_t *data;
        data = (uint8_t*)cfg;
        return nrf_drv_mpu_write_single_register(ICM20648_REG_INT_PIN_CFG, *data);
        
    }
    
    
    
    uint32_t mpu_int_enable(mpu_int_enable_t *cfg)
    {
        uint8_t *data;
        data = (uint8_t*)cfg;
        return nrf_drv_mpu_write_single_register(ICM20648_REG_INT_ENABLE, *data);
    }
    
    
    
    uint32_t mpu_init(void)
    {
        uint32_t err_code;
    	uint8_t who_am_i;
    	
    	// Initate TWI or SPI driver dependent on what is defined from the project
    	err_code = nrf_drv_mpu_init();
        if(err_code != NRF_SUCCESS) return err_code;
    	
    
      /*  uint8_t reset_value = 7; // Resets gyro, accelerometer and temperature sensor signal paths.
        err_code = nrf_drv_mpu_write_single_register(ICM20648_REG_PWR_MGMT_1, ICM20648_BIT_H_RESET);
    	nrf_delay_ms(100);
        if(err_code != NRF_SUCCESS) return err_code;*/
    	
    	//  nrf_drv_mpu_write_single_register(ICM20648_REG_USER_CTRL,ICM20648_BIT_I2C_IF_DIS);
    	
    	
    	 err_code = nrf_drv_mpu_read_registers(ICM20648_REG_WHO_AM_I, &who_am_i,1);
    		SEGGER_RTT_printf(0, "err_code: %d\t", err_code);
    		SEGGER_RTT_printf(0, "WHO_AM_I value: 0x%02x\n", who_am_i);
        if(err_code != NRF_SUCCESS) return err_code;
    	
    
        // Chose  PLL with X axis gyroscope reference as clock source
        err_code = nrf_drv_mpu_write_single_register(ICM20648_REG_PWR_MGMT_1,ICM20648_BIT_CLK_PLL);
    		nrf_delay_ms(100);
        if(err_code != NRF_SUCCESS) return err_code;
    
        return NRF_SUCCESS;
    }
    
    
    
    uint32_t mpu_read_accel(accel_values_t * accel_values)
    {
        uint32_t err_code;
        uint8_t raw_values[6];
        err_code = nrf_drv_mpu_read_registers(ICM20648_REG_ACCEL_XOUT_H_SH  , raw_values, 6);
        if(err_code != NRF_SUCCESS) return err_code;
    
        // Reorganize read sensor values and put them into value struct
        uint8_t *data;
        data = (uint8_t*)accel_values;
        for(uint8_t i = 0; i<6; i++)
        {
            *data = raw_values[5-i];
            data++;
        }
        return NRF_SUCCESS;
    }
    
    
    
    uint32_t mpu_read_gyro(gyro_values_t * gyro_values)
    {
        uint32_t err_code;
        uint8_t raw_values[6];
        err_code = nrf_drv_mpu_read_registers(ICM20648_REG_GYRO_XOUT_H_SH, raw_values,6);
        if(err_code != NRF_SUCCESS) return err_code;
    
        // Reorganize read sensor values and put them into value struct
        uint8_t *data;
        data = (uint8_t*)gyro_values;
        for(uint8_t i = 0; i<6; i++)
        {
            *data = raw_values[5-i];
            data++;
        }
        return NRF_SUCCESS;
    }
    
    
    
    uint32_t mpu_read_temp(temp_value_t * temperature)
    {
        uint32_t err_code;
        uint8_t raw_values[2];
        err_code = nrf_drv_mpu_read_registers(ICM20648_REG_TEMPERATURE_H , raw_values, 2);
        if(err_code != NRF_SUCCESS) return err_code;
    
        *temperature = (temp_value_t)(raw_values[0] << 8) + raw_values[1];
    
        return NRF_SUCCESS;
    }
    
    uint32_t mpu_read_values(mpu_values_t * mpu_values)
    {
        uint32_t err_code;
        uint8_t raw_values[14];
        err_code = nrf_drv_mpu_read_registers(ICM20648_REG_ACCEL_XOUT_H_SH , raw_values, 14);
        if(err_code != NRF_SUCCESS) return err_code;
    
        // Reorganize read sensor values and put them into value struct
        uint8_t *data;
        data = (uint8_t*)mpu_values;
        for(uint8_t i = 0; i<14; i++)
        {
            *data = raw_values[13-i];
            data++;
        }
        return NRF_SUCCESS;
    }
    
    //uint32_t mpu_read_offset_accel(mpu_accel_offset_t * mpu_accel_offset)
    //{
    //    uint32_t err_code;
    //    uint8_t raw_values[3];
    //    err_code = nrf_drv_mpu_read_registers(MPU_REG_SELF_TEST_ACCEL_X, raw_values, 3);
    //    if(err_code != NRF_SUCCESS) return err_code;
    
    //    // Reorganize read sensor values and put them into value struct
    //    uint8_t *data;
    //    data = (uint8_t*)mpu_accel_offset;
    //    for(uint8_t i = 0; i<3; i++)
    //    {
    //        *data = raw_values[2-i];
    //        data++;
    //    }
    //    return NRF_SUCCESS;
    //}
    
    //uint32_t mpu_read_offset_gyro(mpu_gyro_offset_t * mpu_gyro_offset)
    //{
    //    uint32_t err_code;
    //    uint8_t raw_values[3];
    //    err_code = nrf_drv_mpu_read_registers(MPU_REG_SELF_TEST_GYRO_X, raw_values, 3);
    //    if(err_code != NRF_SUCCESS) return err_code;
    
    //    // Reorganize read sensor values and put them into value struct
    //    uint8_t *data;
    //    data = (uint8_t*)mpu_gyro_offset;
    //    for(uint8_t i = 0; i<3; i++)
    //    {
    //        *data = raw_values[2-i];
    //        data++;
    //    }
    //    return NRF_SUCCESS;
    //}
    
    
    uint32_t mpu_read_int_source(uint8_t * int_source)
    {
        return nrf_drv_mpu_read_registers(ICM20648_REG_INT_STATUS , int_source, 1);
    }
    
    
    // Function does not work on MPU60x0 and MPU9255
    #if defined(MPU9150)
    uint32_t mpu_config_ff_detection(uint16_t mg, uint8_t duration)
    {
        uint32_t err_code;
        uint8_t threshold = (uint8_t)(mg/MPU_MG_PR_LSB_FF_THR);
        if(threshold > 255) return MPU_BAD_PARAMETER;
    
        err_code = nrf_drv_mpu_write_single_register(MPU_REG_FF_THR, threshold);
        if(err_code != NRF_SUCCESS) return err_code;
    
        return nrf_drv_mpu_write_single_register(MPU_REG_FF_DUR, duration);
    }
    #endif // defined(MPU9150)
    
    
    
    /*********************************************************************************************************************
     * FUNCTIONS FOR MAGNETOMETER.
     * MPU9150 has an AK8975C and MPU9255 an AK8963 internal magnetometer. Their register maps
     * are similar, but AK8963 has adjustable resoultion (14 and 16 bits) while AK8975C has 13 bit resolution fixed. 
     */
    
    /*#if defined(MPU9150) || defined(MPU9255) && (TWI_COUNT >= 1) // Magnetometer only works with TWI so check if TWI is enabled
    
    uint32_t mpu_magnetometer_init(mpu_magn_config_t * p_magnetometer_conf)
    {	
    	uint32_t err_code;
    	
    	// Read out MPU configuration register
    	mpu_int_pin_cfg_t bypass_config;
    	err_code = nrf_drv_mpu_read_registers(MPU_REG_INT_PIN_CFG, (uint8_t *)&bypass_config, 1);
    	
    	// Set I2C bypass enable bit to be able to communicate with magnetometer via I2C
    	bypass_config.i2c_bypass_en = 1;
    	// Write config value back to MPU config register
    	err_code = mpu_int_cfg_pin(&bypass_config);
    	if (err_code != NRF_SUCCESS) return err_code;
    	
    	// Write magnetometer config data	
    	uint8_t *data;
        data = (uint8_t*)p_magnetometer_conf;	
        return nrf_drv_mpu_write_magnetometer_register(MPU_AK89XX_REG_CNTL, *data);
    }*/
    app_mpu_20648.h

    icm20648.h

  • The example you are using is initializing the UART peripheral. The UART use P0.05 as RTS pin by default (RTS_PIN_NUMBER is defined in pca10040.h BSP file).

    Did you change the pin used by UART? If not, you will not be able to use P0.05 for SPI interface.

    Please clarify if you are using TWI or SPI. You mention both in your post.

Related