cancel
Showing results for 
Search instead for 
Did you mean: 

UART transmission Issue in stm32g4

sireevenkat1
Senior

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 

12 REPLIES 12

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.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
sireevenkat1
Senior

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 

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.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
sireevenkat1
Senior

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

Pavel A.
Evangelist III

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.

 

>>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. 

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..

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

Pavel A.
Evangelist III

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

 

>>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.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..