Skip to main content
Explorer II
January 25, 2024
Question

UART transmission Issue in stm32g4

  • January 25, 2024
  • 6 replies
  • 3306 views

Hi,
I am working with STM32G4.I am communicating with STM32G4 with other controller through  UART communication.
I can able to receive the data from other MCU to STM32G4 all the time but sometimes I can't able to transmit data from stm32g4 to other MCU.I used UART PollForConversion method  for development.
I receive the data from other MCU to STM32g4 for every 1sec.
Below is the STM32G4 side code:

 

uint8_t ocpp_txdata[64];
uint8_t ocpp_rxdata[8];
while(){
 HAL_UART_Receive(&huart5,ocpp_rxdata,7, 1000);
	uint16_t calculatedCRC;
	uint16_t receivedCRC;
 if(ocpp_rxdata[0]==0x22)
 { 	
 	 calculatedCRC = HAL_CRC_Calculate(&hcrc,(uint32_t *)&ocpp_rxdata, 4); 	 
 	 receivedCRC=ocpp_rxdata[4]<<8 | ocpp_rxdata[5];
 	 if(calculatedCRC==receivedCRC){
 switch(ocpp_rxdata[2])
 {
 case 0x01:
 //trasmit data ocpp_txdata[0] to ocpp_txdata[18] 
 //ocpp_txdata[16],ocpp_txdata[17] is crc
 HAL_UART_Transmit(&huart5, ocpp_txdata,19, 100);
 break;
 case 0x02:
 //trasmit data ocpp_txdata[0] to ocpp_txdata[13] 
 //ocpp_txdata[11],ocpp_txdata[12] is crc
 HAL_UART_Transmit(&huart5, ocpp_txdata,14, 100);
 break;
}
}
}

 

I can able to transmit the data from stm32g4 to other mcu but sometimes I can't.
What I observed is whenever I restated the system and if I remove the power in those cases initially I can't able to transmit.

Can anyone suggest what may be the issue.
I know interrupt mode for UART works better but I have to do with pollforconversion method only.

Thanks 

    This topic has been closed for replies.

    6 replies

    Graduate II
    January 25, 2024

    Are you sure the data is received and in-sync with the correct CRC? Because if not, this code won't send anything back.

    Output diagnostics to SWV or another UART for review.

    Explorer II
    January 25, 2024

    Hi @Tesla DeLorean ,

    I can able to see the transmitted data from STM32G4 to other mcu in dock light that means CRC is in sync. The problem is some times its not transmitting, Yes, may be that time CRC not in sync that's why I can able to receive but I can't able to transmit.
    How to solve the issue like its happening sometimes not every time.
    Coming to UART-its same with other uart also and  I am using UART not USART is that make any difference.

    Thanks 

    Graduate II
    January 25, 2024

    UART vs USART shouldn't make a difference. 

    You ignore errors from the HAL and use blocking receive and transmit methods. The UART can concurrently do both. Your receive method is apt to miss characters. 

    I suspect you removed code creating txdata frames.

    Explorer II
    January 25, 2024

    Tx_data is correct only I just removed because it is just assigning the values.
    below I mentioned that part

    ocpp_txdata[0] = 0x23;
    	 ocpp_txdata[1] = 0x12;
    	 ocpp_txdata[2] = 0x12;
    	 ocpp_txdata[3] = 0x02;
    	 ocpp_txdata[4] = 0x01;
     ocpp_txdata[5] =0x00;
    	 ocpp_txdata[6] =0x01;
     ocpp_txdata[7] 0x02;
    	 ocpp_txdata[8] =0x04;
    	 ocpp_txdata[9] =0x01;
     ocpp_txdata[10] =0x05;
     ocpp_txdata[11] =0x04;
    	 ocpp_txdata[12] =0x02;
    	 ocpp_txdata[13] =0x00;
     ocpp_txdata[14] =0x05;
    	 ocpp_txdata[15] =0x05;
    	 // compute CRC to place into last 2 bytes
    	 uint16_t calculatedCRC = HAL_CRC_Calculate(&hcrc,(uint32_t *)&ocpp_txdata, 16);
    
    	 ocpp_txdata[16] = (calculatedCRC >> 8) & 0xFF; //high CRC byte
    	 ocpp_txdata[17] = calculatedCRC & 0xFF; //low CRC byte
    
     ocpp_txdata[18] = 0x04;
    HAL_UART_Transmit(&huart5, ocpp_txdata,19, 100);


     Your receive method is apt to miss characters. 


    Is there any other way please suggest
    Thanks

    Graduate II
    January 25, 2024

    >>Is there any other way please suggest

    Byte-wise in the IRQ handler, into a ring-buffer, that you manager later, say in the foreground task.

    HAL_UART_Transmit(&huart5, ocpp_txdata,19, 100); // Blocks for 18-19 character times

    Would want to use a HAL_UART_ReceiveIT() cyclically so it catches all inbound data as it arrives. A non-HAL implementation is all possible and likely more efficient. 

    Explorer II
    January 29, 2024

    Hi @Tesla DeLorean ,
    Below I modified the code with UART interrupt for reception. Can you suggest is it correct way or not?
    I receive 7 bytes of data from other MCU to STM32G4 everytime.


    @Tesla DeLorean wrote:

    >>Is there any other way please suggest

    Byte-wise in the IRQ handler, into a ring-buffer, that you manager later, say in the foreground task.

    Would want to use a HAL_UART_ReceiveIT() cyclically so it catches all inbound data as it arrives. 


     

    UART_HandleTypeDef huart5;
    UART_RXBUFFER_SIZE 8
    uint8_t ocpp_rxdata[UART_RXBUFFER_SIZE ];
    uint8_t rx_index = 0;
    uint8_t ocppalldata_received = 0;
    
    int main(void) {
     //initialize all configured peripherals
     // Start UART reception in interrupt mode
     HAL_UART_Receive_IT(&huart5, ocpp_rxdata, sizeof(ocpp_rxdata));
     while (1) {
    	ocpp_request();
     }
    }
    
    void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart) {
     if (huart->Instance == huart5) {
     if (rx_index < UART_RXBUFFER_SIZE) {
     ocpp_rxdata[rx_index++] = huart->Instance->RDR; // Read received data
     if (rx_index >= UART_RXBUFFER_SIZE) {
     ocppdata_received = 1; // Set flag when buffer is full
     }
     }
     }
    }
    void ocpp_request()
    {
    	if (ocppdata_received) {
     // Check CRC and start transmission
    	 uint16_t calculatedCRC;
    	 uint16_t receivedCRC;
    	 if(ocpp_rxdata[0]==0x22){
     calculatedCRC = HAL_CRC_Calculate(&hcrc, (uint32_t *)&ocpp_rxdata, 4);
     receivedCRC = ocpp_rxdata[4] << 8 | ocpp_rxdata[5];
     
     if (calculatedCRC == receivedCRC) {
     switch (ocpp_rxdata[2]) {
     case 0x01:
    					 ocpp_txdata[0] = 0x23;
    					 ocpp_txdata[1] = 0x09;
    					 ocpp_txdata[2] = 0x11;
    					 ocpp_txdata[3] = 0x23;
    					 ocpp_txdata[4] = 0x09;
    					 ocpp_txdata[5] = 0x11;
     HAL_UART_Transmit(&huart5, ocpp_txdata, 6, 100);
     break;
     case 0x02:
    					 ocpp_txdata[0] = 0x23;
    					 ocpp_txdata[1] = 0x09;
    					 ocpp_txdata[2] = 0x15;
    					 ocpp_txdata[3] = 0x24;
    					 ocpp_txdata[4] = 0x03;
    					 ocpp_txdata[5] = 0x14;
     HAL_UART_Transmit(&huart5, ocpp_txdata, 6, 100);
     break;
     
     }
     }
    
     // Reset flags and buffer
     ocppdata_received = 0;
     rx_index = 0;
    	HAL_UART_Receive_IT(&huart5, ocpp_rxdata, sizeof(ocpp_rxdata));
     }
    	}
     }

     

     


    Thanks

    Super User
    January 25, 2024

    whenever I restated the system and if I remove the power in those cases initially I can't able to transmit.

    What means initially? Will the transmission start working by itself after some time or you have to reset the STM32 several times?

    There is whole class of notorious issues with starting the app after power cycle vs. no power cycle, under debugger vs. no debugger - caused often by wrong connection of NRST or BOOT0 pins. And another class of notorious issues caused by bad power.

     

    Explorer II
    January 30, 2024

    @Pavel A. wrote:

    whenever I restated the system and if I remove the power in those cases initially I can't able to transmit.

    What means initially? Will the transmission start working by itself after some time or you have to reset the STM32 several times?


    Hi @Pavel A. ,
    As per my observation till now most of the times either I have to reset the STM32 or I have to debug the program again to get it worked.
    Few times transmission starting by it self after some time.
    Initially I observed this issue while using the breakpoints whenever breakpoint occurs, transmission from STM32 to other MCU getting stopped but reception of data from other MCU to STM32 happening.
    After that now I am observing above issue.
    Boot0 pin is connected to GND through 10K resistor.
    NRST pin is connected to reset switch setup.
    Is both pins are correct?

    Thanks

    Super User
    January 29, 2024

    Would want to use a HAL_UART_ReceiveIT() cyclically so it catches all inbound data as it arrives.

    Sorry but this often is a recipe for failure. Every call to HAL_UART_ReceiveIT enables the RX interrupt and disables it on completion, creating time windows when interrupt is disabled. This is especially harmful with size = 1 and no FIFO,

    >A non-HAL implementation is all possible and likely more efficient.

    +1

     

    Graduate II
    January 29, 2024

    >>Sorry but this often is a recipe for failure. 

    I haven't looked at the implementation details in a while, but I'm pretty sure there shouldn't be any kind of race condition if the interrupt is reenabled within the interrupt handler / call-back. The trick would be not to wander off task doing things that take longer than the expected reception time.

    Super User
    January 29, 2024

     if the interrupt is reenabled within the interrupt handler / call-back

    A higher priority interrupt can cut in and here you get it. The precious CPU cycles in the handler could be better used to save or compare the received bytes.

     

    Explorer II
    February 2, 2024

    Hi @Pavel A. @Tesla DeLorean ,

    I checked UART communication from pollforconversion to interrupt method. but I am facing the issue.The data is transmitting and receiving between stm32g4 and other mcu.Some time I am not receiving the data properly like SOF always 0x22 and EOF 0x04 always. data bytes not coming peroperly as expected so then i can't be tramit and receive the proper data.
    below added code

    int main(){ 
    //all initializations
    HAL_UART_RegisterCallback(&huart5,HAL_UART_RX_COMPLETE_CB_ID,HAL_UART_RxCpltCallback);
     HAL_UART_RegisterCallback(&huart5,HAL_UART_TX_COMPLETE_CB_ID,HAL_UART_TxCpltCallback);
     HAL_UART_Receive_IT(&huart5, ocpp_rxdata, 7); /* USER CODE END 2 */
    while(1){
     request();
    }
    }
    void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart) {
     if (huart->Instance == huart5.Instance) {
     alldata_received = 1;
    }
    }
    void request()
    {
    	if (alldata_received) {
     uint16_t calculatedCRC;
    	uint16_t receivedCRC;
     if(ocpp_rxdata[0]==0x22)
     { 	
     	 calculatedCRC = HAL_CRC_Calculate(&hcrc,(uint32_t *)&ocpp_rxdata, 4); 	 
     	 receivedCRC=ocpp_rxdata[4]<<8 | ocpp_rxdata[5];
     	 if(calculatedCRC==receivedCRC){
     switch(ocpp_rxdata[2])
     {
     case 0x01:
     //trasmit data ocpp_txdata[0] to ocpp_txdata[18] 
     //ocpp_txdata[16],ocpp_txdata[17] is crc
     HAL_UART_Transmit_IT(&huart5, ocpp_txdata,19);
     break;
     case 0x02:
     //trasmit data ocpp_txdata[0] to ocpp_txdata[13] 
     //ocpp_txdata[11],ocpp_txdata[12] is crc
     HAL_UART_Transmit_IT(&huart5, ocpp_txdata,14);
     break;
     }
     }
     else{
     crc_error();
     }
     }
    	alldata_received = 0;
    	HAL_UART_Receive_IT(&huart5, ocpp_rxdata, 7);
    }
    void HAL_UART_TxCpltCallback(UART_HandleTypeDef *huart)
    {
    	memset(ocpp_rxdata, '\0',7); //empty the reception data buffer
    
    }


    Sometimes data reception and tramission happening normally only but sometimes I am receiving the in the proper format so receiver data byte are changing so can't able to receive or transmit.
    Please suggest .
    Thanks