summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGerardo Puga <glpuga@gmail.com>2010-06-10 08:10:00 -0500
committerGedare Bloom <gedare@rtems.org>2014-01-09 09:44:14 -0500
commit78c84df00c4dacc3e2660959ca1ee6527fc4dfb6 (patch)
tree64ff0921a04084a90a09be5d37be546db1eee01f
parentlibcsupport: Refactor rtems_deviceio_errno (diff)
downloadrtems-78c84df00c4dacc3e2660959ca1ee6527fc4dfb6.tar.bz2
PR 1548: ERC32 console stops working when UART error flags are set
Problem: The console works fine when only transmitting data from the ERC32, but stops working after a while when receiving data. "Stops working" means, bytes are neither sent nor received from the UART, but the rest of the system keeps functioning (task are executing, the operative system is responsive, etc). Context: - When an RX error occurs, the ERC32 UARTS stop generating RX/TX interrupts until the corresponding error flag in the UART_STATUS are cleared. - The console.c code currently cleans the error flags from the console_isr_x subroutines, but those are NOT called when an RX error occurs. Thus the error flag is never cleaned and then the UARTs stop generating interrupts indefinitely. - The ERC32 UARTs generate a different interrupt when an RX error occurs. Fixed by: - Adding a third interrupt service routine console_isr_error to handle the UART_ERROR trap. This isr cleans the error flags of the channels. - Cleaning the error flags manually just after having initialized the interrupt vectors. This is because if the error flag was already set by the time the interrupt vectors are configured, the interrupts might never be called.
-rw-r--r--c/src/lib/libbsp/sparc/erc32/console/erc32_console.c26
1 files changed, 26 insertions, 0 deletions
diff --git a/c/src/lib/libbsp/sparc/erc32/console/erc32_console.c b/c/src/lib/libbsp/sparc/erc32/console/erc32_console.c
index 2acc72f156..8747e3e87b 100644
--- a/c/src/lib/libbsp/sparc/erc32/console/erc32_console.c
+++ b/c/src/lib/libbsp/sparc/erc32/console/erc32_console.c
@@ -174,6 +174,27 @@ static ssize_t erc32_console_write_support_int(int minor, const char *buf, size_
return 0;
}
+static void erc32_console_isr_error(
+ rtems_vector_number vector
+)
+{
+ int UStat;
+
+ UStat = ERC32_MEC.UART_Status;
+
+ if (UStat & ERC32_MEC_UART_STATUS_ERRA) {
+ ERC32_MEC.UART_Status = ERC32_MEC_UART_STATUS_CLRA;
+ ERC32_MEC.Control = ERC32_MEC.Control;
+ }
+
+ if (UStat & ERC32_MEC_UART_STATUS_ERRB) {
+ ERC32_MEC.UART_Status = ERC32_MEC_UART_STATUS_CLRB;
+ ERC32_MEC.Control = ERC32_MEC.Control;
+ }
+
+ ERC32_Clear_interrupt( ERC32_INTERRUPT_UART_ERROR );
+}
+
static void erc32_console_isr_a(
rtems_vector_number vector
)
@@ -304,5 +325,10 @@ static void erc32_console_initialize(
#if (CONSOLE_USE_INTERRUPTS)
set_vector(erc32_console_isr_a, CONSOLE_UART_A_TRAP, 1);
set_vector(erc32_console_isr_b, CONSOLE_UART_B_TRAP, 1);
+ set_vector(erc32_console_isr_error, CONSOLE_UART_ERROR_TRAP, 1);
#endif
+
+ /* Clear any previous error flags */
+ ERC32_MEC.UART_Status = ERC32_MEC_UART_STATUS_CLRA;
+ ERC32_MEC.UART_Status = ERC32_MEC_UART_STATUS_CLRB;
}