4 posts / 0 new
Last post
booyeon
Offline
Last seen:4 years 7 months ago
Joined:2015-09-14 18:36
I2C data transfer size

Is there a way to send/receive more than 32 bytes of data through I2C in one go?

Device:
MT_dialog
Offline
Last seen:1 month 3 weeks ago
Staff
Joined:2015-06-08 11:34
Hi booyeon,

Hi booyeon,

The current drivers implementation uses the 32 byte transmit and receive FIFO. You can send bursts of data with the current implementation since the driver checks if the TFNF flag so it keeps feeding data in the FIFO as long as it has room. Regarding the receiving side the driver has this limitation since 32 is the FIFO size, you will have to implement a different reading process in order to take more than 32 bytes, i suppose that you can poll the status of your receiving FIFO (full, not full) through the RFF and RFNE flags of the I2C_STATUS_REG and if there is room in the receive FIFO clock data from the slave or wait until there is room in the FIFO.

Thanks MT_dialog

booyeon
Offline
Last seen:4 years 7 months ago
Joined:2015-09-14 18:36
I did the following but did

I did the following but did not seem to work. Please advise if you see any issues. Thanks.

Initially request for 32 bytes read at the start
for (j = 0; j < 32; j++)
SEND_I2C_COMMAND(0x0100);

Then generate an interrupt based on RXFIFO level set to less than 32 bytes; e.g. 16 bytes.
Once the interrupt is generated, check and read available data in the RXFIFO and request for more data
input_level = GetWord16(I2C_RXFLR_REG);
for (i=0; iinput_buffer[i++] = (0xFF & GetWord16(I2C_DATA_CMD_REG));
for (j=0; jSEND_I2C_COMMAND(0x0100);

MT_dialog
Offline
Last seen:1 month 3 weeks ago
Staff
Joined:2015-06-08 11:34
Hi booyeon,

Hi booyeon,

基于i2c_eeprom外围的例子我done some modifications presented below, please try them out seems to be working on my side.

1. Enable the NVIC in order to get the I2C R_RX_FULL interrupts.

2. Set the I2C_RX_TL_REG to the value that you want.

3. Unset the M_TX_EMPTY since its enabled by default (hits when the FIFO is empty)

4. Create a function i2c_eeprom_read_data_cust():

uint32_t i2c_eeprom_read_data_cust(uint8_t *rd_data_ptr, uint32_t address, uint32_t size)
{
uint32_t bytes_read = 0x100; //left overs from example

i2c_wait_until_eeprom_ready();
i2c_send_address(address);
read_data_cust(&rd_data_ptr, address, 0x100);

return bytes_read; //left overs from example
}

5. The read_data_cust():

static void read_data_cust(uint8_t **p, uint32_t address, uint32_t size)
{
int j;
for (j = 0; j < size; j++)
{
WAIT_WHILE_I2C_FIFO_IS_FULL(); // Wait if Tx FIFO is full
SEND_I2C_COMMAND(0x0100); // Set read access for times
}
}

6. When the FIFO threshold is over the interrupt will occur and will be served by the below ISR:

void read_i2c_int_custom(void)
{
while(GetWord16(I2C_RXFLR_REG))
{
*test_p =(0xFF & GetWord16(I2C_DATA_CMD_REG)); // Get the received byte
test_p++;
}
}

Hope it helps,

Thanks MT_dialog

Topic locked