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

Discussion in 'Embedded Systems and Microcontrollers' started by MMcLaren, Jun 13, 2018.

  1. MMcLaren

    Thread Starter Distinguished Member

    Feb 14, 2010
    837
    158
    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 (ASM):
    1. ;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    2. ;  interrupt vector                                               ~
    3. ;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    4.         org     0x0004
    5. v_int                           ; using 'RCIF' interrupts only
    6. ;
    7. ;  check for 'framing' and 'overrun' error conditions
    8. ;
    9.         movlb   RCSTA/128       ; bank 3                          |03
    10.         btfsc   RCSTA,FERR      ; framing error? no, skip, else   |03
    11.         bra     FERR_error      ; branch (correct framing error)  |03
    12.         btfsc   RCSTA,OERR      ; overrun error? no, skip, else   |03
    13.         bra     OERR_error      ; branch (correct overrun error)  |03
    14. ;
    15. ;  prep for indirect access at 'push' pointer in circular buffer
    16. ;
    17.         movlw   rxbuf/256       ; FSR1 = &rxbuf[push]             |03
    18.         movwf   FSR1H           ;  "                              |03
    19.         movlw   rxbuf%256       ;  "                              |03
    20.         addwf   push,W          ;  "                              |03
    21.         movwf   FSR1L           ;  "                              |03
    22. ;
    23. ;  add Rx character to circular buffer (clears RCIF int flag)
    24. ;
    25.         movf    RCREG,W         ; get Rx char, clear RCIF flag    |03
    26.         movwf   INDF1           ; rxbuf[push] = rcreg             |03
    27. ;
    28. ;  if push pointer + 1 equals pull pointer, exit (buffer full)
    29. ;
    30.         incf    push,W          ;                                 |03
    31.         andlw   buffersize-1    ; wreg = ++push % buffersize      |03
    32.         xorwf   pull,W          ; full (push + 1 == pull)?        |03
    33.         skpnz                   ; no, skip, else                  |03
    34.         retfie                  ; exit (ignore new character)     |??
    35. ;
    36. ;  increment 'push' pointer
    37. ;
    38.         xorwf   pull,W          ; wreg = ++push % buffersize      |03
    39.         movwf   push            ; update 'push' pointer           |03
    40.         retfie                  ;                                 |??
    41. ;
    42. ;  handle 'overrun' and 'framing' errors  ????
    43. ;
    44. OERR_error
    45. FERR_error
    46.         bcf     RCSTA,SPEN      ; reset receiver                  |03
    47.         movf    RCREG,W         ; clear RCReg                     |03
    48.         movf    RCREG,W         ;                                 |03
    49.         bsf     RCSTA,SPEN      ; enable receiver                 |03
    50.         retfie                  ;                                 |??
    51.  
    52. ;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    53.  
     
    Last edited: Jun 13, 2018
  2. JohnInTX

    Moderator

    Jun 26, 2012
    3,363
    1,685
    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!
     
    MMcLaren likes this.
  3. MMcLaren

    Thread Starter Distinguished Member

    Feb 14, 2010
    837
    158
    Thank you for a thoughtful insightful response, John. That helps a lot...

    Cheerful regards, Mike
     
    JohnInTX likes this.
  4. nsaspook

    AAC Fanatic!

    Aug 27, 2009
    4,820
    5,215
    MMcLaren and JohnInTX like this.
Loading...