AnsweredAssumed Answered

Overrun detection needed for reliable SCI reception?

Question asked by Johan Forslöf on Mar 21, 2013
Latest reply on Mar 24, 2013 by bigmac

Basically I'm having trouble with a overruns causing a simple SCI receiver getting stuck in a state where no further interrupts can occur.


It seems if overrun occurring between polling SCIS1 and reading SCID leaves the peripheral with RDRF cleared but no longer receiving data, until the buffer is flushed by polling SCID.


__interrupt VectorNumber_Vscirx void ReceiveInterrupt(void) {     char data;     (void) SCIS1;     // The problematic overflow occurs here     data = SCID; }


For the record this happens on both 9S08QE8 and 9S08SH8 but not in the full-chip simulator.


This has rather caught me by surprise as I've previously always just ignored UART errors and this leaves me with a lot of potentially vulnerable old code across various Freescale devices to fix up, possibly even on MCUs from other manufacturers.


So what is the intended way of reliably reading data?



The following is a simple repro case using the loopback mode, which always gets stuck after the overrun.


#include "derivative.h"  // Transmit a character and busy-wait for it to get through static void transmit(char data) {     SCID = data;     data = 0;     do {         __RESET_WATCHDOG();     } while(++data); }  void main(void) {     char overrun = 10;      // Initialize the UART in loopback mode     SCIBD = 1;     SCIC1_LOOPS = 1;     SCIC2 = SCIC2_RE_MASK | SCIC2_TE_MASK;     (void) SCIS1;     (void) SCID;      // Keep transmitting character to ourself     for(;;) {         transmit(overrun);          // Received anything?         if(SCIS1_RDRF) {             // Force an intermittent buffer overflow. Imagine the next character             // arriving in the middle of a delayed interrupt             if(!--overrun)                 transmit(overrun);              // Actually fetch the character             (void) SCID;         }     } }