backport a serial console fix from the sam4e to the sama5d3
This commit is contained in:
parent
9b5e800cc0
commit
9a724d8b36
@ -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 */
|
||||
|
||||
|
@ -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
|
||||
}
|
||||
|
||||
|
||||
|
@ -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 */
|
||||
|
Loading…
Reference in New Issue
Block a user