2021-03-26 10:17 PM
I'm stuck trying to transfer a 1024 bit buffer to a SSD1306 via I2C/DMA using the HAL. I am using a stm32L432 nucleo board.
Using HAL_I2C_Mem_Write works fine, but HAL_I2C_Mem_Write_DMA only transmits the first 255 bytes and leaves the bus hung on HAL_I2C_STATE_BUSY_TX.
I have read that this is because the DMA is faster than the I2C transfer and finishes first, but I don't know how to correct this... Stepping through HAL_I2C_Mem_Write_DMA, it seems to set everything up right, setting xfermode = I2C_RELOAD_MODE; and taking into account that the data to be sent is >255 bytes. It LOOKS like it is supposed to loop through again until NBYTES is 0, but it only goes through once and then triggers the I2C_ISR_TCR interrupt.
From within the interrupt handler, I can see NBYTES is still 255 as expected, and I2C_CR2_RELOAD = 1
I2C_CR2_START = 0
I2C_CR2_AUTOEND = 0
xferCount = 769
DMA_CCR_EN = 1
DMA_ISR_TCIF6 = 0
if I reset NBYTES with
I2C1->CR2 &= ~(I2C_CR2_NBYTES);
I2C1->CR2 |= (255 << I2C_CR2_NBYTES_Pos);
That clears I2C_ISR_TCR, but it does not continue the transfer.
Looking at page 1153 on the datasheet, it seems like it should be working. Is the DMA somehow stopping the I2C transfer thinking it is complete? What do I need to do to get this working? Is there some flag or interrupt I need to clear to get it to loop through the remaining times?
Thanks!