NCS SDK 2.7.0 uses I2C(SCL P0.10, SDA P0.09 ) failed

1. dts config file, I2C_SDA is configed GPIO P0.09/NFC1I2C_SCL is configed GPIO P0.10/NFC1, months ago, I'm using the old SDK, I also found that these pins configed as I2C function can not work, now the NCS SDK has the same problem, Could you help to check why?

&i2c0 {
	status = "okay";
	pinctrl-0 = <&i2c0_default>;
	pinctrl-names = "default";
	clock-frequency = <I2C_BITRATE_FAST>;
	is31fl3235a_part1: is31fl3235a_part1@78 {
		compatible = "i2c-device";
		reg = <0x78>;
		status = "okay";
	};
	is31fl3235a_part2: is31fl3235a_part2@7B {
		compatible = "i2c-device";
		reg = <0x7B>;
		status = "okay";
	};
};

&pinctrl {
	i2c0_default: i2c0_default {
		group1 {
			psels = <NRF_PSEL(TWIM_SCL, 0, 10)>, <NRF_PSEL(TWIM_SDA, 0, 9)>;
		};
	};
};

2. Driver code

#define IS31FL3235A_REG_SHUTDOWN 0x00
#define IS31FL3235A_REG_GBL_CTL 0x4A
#define IS31FL3235A_REG_OUT_FREQ 0x4B
#define IS31FL3235A_REG_RST 0x4F

#define MCU1_NODE DT_NODELABEL(is31fl3235a_part1)
#define MCU2_NODE DT_NODELABEL(is31fl3235a_part2)

static const struct i2c_dt_spec mcu1_i2c = I2C_DT_SPEC_GET(MCU1_NODE);
static const struct i2c_dt_spec mcu2_i2c = I2C_DT_SPEC_GET(MCU2_NODE);

int is31fl3235a_init() {
    int err;
    if (!device_is_ready(mcu1_i2c.bus)) {
        LOG_ERR("I2C bus %s is not ready!\n\r", mcu1_i2c.bus->name);
        return -1;
    }
    if (!device_is_ready(mcu2_i2c.bus)) {
        LOG_ERR("I2C bus %s is not ready!\n\r", mcu2_i2c.bus->name);
        return -1;
    }
    uint8_t config[2] = {IS31FL3235A_REG_SHUTDOWN, 0x01};
    err = i2c_write(mcu1_i2c.bus, config, sizeof(config), 0x78);
    if (err < 0) {
        LOG_ERR("Could not write to I2C device %s\n\r", "mcu1");
        return -1;
    }
    err = i2c_write(mcu2_i2c.bus, config, sizeof(config), 0x7B);
    if (err < 0) {
        LOG_ERR("Could not write to I2C device %s\n\r", "mcu2");
        return -1;
    }

    return 0;
}

When running, I got the below exception

SEGGER J-Link V7.94e - Real time terminal output
SEGGER J-Link V9.6, SN=69650869
Process: JLink.exe
[00:00:00.501,007] <err> PHOENIX_IS31Fl3235A: Could not write to I2C device mcu1

  • Read the PS. Those pins need to be configured in UICR in order to allow them to work as GPIOs.

  • I uses below commands to set NFCPINS to gpio, but I still got the I2C write exception, Any other things need to configure?

    > nrfjprog --memrd 0x1000120C
    0x1000120C: FFFFFFFF                              |....|
    > nrfjprog --memwr 0x4001E504 --val 1
    Parsing parameters.
    Writing.
    > nrfjprog --memwr 0x1000120C --val 0
    Parsing parameters.
    Writing.
    > nrfjprog --reset
    Applying system reset.
    Run.
    > nrfjprog --memrd 0x1000120C
    0x1000120C: 00000000                              |....|
    

  • Hi,

    To use the NFCT pins as GPIO's without needing additional steps you can add this to  your board files or an overlay file:

    	  &uicr {
    	      nfct-pins-as-gpios;
    	  };

  • I still get below exception:

    Process: JLink.exe
    [00:00:00.000,793] <inf> PHOENIX_IS31Fl3235A: I2C bus i2c@40003000 is ready!
    
    [00:00:00.001,037] <err> PHOENIX_IS31Fl3235A: Could not write to I2C device mcu1
    
    [00:00:00.001,098] <inf> main: Battery value: 9464
    [00:00:00.001,159] <inf> main: MCU1 value: 404
    [00:00:00.001,190] <inf> main: MCU2 value: 392

    my dts file

    &i2c0 {
    	status = "okay";
    	pinctrl-0 = <&i2c0_default>;
    	pinctrl-names = "default";
    	clock-frequency = <I2C_BITRATE_STANDARD>;
    	is31fl3235a_part1: is31fl3235a_part1@78 {
    		compatible = "i2c-device";
    		reg = <0x78>;
    		status = "okay";
    	};
    	// is31fl3235a_part2: is31fl3235a_part2@7B {
    	// 	compatible = "i2c-device";
    	// 	reg = <0x7B>;
    	// 	status = "okay";
    	// };
    };
    
    &uicr {
    	nfct-pins-as-gpios;
    };
    
    &pinctrl {
    	i2c0_default: i2c0_default {
    		group1 {
    			psels = <NRF_PSEL(TWIM_SCL, 0, 10)>, <NRF_PSEL(TWIM_SDA, 0, 9)>;
    		};
    	};
    
    	spi1_default: spi1_default {
    		group1 {
    			psels = <NRF_PSEL(SPIM_MISO, 0, 14)>,
    					<NRF_PSEL(SPIM_MOSI, 0, 15)>,
    					<NRF_PSEL(SPIM_SCK, 0, 17)>;
    		};
    	};
    };

    my c file

    #define IS31FL3235A_REG_SHUTDOWN 0x00
    #define IS31FL3235A_REG_GBL_CTL 0x4A
    #define IS31FL3235A_REG_OUT_FREQ 0x4B
    #define IS31FL3235A_REG_RST 0x4F
    
    #define MCU1_NODE DT_NODELABEL(is31fl3235a_part1)
    
    static const struct i2c_dt_spec mcu1_i2c = I2C_DT_SPEC_GET(MCU1_NODE);
    
    // init
    int is31fl3235a_init();
    
    int is31fl3235a_init() {
        int err;
        if (!device_is_ready(mcu1_i2c.bus)) {
            LOG_ERR("I2C bus %s is not ready!\n\r", mcu1_i2c.bus->name);
            return -1;
        } else {
            LOG_INF("I2C bus %s is ready!\n\r", mcu1_i2c.bus->name);
        }
    
        uint8_t config[2] = {IS31FL3235A_REG_SHUTDOWN, 0x01};
        err = i2c_write_dt(&mcu1_i2c, config, sizeof(config));
        if (err < 0) {
            LOG_ERR("Could not write to I2C device %s\n\r", "mcu1");
            return -1;
        }
    
    
        return 0;
    }

  • Hi,

    I see. It look slike you are also missing pullup configurations, unless you have external pull resistors? See this post.

Related