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

TWI/I2C with SDK 11 (long transfers)

Hi,

I would like to use my NRF51DK with SDK11 and SD130 to control my SSD1306 OLED screen over TWI/I2C.

To refresh the OLED screen, we have to send it the whole display buffer in one transfer. All was working great under SDK9 and SDK10 (SD110) in which we could send long buffers (length argument was uint32_t), however in SDK11, nrf_drv_twi_tx() takes an "uint8_t length".

I then tried to slice buffers into 255bytes max transfers, but it does not work. I looked over the TWI bus with my logic analyzer, all signals are correctly generated but a start condition happens every time a transfer slice begins (I thought it might be the problem as it looks to be the only difference from the results I get with SDK10).

This is the code I use to slice sent data :

bool I2C_Write(uint8_t address, uint8_t const  *data, uint16_t length, bool Stop )
{
	uint32_t err_code;
	for (int i=0; i<length; i+=256) {
		err_code = nrf_drv_twi_tx(&twi, address, &data[i], MIN(255, length-i), (i+256 >= length)? !Stop : true);
		if (err_code != NRF_SUCCESS) return false;
	}
	return (err_code == NRF_SUCCESS);
}

and the following to initialize TWI:

nrf_drv_twi_t twi = NRF_DRV_TWI_INSTANCE(0);

bool I2C_master_init(uint32_t sda, uint32_t scl, nrf_twi_frequency_t frequency)
{
	nrf_drv_twi_config_t config;
	config.frequency = frequency;
	config.interrupt_priority = APP_IRQ_PRIORITY_HIGH;
	config.scl = scl;
	config.sda = sda;
	
	uint32_t err_code = nrf_drv_twi_init(&twi, &config, NULL, NULL);
	nrf_drv_twi_enable(&twi);

  return (err_code == NRF_SUCCESS);
}

How should I handle long packet transfers with the new SDK11?

Thank you

Arnaud

Related