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

Parents
  • Hi,

    Right you are. In this case I think your best bet is to use the old driver from SDK 10. Hopefully it is not too complicated to port or alternately you can use SDK 10. The reason the new driver now only supports 255 bytes per transaction in order to be compliant with the 255 bytes per transaction limit on the EasyDMA. If you are using nRF51 you may be able to fix your problem by changing the length parameter from uint8_t to uint16_t as nRF51 does not have EasyDMA for TWI.

    TWI slaves can have trouble recieving multiple start signals, this may be what is causing your error.

    Best regards,

    Øyvind

Reply
  • Hi,

    Right you are. In this case I think your best bet is to use the old driver from SDK 10. Hopefully it is not too complicated to port or alternately you can use SDK 10. The reason the new driver now only supports 255 bytes per transaction in order to be compliant with the 255 bytes per transaction limit on the EasyDMA. If you are using nRF51 you may be able to fix your problem by changing the length parameter from uint8_t to uint16_t as nRF51 does not have EasyDMA for TWI.

    TWI slaves can have trouble recieving multiple start signals, this may be what is causing your error.

    Best regards,

    Øyvind

Children
Related