Skip to main content
Explorer
August 14, 2024
Solved

Low Layer API for I2C Communication in Stm32L031

  • August 14, 2024
  • 4 replies
  • 4366 views

Hi,

I have created a code snippet to communicate with I2C using LL API instead of HAL. The code is given below

 

uint8_t temp[2]={0xF9,0x00};

while(LL_I2C_IsActiveFlag_BUSY(I2C1)); // Wait until the I2C bus is not busy



LL_I2C_HandleTransfer(I2C1, 0x94, LL_I2C_ADDRSLAVE_7BIT, 2, LL_I2C_MODE_AUTOEND, LL_I2C_GENERATE_START_WRITE);

LL_mDelay(10);

for (int i = 0; i < 2; i++) {

while (!LL_I2C_IsActiveFlag_TXE(I2C1)); // Wait until the data register is empty



if (LL_I2C_IsActiveFlag_NACK(I2C1)) { // Check for NACK (Not Acknowledged)



return 1;

}



LL_I2C_TransmitData8(I2C1, temp[i]); // Transmit data byte

LL_mDelay(10);

LL_I2C_ClearFlag_TXE(I2C1);



}



LL_I2C_GenerateStopCondition(I2C1);

LL_mDelay(10);

LL_I2C_ClearFlag_STOP(I2C1); // Clear the stop flag





// Reception (Rx)

LL_I2C_HandleTransfer(I2C1, 0x94, LL_I2C_ADDRSLAVE_7BIT, 16, LL_I2C_MODE_AUTOEND, LL_I2C_GENERATE_START_READ);



int i = 0;



// Wait for the stop condition or reception of 16 bytes

while (!LL_I2C_IsActiveFlag_STOP(I2C1)) {

if (LL_I2C_IsActiveFlag_RXNE(I2C1)) { // Check if data is received

Received[i++] = LL_I2C_ReceiveData8(I2C1); // Store received data

if (i >= 16) break; // Exit if 16 bytes have been received

}

}



// Ensure stop flag is cleared after reception is complete

if (LL_I2C_IsActiveFlag_STOP(I2C1)) {

LL_I2C_ClearFlag_STOP(I2C1);

}

 

 

 

i am able to transmit the data, but failed to read from the buffer. Anyone with prior experience in LL I2C can give me solution for this.

    This topic has been closed for replies.
    Best answer by Saket_Om

    Hello @Sivakumarzcs128 

    To transfer data exceeding 255 bytes, you need to enable the reload mode.

    LL_I2C_HandleTransfer(I2C3, SLAVE_OWN_ADDRESS, LL_I2C_ADDRSLAVE_7BIT, ubNbDataToTransmit, LL_I2C_MODE_RELOAD, LL_I2C_GENERATE_START_WRITE);

     

    This API should be called for each 255-byte transfer. The final call to this function should use the autoend mode.

    In your case, you need to transfer 284 bytes, so you will call the API the first time with reload mode and the second time with autoend mode.

    Here is the LL code for calling the function:

    // First call with reload mode for the first 255 bytes
    LL_I2C_HandleTransfer(I2C3, SLAVE_OWN_ADDRESS, LL_I2C_ADDRSLAVE_7BIT, 255, LL_I2C_MODE_RELOAD, LL_I2C_GENERATE_START_WRITE);
    
    // ...
    
    // Second call with autoend mode for the remaining 29 bytes
    LL_I2C_HandleTransfer(I2C3, SLAVE_OWN_ADDRESS, LL_I2C_ADDRSLAVE_7BIT, 29, LL_I2C_MODE_AUTOEND, LL_I2C_GENERATE_NOSTARTSTOP);

     

    4 replies

    Technical Moderator
    August 14, 2024

    Hello @Sivakumarzcs128 

     

    Is the RXNE flag set? Or is the following if condition is true 

     

    if (LL_I2C_IsActiveFlag_RXNE(I2C1))

     

    Is the following instruction executed:

     

     

    Received[i++] = LL_I2C_ReceiveData8(I2C1);

     

    How the variable Received is declared? 

     

     

     

    Explorer
    August 14, 2024

    The RXNE flag is set when the Handle transfer for read is completed and then reset when i check the stop flag condition. Also the variable received is declared as a buffer .

    Technical Moderator
    August 14, 2024

    @Sivakumarzcs128 

    Could you place a breakpoint on the following instruction and check if the data is being read from the SPI data register?

    Received[i++] = LL_I2C_ReceiveData8(I2C1);

     

    Explorer
    August 14, 2024

    i am always stuck here in this point 

    while (!LL_I2C_IsActiveFlag_STOP(I2C1))

    Also what are the things taken care during changing from HAL to LL in Stm32l031. 

    Explorer
    August 16, 2024

    We have changed the code and now the I2C communication looks fine. Now we faces an issues of reading some data buffer ,where the buffer contains more than 255 data. 

    LL_I2C_SetSlaveAddr(I2C1, (devAddr << 1) );

    LL_I2C_SetTransferSize(I2C1, rxsize);

    LL_I2C_SetTransferRequest(I2C1, LL_I2C_REQUEST_READ);

    LL_I2C_GenerateStartCondition(I2C1);

     

    The rxsize buffer is nearly 284, But the SetTransferSize parameter must be a value between Min_Data=0x00 and Max_Data=0xFF.

    How can we read the remaing datas without losing any. given below is how we read the data

     

    while(LL_I2C_IsActiveFlag_RXNE(I2C1))

    {

    *rxbyte = LL_I2C_ReceiveData8(I2C1);

    LL_mDelay(5);

    rxbyte++;

    }

    Saket_OmAnswer
    Technical Moderator
    August 16, 2024

    Hello @Sivakumarzcs128 

    To transfer data exceeding 255 bytes, you need to enable the reload mode.

    LL_I2C_HandleTransfer(I2C3, SLAVE_OWN_ADDRESS, LL_I2C_ADDRSLAVE_7BIT, ubNbDataToTransmit, LL_I2C_MODE_RELOAD, LL_I2C_GENERATE_START_WRITE);

     

    This API should be called for each 255-byte transfer. The final call to this function should use the autoend mode.

    In your case, you need to transfer 284 bytes, so you will call the API the first time with reload mode and the second time with autoend mode.

    Here is the LL code for calling the function:

    // First call with reload mode for the first 255 bytes
    LL_I2C_HandleTransfer(I2C3, SLAVE_OWN_ADDRESS, LL_I2C_ADDRSLAVE_7BIT, 255, LL_I2C_MODE_RELOAD, LL_I2C_GENERATE_START_WRITE);
    
    // ...
    
    // Second call with autoend mode for the remaining 29 bytes
    LL_I2C_HandleTransfer(I2C3, SLAVE_OWN_ADDRESS, LL_I2C_ADDRSLAVE_7BIT, 29, LL_I2C_MODE_AUTOEND, LL_I2C_GENERATE_NOSTARTSTOP);

     

    Technical Moderator
    August 22, 2024

    Hello @Sivakumarzcs128 

    Has your issue been resolved by using the reload mode?

    ST Employee
    August 22, 2024

    hello @Sivakumarzcs128  , 

    You can follow the examples provided in the STM32CubeL0 repository on GitHub. Specifically, you can refer to the  I2C LL examples for the NUCLEO-L073RZ board , it can help you to solve your issue : 

    STM32CubeL0/Projects/NUCLEO-L073RZ/Examples_LL/I2C at master · STMicroelectronics/STM32CubeL0 · GitHub

     

    BR