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)
|
void up_lowputc(char ch)
|
||||||
{
|
{
|
||||||
#ifdef HAVE_CONSOLE
|
#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
|
#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
|
* Name: sam_lowsetup
|
||||||
*
|
*
|
||||||
|
@ -1219,62 +1219,4 @@ void up_serialinit(void)
|
|||||||
#endif
|
#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 */
|
#endif /* USE_SERIALDRIVER */
|
||||||
|
Loading…
Reference in New Issue
Block a user