cancel
Showing results for 
Search instead for 
Did you mean: 

STM8AF6223A UART 4 RXNE Flag is not set

CPack.1
Associate

I have a STM8AF6223A Processor connected to another processor on Pin 2, UART TX and Pin 3, UART RX.

The oscilloscope verifies that both processors send correctly, 19200 Baud, 8bit Data, no parity, 1 stop bit.

The STM8 processor receives the data in the UART4->DR register mostly correct, but not always correct. How is it possible that the RXNE Flag does not get set?

I am using the stdlib STM8S/A Standard Peripherals Library V2.3.1 26-April-2018. The IDE is ST Visual Develop with the Cosmic Compiler.

This is my example code:

The waitCounter always increases to 1000, the RXNE Flag is never set. At the same time the other processor sends 0x55 constantly, the data is available.0693W00000Bde61QAB.png0693W00000Bde5XQAR.png

/* Includes ------------------------------------------------------------------*/
#include "stm8s.h"
 
/* Private defines -----------------------------------------------------------*/
#define F_CPU 2000000UL
#define _GPIO 1 /* enables the GPIOs */
#define _EXTI 1 /* enables the EXTI */
 
 
 
void SendData(uint16_t min, uint16_t current)
{
  uint8_t main_state = 1;
  uint8_t checksum = 0;
  uint8_t dummy = 0;
  
  // Check and clear uart error flags
  // Read SR then read DR registers
  dummy = UART4->SR;
  if (dummy & (UART4_SR_OR + UART4_SR_FE + UART4_SR_PE))
  {
    dummy = UART4->DR;
  }
  
  while(main_state != 0)
  {
    switch (main_state)
    {
    case 0:
      // end sending
    break;
      
    case 1:
      // Send sync byte
      while (!(UART4->SR & UART4_SR_TXE)) {};
      UART4->DR = 0x9A;
      main_state++;
      break;
      
    case 2:
      // Send sync byte 2
      while (!(UART4->SR & UART4_SR_TXE)) {};
      UART4->DR = 0x9B;
      main_state++;
      break;
      
    case 3:
      // Send first long term byte
      while (!(UART4->SR & UART4_SR_TXE)) {};
      UART4->DR = (uint8_t)(min);
      checksum = (uint8_t)(min);
      main_state++;
      break;
      
    case 4:
      // Send second long term byte
      while (!(UART4->SR & UART4_SR_TXE)) {};
      UART4->DR = (uint16_t)(min >> 8);
      checksum = checksum + (uint16_t)(min >> 8);
      main_state++;
      break;
      
    case 5:
      // Send first current byte
      while (!(UART4->SR & UART4_SR_TXE)) {};
      UART4->DR = (uint8_t)(current);
      checksum = checksum + (uint8_t)(current);
      main_state++;
      break;
      
    case 6:
      // Send second current byte
      while (!(UART4->SR & UART4_SR_TXE)) {};
      UART4->DR = (uint16_t)(current >> 8);
      checksum = checksum + (uint16_t)(current >> 8);
      main_state++;
      break;
      
    case 7:
      // Send checksum byte
      while (!(UART4->SR & UART4_SR_TXE)) {};
      UART4->DR = checksum;
      main_state++;
      break;
      
    case 8:
      // Send termination byte
      while (!(UART4->SR & UART4_SR_TXE)) {};
      UART4->DR = 0xFF;
			while (!(UART4->SR & UART4_SR_TXE)) {};
      main_state = 0;
      break;
      
    default:
      main_state = 0;
      break;
    }
  }
}
 
void main(void)
{
  uint16_t i = 0;
	uint8_t receivedCommand = 0;
	bool waitForData = TRUE;
	FlagStatus receiveRegisterNotEmpty = RESET;
	uint8_t dummy;
	uint16_t waitCounter = 0;
	
	uint8_t receive_byte = 0;
  
  //disableInterrupts();
  
  UART4_DeInit();
  
  UART4_Init((u32)19200,                   // uint32_t BaudRate
             UART4_WORDLENGTH_8D,          // UART_WordLength_TypeDef WordLength
             UART4_STOPBITS_1,             // UART_StopBits_TypeDef StopBits
             UART4_PARITY_NO,              // UART_Parity_TypeDef Parity
             UART4_SYNCMODE_CLOCK_DISABLE, // UART_SyncMode_TypeDef SyncMode
             UART4_MODE_TXRX_ENABLE        // UART_Mode_TypeDef Mode
             );
  
  //UART4_Cmd(DISABLE);
  
  /* Enable general interrupts */
  //enableInterrupts();
  
  /* Infinite loop */
  while (1)
  {
	  // Try to communicate
    UART4_Cmd(ENABLE);
		
    // Wait
    for (i = 0; i < 2000; i++) // 4000us delay
    {
      _asm("nop");
    }
		
		// Check and clear uart error flags
    // Read SR then read DR registers
		dummy = UART4->DR;
    dummy = UART4->SR;
    if (dummy & (UART4_SR_OR + UART4_SR_FE + UART4_SR_PE))
    {
      dummy = UART4->DR;
    }
 
		waitCounter = 0;
		//waitForData = TRUE;
		while((UART4_GetFlagStatus(UART4_FLAG_RXNE) == RESET) 
		      && (waitCounter < 1000))
		{
			// Wait
      for (i = 0; i < 20; i++) // 40us delay
      {
        _asm("nop");
      }
			waitCounter++;
		}
	
	  receivedCommand = UART4_ReceiveData8();
		
		if (receivedCommand == 0x55)
		{
			receivedCommand = 1;
		}
		else
		{
			receivedCommand = 0;
		}
		
		if (1 == receivedCommand)
		{
      SendData(600, 650);
			
			SendData(600, 650);
			
			SendData(600, 650);
		}
		
		UART4_Cmd(DISABLE);
		
    if (0 == receivedCommand)  // TI may not have power
    {
      // Do not measure too often, add an additional delay
      for (i = 0; i < 50000; i++) // 100ms delay
      {
        _asm("nop");
      }
    }
  }
}

2 REPLIES 2
CPack.1
Associate

Further tests found, that the RXNE flag was not set anymore, if errors were cleared before:

    dummy = UART4->SR;
    if (dummy & (UART4_SR_OR + UART4_SR_FE + UART4_SR_PE))
    {
      dummy = UART4->DR;
    }

The problem is solved by receiving interrupt-based.

Piranha
Chief II

Take a note that typically bit fields are merged with a bitwise OR ('|') operation, not addition ('+').