summaryrefslogtreecommitdiff
path: root/nuttx/arch/c5471/src
diff options
context:
space:
mode:
Diffstat (limited to 'nuttx/arch/c5471/src')
-rw-r--r--nuttx/arch/c5471/src/up_blocktask.c2
-rw-r--r--nuttx/arch/c5471/src/up_doirq.c16
-rw-r--r--nuttx/arch/c5471/src/up_serial.c51
3 files changed, 62 insertions, 7 deletions
diff --git a/nuttx/arch/c5471/src/up_blocktask.c b/nuttx/arch/c5471/src/up_blocktask.c
index 6b42d4270..5e0693e2e 100644
--- a/nuttx/arch/c5471/src/up_blocktask.c
+++ b/nuttx/arch/c5471/src/up_blocktask.c
@@ -95,8 +95,6 @@ void up_block_task(_TCB *tcb, tstate_t task_state)
_TCB *rtcb = (_TCB*)g_readytorun.head;
boolean switch_needed;
- dbg("Blocking TCB=%p\n", tcb);
-
/* Remove the tcb task from the ready-to-run list. If we
* are blocking the task at the head of the task list (the
* most likely case), then a context switch to the next
diff --git a/nuttx/arch/c5471/src/up_doirq.c b/nuttx/arch/c5471/src/up_doirq.c
index f4e07873c..ab1b40d65 100644
--- a/nuttx/arch/c5471/src/up_doirq.c
+++ b/nuttx/arch/c5471/src/up_doirq.c
@@ -74,6 +74,13 @@ void up_doirq(int irq, uint32* regs)
#else
if ((unsigned)irq < NR_IRQS)
{
+ /* Current regs non-zero indicates that we are processing
+ * an interrupt; current_regs is also used to manage
+ * interrupt level context switches.
+ */
+
+ current_regs = regs;
+
/* Mask and acknowledge the interrupt */
up_maskack_irq(irq);
@@ -82,8 +89,15 @@ void up_doirq(int irq, uint32* regs)
irq_dispatch(irq, regs);
- /* Then unmask it */
+ /* Indicate that we are no long in an interrupt handler */
+
+ current_regs = NULL;
+
+ /* Unmask the last interrupt (global interrupts are still
+ * disabled.
+ */
+ current_regs = NULL;
up_enable_irq(irq);
}
up_ledoff(LED_INIRQ);
diff --git a/nuttx/arch/c5471/src/up_serial.c b/nuttx/arch/c5471/src/up_serial.c
index c6d6dc58e..022befd38 100644
--- a/nuttx/arch/c5471/src/up_serial.c
+++ b/nuttx/arch/c5471/src/up_serial.c
@@ -521,7 +521,7 @@ static inline void up_givesem(sem_t *sem)
* characters from the tail of the buffer.
*/
-static inline void up_recvchars(up_dev_t *dev)
+static void up_recvchars(up_dev_t *dev)
{
uint16 status;
int nexthead = dev->recv.head + 1;
@@ -801,6 +801,32 @@ static void shutdown(up_dev_t * dev)
}
/************************************************************
+ * Name: up_irqwrite
+ ************************************************************/
+
+static ssize_t up_irqwrite(up_dev_t *dev, const char *buffer, size_t buflen)
+{
+ ssize_t ret = buflen;
+
+ /* Force each character through the low level interface */
+
+ for (; buflen; buflen--)
+ {
+ int ch = *buffer++;
+ up_lowputc(ch);
+
+ /* If this is the console, then we should replace LF with LF-CR */
+
+ if (ch == '\n')
+ {
+ up_lowputc('\r');
+ }
+ }
+
+ return ret;
+}
+
+/************************************************************
* Name: up_write
************************************************************/
@@ -810,6 +836,23 @@ static ssize_t up_write(struct file *filep, const char *buffer, size_t buflen)
up_dev_t *dev = inode->i_private;
ssize_t ret = buflen;
+ /* We may receive console writes through this path from
+ * interrupt handlers! In this case, we will need to do
+ * things a little differently.
+ */
+
+ if (up_interrupt_context())
+ {
+ if (dev->isconsole)
+ {
+ return up_irqwrite(dev, buffer, buflen);
+ }
+ else
+ {
+ return ERROR;
+ }
+ }
+
/* Only one user can be accessing dev->xmit.head at once */
up_takesem(&dev->xmit.sem);
@@ -827,10 +870,10 @@ static ssize_t up_write(struct file *filep, const char *buffer, size_t buflen)
/* Put the character into the transmit buffer */
up_putxmitchar(dev, ch);
-
+
/* If this is the console, then we should replace LF with LF-CR */
- if (ch == '\n')
+ if (dev->isconsole && ch == '\n')
{
up_putxmitchar(dev, '\r');
}
@@ -895,7 +938,7 @@ static ssize_t up_read(struct file *filep, char *buffer, size_t buflen)
}
up_enablerxint(dev);
- up_takesem(&dev->recv.sem);
+ up_givesem(&dev->recv.sem);
return ret;
}