Commit e5872c90 authored by Jeffrey Lee's avatar Jeffrey Lee

Fix UART error IRQs not being cleared

Detail:
  s/UART - Update HAL_UARTReceiveByte to clear error IRQs when the FIFO is believed to be empty. Disable IRQs in some complex routines to prevent any re-entrancy issues, and also clear the RX threshold IRQ when flushing the FIFOs or adjusting the threshold level.
Admin:
  Tested on Raspberry Pi 1
  Resolves ticket #429


Version 0.63. Tagged as 'BCM2835-0_63'
parent 9115b479
/* (0.62)
/* (0.63)
*
* This file is automatically maintained by srccommit, do not edit manually.
* Last processed by srccommit version: 1.1.
*
*/
#define Module_MajorVersion_CMHG 0.62
#define Module_MajorVersion_CMHG 0.63
#define Module_MinorVersion_CMHG
#define Module_Date_CMHG 22 Oct 2016
#define Module_Date_CMHG 25 Oct 2016
#define Module_MajorVersion "0.62"
#define Module_Version 62
#define Module_MajorVersion "0.63"
#define Module_Version 63
#define Module_MinorVersion ""
#define Module_Date "22 Oct 2016"
#define Module_Date "25 Oct 2016"
#define Module_ApplicationDate "22-Oct-16"
#define Module_ApplicationDate "25-Oct-16"
#define Module_ComponentName "BCM2835"
#define Module_ComponentPath "mixed/RiscOS/Sources/HAL/BCM2835"
#define Module_FullVersion "0.62"
#define Module_HelpVersion "0.62 (22 Oct 2016)"
#define Module_LibraryVersionInfo "0:62"
#define Module_FullVersion "0.63"
#define Module_HelpVersion "0.63 (25 Oct 2016)"
#define Module_LibraryVersionInfo "0:63"
......@@ -186,11 +186,23 @@ HAL_UARTReceiveByte ROUT
MOVNE ip, #0
LDREQ ip, [a1, #UARTDR]
DataSyncBarrier lr ; resync after reading peripheral
; If the FIFO is empty, clear all the line status error IRQs. This is
; the only time we can be reasonably certain that there aren't any
; further bad bytes in the FIFO.
;
; There is a race condition here where a new bad byte could arrive just
; before we clear the errors, but as long as the OS has the RX threshold
; & RX timeout IRQs active there shouldn't be any danger of the bad data
; being missed, just delayed a bit.
MOVNE lr, #(1:SHL:UI_OE)+(1:SHL:UI_BE)+(1:SHL:UI_PE)+(1:SHL:UI_FE)
STRNE lr, [a1, #UARTICR]
TEQ a2, #0
BEQ %FT90
; Status wanted, so clear error bits from UARTLineStatus
TST ip, #&F00
STRNE ip, [a1, #UARTRSRECR]
TST ip, #(1:SHL:DR_OE)+(1:SHL:DR_BE)+(1:SHL:DR_PE)+(1:SHL:DR_FE)
STRNE ip, [a1, #UARTRSRECR] ; n.b. written value doesn't matter
BL calcstatus
STR a1, [a2]
90
......@@ -262,7 +274,8 @@ HAL_UARTLineStatus
LDR ip, [a1, #UARTRSRECR]
DataSyncBarrier a2 ; resync after reading/before write
MOVS ip, ip, LSL #DR_FE-RSR_FE ; Convert RSRECR to fake DR
STRNE ip, [a1, #UARTRSRECR] ; Clear any errors
AND a4, a3, #1:SHL:FLAG_RXFE
STRNE ip, [a1, #UARTRSRECR] ; Clear any errors, written value doesn't matter
B calcstatus ; Exit via calcstatus
; int HAL_UARTInterruptEnable(int port, int eor, int mask)
......@@ -277,7 +290,9 @@ HAL_UARTLineStatus
; Returns previous state.
;
HAL_UARTInterruptEnable
Entry
BaseAddr
PHPSEI
LDR a4, [a1, #UARTIMSC]
DataSyncBarrier ip ; resync after reading/before write
; Remap IMSC to match the API
......@@ -310,9 +325,10 @@ HAL_UARTInterruptEnable
]
TEQ a2, a4
STRNE a2, [a1, #UARTIMSC]
PLP
DataSyncBarrier a2
MOV a1, ip
MOV pc, lr
EXIT
; int HAL_UARTRate(int port, int baud16)
......@@ -321,9 +337,10 @@ HAL_UARTInterruptEnable
; Use -1 to read.
;
HAL_UARTRate ROUT
Entry
Entry "v1"
BaseAddr
DataSyncBarrier a3
PHPSEI v1
; Get current baud
LDR a3, [a1, #UARTIBRD]
LDR a4, [a1, #UARTFBRD]
......@@ -346,6 +363,7 @@ HAL_UARTRate ROUT
STR a3, [a1, #UARTLCRH]
StartUART a3
90
PLP v1
DataSyncBarrier a3
MOV a1, ip
EXIT
......@@ -364,8 +382,10 @@ HAL_UARTRate ROUT
;
HAL_UARTFormat ROUT
Entry
BaseAddr
DataSyncBarrier a3
PHPSEI
; Get current settings
LDR a3, [a1, #UARTLCRH]
AND a4, a3, #LCRH_WLEN
......@@ -396,9 +416,10 @@ HAL_UARTFormat ROUT
STR a3, [a1, #UARTLCRH]
StartUART a3
90
PLP
DataSyncBarrier a3
MOV a1, a4
MOV pc, lr
EXIT
; void HAL_UARTFIFOSize(int port, int *rx, int *tx)
;
......@@ -425,12 +446,16 @@ HAL_UARTFIFOClear
BaseAddr
; We can't individually flush FIFOs, so just flush both of them
DataSyncBarrier a2
PHPSEI ip
StopUART a2
LDR a2, [a1, #UARTLCRH]
BIC a3, a2, #LCRH_FEN
STR a3, [a1, #UARTLCRH] ; Disabling the FIFOs should flush them
MOV a3, #1:SHL:UI_RX
STR a3, [a1, #UARTICR] ; Clear RX threshold IRQ as well, otherwise it may get stuck on
STR a2, [a1, #UARTLCRH] ; Restore original state
StartUART a3
PLP ip
DataSyncBarrier a2
MOV pc, lr
......@@ -442,6 +467,7 @@ HAL_UARTFIFOClear
HAL_UARTFIFOEnable ROUT
BaseAddr
DataSyncBarrier a3
PHPSEI ip
LDR a3, [a1, #UARTLCRH]
CMP a2, #0
BLT %FT90
......@@ -451,6 +477,7 @@ HAL_UARTFIFOEnable ROUT
STR a4, [a1, #UARTLCRH]
StartUART a2
90
PLP ip
DataSyncBarrier a2
AND a1, a3, #LCRH_FEN
ASSERT LCRH_FEN = 1:SHL:4
......@@ -459,13 +486,13 @@ HAL_UARTFIFOEnable ROUT
; int HAL_UARTFIFOThreshold(int port, int threshold)
;
; Sets the receive threshold level for the FIFO RX interrupt. For OMAP3530
; this is 8, 16, 56 or 60 bytes. Returns previous value. -1 to read.
; Sets the receive threshold level for the FIFO RX interrupt. -1 to read.
;
HAL_UARTFIFOThreshold ROUT
Entry
Entry "v1"
BaseAddr
DataSyncBarrier a3
PHPSEI v1
; Calc current level
LDR a3, [a1, #UARTIFLS]
AND a4, a3, #7:SHL:3
......@@ -484,7 +511,10 @@ HAL_UARTFIFOThreshold ROUT
BNE %BT10
20
STR a3, [a1, #UARTIFLS]
MOV a3, #1:SHL:UI_RX
STR a3, [a1, #UARTICR] ; Clear RX threshold IRQ as well, otherwise it may get stuck on (n.b. if FIFO is currently non-empty we'll assume the RX timeout IRQ will take care of it)
90
PLP v1
DataSyncBarrier a2
MOV a1, a4
EXIT
......@@ -552,6 +582,7 @@ HAL_UARTInterruptID ROUT
HAL_UARTBreak ROUT
BaseAddr
DataSyncBarrier a3
PHPSEI ip
LDR a3, [a1, #UARTLCRH]
AND a4, a3, #LCRH_BRK
CMP a2, #0
......@@ -562,6 +593,7 @@ HAL_UARTBreak ROUT
STR a3, [a1, #UARTLCRH]
StartUART a2
90
PLP ip
DataSyncBarrier a2
ASSERT LCRH_BRK = 1
MOV a1, a4
......@@ -581,8 +613,10 @@ HAL_UARTBreak ROUT
HAL_UARTModemControl
[ ModemControl
Entry
BaseAddr
DataSyncBarrier a4
PHPSEI
LDR a4, [a1, #UARTCR]
; Map to API format
AND ip, a4, #CR_RTS
......@@ -601,10 +635,13 @@ HAL_UARTModemControl
ORRNE a2, a2, #CR_CTSEN+CR_RTSEN
TEQ a2, a4
STRNE a2, [a1, #UARTCR]
PLP
DataSyncBarrier a2
MOV a1, ip
]
EXIT
|
MOV pc, lr
]
; int HAL_UARTModemStatus(int port)
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment