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

IO expander control with TWI

Hello,

I've been trying to control MCP23017 IO expander with TWI using nRF52832. When I execute the code it stops at nrf_drv_twi_tx. The address pins A(0:2) are 0.

Any idea on what may not work here?

Code:

#define I2C_SCL_PIN 			(21)
#define I2C_SDA_PIN 			(20)
#define I2C_EXPANDER_ADD 	        (0x40)

const int resetPin = 19;
const int ledPin = 26;
	
static const nrf_drv_twi_t twi = NRF_DRV_TWI_INSTANCE(0);

static ret_code_t i2cSend(size_t target_register, uint8_t data_to_write) {
		uint8_t buffer[2];
		buffer[0] = target_register;
		buffer[1] = data_to_write;
	
		return nrf_drv_twi_tx(&twi, I2C_EXPANDER_ADD, buffer, 0x02, false);		
}

int main(){	
	ret_code_t err_code;
	uint8_t data;
	size_t addr;
	
	nrf_gpio_cfg_output(resetPin);	//Expander reset pin																											
	nrf_gpio_cfg_output(ledPin);
	nrf_gpio_pin_set(resetPin);	
	nrf_gpio_pin_set(ledPin);          //Expander inactive state
	
  const nrf_drv_twi_config_t twi_config = {
    .scl                       = I2C_SCL_PIN,
    .sda                      = I2C_SDA_PIN,
    .frequency            = NRF_TWI_FREQ_400K,
    .interrupt_priority = APP_IRQ_PRIORITY_HIGH
  };
	
	err_code = nrf_drv_twi_init(&twi, &twi_config, NULL, NULL);
	APP_ERROR_CHECK(err_code);
	
	nrf_drv_twi_enable(&twi);
	
  i2cSend(0x01, 0x00);                     //Access direction register of PortB
	
	while(1){
		nrf_delay_ms(500);
		
		i2cSend(0x13, 0x02);	           //Access PortB, Turn LED2 ON
		nrf_gpio_pin_set(ledPin);     //Turn LED1 OFF
		
		nrf_delay_ms(500);
		
		i2cSend(0x13, 0x00);            //Access PortB, Turn LED2 OFF																																	
		nrf_gpio_pin_clear(ledPin);  //Turn LED1 ON
	}
}
Parents
  • Hi

    First, pin 21 on the nRF52 is a chip reset pin unless otherwise is configured in the UICR->PSELRESET registers. So if possible try to use a different set of TWI pins.

    Second, when you don't provide an event handler function to nrf_drv_twi_init() the TWI driver will operate in blocking mode. I.e. if something goes wrong your application will get stuck in nrf_drv_twi_tx(). In this case the blocking mode is probably not the issue though, but the pins that you use might be.

    Edit: When a pin is configured as a reset pin it is disconnected from other functionality, so your chip won't reset whenever the TWI is active. What I think happens in your case is that: The SCL signal is routed to the reset pin, but the reset functionality overrules the TWI functionality. Hence, the TWI transaction fails and since you have configured the TWI module in blocking mode the code hangs in nrf_drv_twi_tx().

  • I have changed the reset pin to an other pin, and the address to 0x20 (shift left was not necessary) and everything works!

    thank you!

Reply Children
No Data
Related