cancel
Showing results for 
Search instead for 
Did you mean: 

I2C communication via GPDMA on STM32U5 - stops transmitting after two messages

b0
Associate

Hello
I am new to the STM32U5 and have problems with I2C communication via GPDMA.
My transmit buffer consists out of ten messages that should be send.
Strangely, only two write commands are written to the bus. However, this includes the first and the third buffer content of the Tx buffer - the second buffer content is not transmitted. After a new I2C start condition, no further content is written to the bus except the write address.

This is the configuration of the GPDMA:
In the case of using a falling or rising edge as the TriggerPolarity, only the starting condition is generated and readable on the bus. The behavior described above applies to the Masked polarity configuration as shown in the code.

void DMA_memoryToPeriperhalInitSTC(uint8_t *I2C_RxDatabuffer,uint8_t *I2C_TxDatabuffer) { uint32_t I2C4_PeriperhalTxAddress = LL_I2C_DMA_GetRegAddr(I2C4, LL_I2C_DMA_REG_DATA_TRANSMIT); uint32_t MemorySrcAddress = (uint32_t)&I2C_TxDatabuffer[0]; // ######################################################### // DMA init Memory to peripheral (tx-transmit) LL_DMA_InitTypeDef DMA_InitTxStruct = {0}; DMA_InitTxStruct.SrcAddress = MemorySrcAddress; DMA_InitTxStruct.DestAddress = I2C4_PeriperhalTxAddress; DMA_InitTxStruct.Direction = LL_DMA_DIRECTION_MEMORY_TO_PERIPH; DMA_InitTxStruct.BlkHWRequest = LL_DMA_HWREQUEST_BLK; DMA_InitTxStruct.DataAlignment = LL_DMA_DATA_ALIGN_ZEROPADD; DMA_InitTxStruct.SrcDataWidth = LL_DMA_SRC_DATAWIDTH_BYTE; DMA_InitTxStruct.DestDataWidth = LL_DMA_SRC_DATAWIDTH_BYTE; DMA_InitTxStruct.SrcIncMode = LL_DMA_SRC_INCREMENT; DMA_InitTxStruct.DestIncMode = LL_DMA_DEST_FIXED; DMA_InitTxStruct.Priority = LL_DMA_HIGH_PRIORITY; DMA_InitTxStruct.BlkDataLength = 10; DMA_InitTxStruct.BlkRptCount = 0; DMA_InitTxStruct.TriggerPolarity = LL_DMA_TRIG_POLARITY_MASKED; DMA_InitTxStruct.TriggerSelection = LL_GPDMA1_TRIGGER_GPDMA1_CH10_TCF; DMA_InitTxStruct.Request = LL_GPDMA1_REQUEST_I2C4_TX; DMA_InitTxStruct.TransferEventMode = LL_DMA_TCEM_BLK_TRANSFER; LL_DMA_Init (GPDMA1, LL_DMA_CHANNEL_10, &DMA_InitTxStruct); LL_DMA_SetSrcAllocatedPort(GPDMA1, LL_DMA_CHANNEL_10, LL_DMA_SRC_ALLOCATED_PORT0); LL_DMA_EnableChannel (GPDMA1, LL_DMA_CHANNEL_10); // ######################################################### // DMA init Memory to peripheral (rx - receive) uint32_t I2C4_PeriperhalRxAddress = LL_I2C_DMA_GetRegAddr(I2C4, LL_I2C_DMA_REG_DATA_RECEIVE); uint32_t MemoryDstAddress = (uint32_t)&I2C_RxDatabuffer[0]; LL_DMA_InitTypeDef DMA_InitRxStruct = {0}; DMA_InitRxStruct.SrcAddress = I2C4_PeriperhalRxAddress; DMA_InitRxStruct.DestAddress = MemoryDstAddress; DMA_InitRxStruct.Direction = LL_DMA_DIRECTION_PERIPH_TO_MEMORY; DMA_InitRxStruct.BlkHWRequest = LL_DMA_HWREQUEST_BLK; DMA_InitRxStruct.DataAlignment = LL_DMA_DATA_ALIGN_ZEROPADD; DMA_InitRxStruct.SrcDataWidth = LL_DMA_SRC_DATAWIDTH_BYTE; DMA_InitRxStruct.DestDataWidth = LL_DMA_SRC_DATAWIDTH_BYTE; DMA_InitRxStruct.SrcIncMode = LL_DMA_SRC_FIXED; DMA_InitRxStruct.DestIncMode = LL_DMA_DEST_INCREMENT; DMA_InitRxStruct.Priority = LL_DMA_HIGH_PRIORITY; DMA_InitRxStruct.BlkDataLength = 10; DMA_InitRxStruct.BlkRptCount = 0; DMA_InitRxStruct.TriggerPolarity = LL_DMA_TRIG_POLARITY_MASKED; DMA_InitRxStruct.TriggerSelection = LL_GPDMA1_TRIGGER_GPDMA1_CH1_TCF; DMA_InitRxStruct.Request = LL_GPDMA1_REQUEST_I2C4_RX; LL_DMA_Init (GPDMA1, LL_DMA_CHANNEL_11, &DMA_InitRxStruct); LL_DMA_SetSrcAllocatedPort(GPDMA1, LL_DMA_CHANNEL_11, LL_DMA_SRC_ALLOCATED_PORT1); LL_DMA_EnableChannel (GPDMA1, LL_DMA_CHANNEL_11); }
View more

The I2C config:
I think most relevant for connecting GPDMA and I2C are enabling of rx and tx requests

void I2C_initC(void) { LL_I2C_Disable(I2C4); LL_I2C_InitTypeDef I2C_InitTypeDef_t = {0}; I2C_InitTypeDef_t.PeripheralMode = LL_I2C_MODE_I2C; I2C_InitTypeDef_t.Timing = __LL_I2C_CONVERT_TIMINGS(I2C_TIMING_PRESCALER, I2C_TIMING_SETUPTIME, I2C_TIMING_HOLDTIME, I2C_TIMING_HIGHPERIOD, I2C_TIMING_LOWPERIOD); I2C_InitTypeDef_t.AnalogFilter = LL_I2C_ANALOGFILTER_ENABLE; I2C_InitTypeDef_t.DigitalFilter = 0; I2C_InitTypeDef_t.OwnAddress1 = 0; I2C_InitTypeDef_t.TypeAcknowledge = LL_I2C_ACK; I2C_InitTypeDef_t.OwnAddrSize = LL_I2C_OWNADDRESS1_7BIT; (void) LL_I2C_Init(I2C4, &I2C_InitTypeDef_t); LL_I2C_EnableDMAReq_TX(I2C4); LL_I2C_EnableDMAReq_RX(I2C4); LL_I2C_EnableIT_RX (I2C4); LL_I2C_Enable(I2C4); }

The loop in the main function to transmit and receive sensordata.
The transmit as well as the receive buffer are of the datatype uint8_t.

for(uint8_t i = 0; i<= 9 ; i++) { // write I2C CheckTXISF(); LL_I2C_SetSlaveAddr(I2C4, SensorWriteAdress); LL_I2C_SetTransferSize(I2C4, 0x01u); LL_I2C_SetTransferRequest(I2C4, LL_I2C_REQUEST_WRITE); LL_I2C_GenerateStartCondition(I2C4); // Read I2C CheckTXISF(); LL_I2C_SetSlaveAddr(I2C4, SensorReadAddress); LL_I2C_SetTransferSize(I2C4, 0x01u); LL_I2C_SetTransferRequest(I2C4, LL_I2C_REQUEST_READ); LL_I2C_GenerateStartCondition(I2C4); CheckSTOPF(); }


I would appreciate any hint regarding I2C communication via GPDMA.

1 REPLY 1
Maxime_MARCHETTO
Community manager
Community manager

Hello @b0,

Welcome to the ST Community!

This post has been escalated to the ST Online Support Team for additional assistance.  We'll contact you directly.

Best regards,
Maxime


In order to give better visibility on the answered topics, please click on 'Accept as Solution' on the reply which solved your issue or answered your question.