backport a serial console fix from the sam4e to the sama5d3

This commit is contained in:
Gregory Nutt 2014-03-25 14:34:07 -06:00
parent 9b5e800cc0
commit 9a724d8b36
3 changed files with 54 additions and 94 deletions

View File

@ -285,14 +285,16 @@ void up_lowputc(char ch)
{
/* Wait for the transmitter to be available */
while ((getreg32(SAM_CONSOLE_BASE + SAM_UART_SR_OFFSET) & UART_INT_TXEMPTY) == 0);
while ((getreg32(SAM_CONSOLE_BASE + SAM_UART_SR_OFFSET) &
UART_INT_TXEMPTY) == 0);
/* Disable interrupts so that the test and the transmission are
* atomic.
*/
flags = irqsave();
if ((getreg32(SAM_CONSOLE_BASE + SAM_UART_SR_OFFSET) & UART_INT_TXEMPTY) != 0)
if ((getreg32(SAM_CONSOLE_BASE + SAM_UART_SR_OFFSET) &
UART_INT_TXEMPTY) != 0)
{
/* Send the character */

View File

@ -247,13 +247,59 @@
void up_lowputc(char ch)
{
/* Wait for the transmitter to be available */
#ifdef HAVE_CONSOLE
irqstate_t flags;
while ((getreg32(SAM_CONSOLE_VBASE + SAM_UART_SR_OFFSET) & UART_INT_TXEMPTY) == 0);
for (;;)
{
/* Wait for the transmitter to be available */
/* Send the character */
while (((getreg32(SAM_CONSOLE_VBASE + SAM_UART_SR_OFFSET) &
UART_INT_TXEMPTY) == 0);
putreg32((uint32_t)ch, SAM_CONSOLE_VBASE + SAM_UART_THR_OFFSET);
/* Disable interrupts so that the test and the transmission are
* atomic.
*/
flags = irqsave();
if ((getreg32(SAM_CONSOLE_VBASE + SAM_UART_SR_OFFSET) &
UART_INT_TXEMPTY) != 0)
{
/* Send the character */
putreg32((uint32_t)ch, SAM_CONSOLE_VBASE + SAM_UART_THR_OFFSET);
irqrestore(flags);
return;
}
irqrestore(flags);
}
#endif
}
/****************************************************************************
* Name: up_putc
*
* Description:
* Provide priority, low-level access to support OS debug writes
*
****************************************************************************/
int up_putc(int ch)
{
#ifdef HAVE_CONSOLE
/* Check for LF */
if (ch == '\n')
{
/* Add CR */
up_lowputc('\r');
}
up_lowputc(ch);
#endif
return ch;
}
/**************************************************************************
@ -373,5 +419,3 @@ void sam_lowsetup(void)
SAM_CONSOLE_VBASE + SAM_UART_CR_OFFSET);
#endif
}

View File

@ -1189,90 +1189,4 @@ void up_serialinit(void)
#endif
}
/****************************************************************************
* Name: up_putc
*
* Description:
* Provide priority, low-level access to support OS debug writes. This
* function is intended only to support early boot-up logic and serial
* debug output from interrupt handlers. It is invasive and will effect
* your realtime performance!
*
****************************************************************************/
int up_putc(int ch)
{
#ifdef HAVE_CONSOLE
/* This logic does not work. Apparently re-entrancy problems cause the
* loss of serial interrupts (a bad, zero IMR gets set). My attempts to
* make this function fully re-entrant have not been successful but the
* following brute force approach works just fine.
*/
#if 0
struct up_dev_s *priv = (struct up_dev_s*)CONSOLE_DEV.priv;
uint32_t imr;
/* Disable serial interrupts */
up_disableallints(priv, &imr);
#else
irqstate_t flags;
/* Disable all interrupts */
flags = irqsave();
#endif
/* Check for LF */
if (ch == '\n')
{
/* Add CR */
up_lowputc('\r');
}
up_lowputc(ch);
#if 0 /* See comments above */
/* Restore serial interrupts */
up_restoreusartint(priv, imr);
#else
/* Restore all interrupts */
irqrestore(flags);
#endif
#endif
return ch;
}
#else /* USE_SERIALDRIVER */
/****************************************************************************
* Name: up_putc
*
* Description:
* Provide priority, low-level access to support OS debug writes
*
****************************************************************************/
int up_putc(int ch)
{
#ifdef HAVE_CONSOLE
/* Check for LF */
if (ch == '\n')
{
/* Add CR */
up_lowputc('\r');
}
up_lowputc(ch);
#endif
return ch;
}
#endif /* USE_SERIALDRIVER */