SAM3/4 Serial: Fix a mysterious multi-tasking bug that can lock up the serial port
This commit is contained in:
parent
3c3506bd13
commit
93380d8156
@ -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
|
||||
*
|
||||
|
@ -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 */
|
||||
|
Loading…
Reference in New Issue
Block a user