aboutsummaryrefslogtreecommitdiffstats
path: root/ports/ARM7-LPC214x
diff options
context:
space:
mode:
authorgdisirio <gdisirio@35acf78f-673a-0410-8e92-d51de3d6d3f4>2009-01-10 15:20:40 +0000
committergdisirio <gdisirio@35acf78f-673a-0410-8e92-d51de3d6d3f4>2009-01-10 15:20:40 +0000
commit23626829b9463237559b0283bbb5327331b9e280 (patch)
treee35982eb2f61bdaca2e3372177c64770f55ad22d /ports/ARM7-LPC214x
parent2730efd717f3a4bb736f49250769b119fb4cbfa3 (diff)
downloadChibiOS-23626829b9463237559b0283bbb5327331b9e280.tar.gz
ChibiOS-23626829b9463237559b0283bbb5327331b9e280.tar.bz2
ChibiOS-23626829b9463237559b0283bbb5327331b9e280.zip
git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@610 35acf78f-673a-0410-8e92-d51de3d6d3f4
Diffstat (limited to 'ports/ARM7-LPC214x')
-rw-r--r--ports/ARM7-LPC214x/lpc214x_serial.c35
1 files changed, 25 insertions, 10 deletions
diff --git a/ports/ARM7-LPC214x/lpc214x_serial.c b/ports/ARM7-LPC214x/lpc214x_serial.c
index 88a142ed0..38eae3169 100644
--- a/ports/ARM7-LPC214x/lpc214x_serial.c
+++ b/ports/ARM7-LPC214x/lpc214x_serial.c
@@ -43,13 +43,16 @@ static void SetError(IOREG32 err, FullDuplexDriver *com) {
sts |= SD_FRAMING_ERROR;
if (err & LSR_BREAK)
sts |= SD_BREAK_DETECTED;
+ chSysLockI();
chFDDAddFlagsI(com, sts);
+ chSysUnlockI();
}
/*
* Tries hard to clear all the pending interrupt sources, we dont want to
* go through the whole ISR and have another interrupt soon after.
*/
+__attribute__((noinline))
static void ServeInterrupt(UART *u, FullDuplexDriver *com) {
while (TRUE) {
@@ -62,26 +65,37 @@ static void ServeInterrupt(UART *u, FullDuplexDriver *com) {
break;
case IIR_SRC_TIMEOUT:
case IIR_SRC_RX:
- while (u->UART_LSR & LSR_RBR_FULL)
+ while (u->UART_LSR & LSR_RBR_FULL) {
+ chSysLockI();
if (chIQPutI(&com->sd_iqueue, u->UART_RBR) < Q_OK)
chFDDAddFlagsI(com, SD_OVERRUN_ERROR);
+ chSysUnlockI();
+ }
+ chSysLockI();
chEvtBroadcastI(&com->sd_ievent);
+ chSysUnlockI();
break;
case IIR_SRC_TX:
{
#ifdef FIFO_PRELOAD
int i = FIFO_PRELOAD;
do {
+ chSysLockI();
msg_t b = chOQGetI(&com->sd_oqueue);
+ chSysUnlockI();
if (b < Q_OK) {
u->UART_IER &= ~IER_THRE;
+ chSysLockI();
chEvtBroadcastI(&com->sd_oevent);
+ chSysUnlockI();
break;
}
u->UART_THR = b;
} while (--i);
#else
+ chSysLockI();
msg_t b = chFDDRequestDataI(com);
+ chSysUnlockI();
if (b < Q_OK)
u->UART_IER &= ~IER_THRE;
else
@@ -95,25 +109,19 @@ static void ServeInterrupt(UART *u, FullDuplexDriver *com) {
}
}
-__attribute__((naked, weak))
-void UART0IrqHandler(void) {
+CH_IRQ_HANDLER void UART0IrqHandler(void) {
chSysIRQEnterI();
-
ServeInterrupt(U0Base, &COM1);
VICVectAddr = 0;
-
chSysIRQExitI();
}
-__attribute__((naked, weak))
-void UART1IrqHandler(void) {
+CH_IRQ_HANDLER void UART1IrqHandler(void) {
chSysIRQEnterI();
-
ServeInterrupt(U1Base, &COM2);
VICVectAddr = 0;
-
chSysIRQExitI();
}
@@ -123,9 +131,13 @@ static void preload(UART *u, FullDuplexDriver *com) {
if (u->UART_LSR & LSR_THRE) {
int i = FIFO_PRELOAD;
do {
+ chSysLockI();
msg_t b = chOQGetI(&com->sd_oqueue);
+ chSysUnlockI();
if (b < Q_OK) {
+ chSysLockI();
chEvtBroadcastI(&com->sd_oevent);
+ chSysUnlockI();
return;
}
u->UART_THR = b;
@@ -146,8 +158,11 @@ static void OutNotify1(void) {
#else
UART *u = U0Base;
- if (u->UART_LSR & LSR_THRE)
+ if (u->UART_LSR & LSR_THRE) {
+ chSysLockI();
u->UART_THR = chOQGetI(&COM1.sd_oqueue);
+ chSysUnlockI();
+ }
u->UART_IER |= IER_THRE;
#endif
}