cancel
Showing results for 
Search instead for 
Did you mean: 

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

b0
Visitor

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);    
}

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.

0 REPLIES 0