SAM3/4 Serial: Fix a mysterious multi-tasking bug that can lock up the serial port

This commit is contained in:
Gregory Nutt 2014-03-25 12:44:03 -06:00
parent 3c3506bd13
commit 93380d8156
2 changed files with 47 additions and 62 deletions

View File

@ -279,16 +279,59 @@
void up_lowputc(char ch)
{
#ifdef HAVE_CONSOLE
/* Wait for the transmitter to be available */
irqstate_t flags;
while ((getreg32(SAM_CONSOLE_BASE + SAM_UART_SR_OFFSET) & UART_INT_TXEMPTY) == 0);
for (;;)
{
/* Wait for the transmitter to be available */
/* Send the character */
while ((getreg32(SAM_CONSOLE_BASE + SAM_UART_SR_OFFSET) & UART_INT_TXEMPTY) == 0);
putreg32((uint32_t)ch, SAM_CONSOLE_BASE + SAM_UART_THR_OFFSET);
/* 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)
{
/* Send the character */
putreg32((uint32_t)ch, SAM_CONSOLE_BASE + 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;
}
/**************************************************************************
* Name: sam_lowsetup
*

View File

@ -1219,62 +1219,4 @@ void up_serialinit(void)
#endif
}
/****************************************************************************
* Name: up_putc
*
* Description:
* Provide priority, low-level access to support OS debug writes
*
****************************************************************************/
int up_putc(int ch)
{
#ifdef HAVE_CONSOLE
struct up_dev_s *priv = (struct up_dev_s*)CONSOLE_DEV.priv;
uint32_t imr;
up_disableallints(priv, &imr);
/* Check for LF */
if (ch == '\n')
{
/* Add CR */
up_lowputc('\r');
}
up_lowputc(ch);
up_restoreusartint(priv, imr);
#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 */