Question: Handling PIC USART "overrun" & "framing" errors

Thread Starter

MMcLaren

Joined Feb 14, 2010
861
I'm using Receive Character (RCIF) interrupts along with a circular buffer and checking for "overrun" and "framing" errors in my interrupt handler.

My question is, if I get an "overrun" or a "framing" error, will that prevent the USART from generating an RCIF interrupt? In other words, is there a chance that an error can occur but I won't know about it because the USART didn't generate an RCIF interrupt and the error conditions are only being checked in my interrupt handler?

Honestly, I don't think I've ever experienced either type of USART error condition in the past but I'd like to make my code more robust so I'd like to include error handling capability. I'm just not sure how to do it.

TIA... Cheerful regards, Mike

Code:
;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
;  interrupt vector                                               ~
;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
        org     0x0004
v_int                           ; using 'RCIF' interrupts only
;
;  check for 'framing' and 'overrun' error conditions
;
        movlb   RCSTA/128       ; bank 3                          |03
        btfsc   RCSTA,FERR      ; framing error? no, skip, else   |03
        bra     FERR_error      ; branch (correct framing error)  |03
        btfsc   RCSTA,OERR      ; overrun error? no, skip, else   |03
        bra     OERR_error      ; branch (correct overrun error)  |03
;
;  prep for indirect access at 'push' pointer in circular buffer
;
        movlw   rxbuf/256       ; FSR1 = &rxbuf[push]             |03
        movwf   FSR1H           ;  "                              |03
        movlw   rxbuf%256       ;  "                              |03
        addwf   push,W          ;  "                              |03
        movwf   FSR1L           ;  "                              |03
;
;  add Rx character to circular buffer (clears RCIF int flag)
;
        movf    RCREG,W         ; get Rx char, clear RCIF flag    |03
        movwf   INDF1           ; rxbuf[push] = rcreg             |03
;
;  if push pointer + 1 equals pull pointer, exit (buffer full)
;
        incf    push,W          ;                                 |03
        andlw   buffersize-1    ; wreg = ++push % buffersize      |03
        xorwf   pull,W          ; full (push + 1 == pull)?        |03
        skpnz                   ; no, skip, else                  |03
        retfie                  ; exit (ignore new character)     |??
;
;  increment 'push' pointer
;
        xorwf   pull,W          ; wreg = ++push % buffersize      |03
        movwf   push            ; update 'push' pointer           |03
        retfie                  ;                                 |??
;
;  handle 'overrun' and 'framing' errors  ????
;
OERR_error
FERR_error
        bcf     RCSTA,SPEN      ; reset receiver                  |03
        movf    RCREG,W         ; clear RCReg                     |03
        movf    RCREG,W         ;                                 |03
        bsf     RCSTA,SPEN      ; enable receiver                 |03
        retfie                  ;                                 |??

;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
Last edited:

JohnInTX

Joined Jun 26, 2012
4,787
A framing error does not disable reception or interrupts. An overrun error disables both.

For framing errors, I sometimes jam an escape code into the RX buffer to indicate the problem. The consumer can figure it out from there - usually a flush buffer and re-sync. Since framing errors are almost always caused by baudrate problems it's usually fatal.

Overrun errors are important to detect on each character since you won't get any further interrupts. The remedy is again to flush and re-sync. The reality is that overrun errors indicate that your code can't keep up with the data. Faster processing, slower baudrate, character pacing by the transmitter are possible solutions.

I try to incorporate the error handling / recovery in the low level receiver but the reality is that either means your data is kaput and you need to restart. In that case, a simple flag or return value for getchar() would be sufficient. As long as 1) the UART gets fixed without a RESET and 2)you don't use corrupt data, you're good.

Either error usually means that you need some design changes. As you've seen, if the design is right you don't see them very often if at all but you always need to code to handle them just in case.

Have fun!
 

nsaspook

Joined Aug 27, 2009
13,261
Top