Skip to content

Commit e4a5b14

Browse files
committed
Fix UART receiver corruption
When the UART receiver is disconnected for a time shorter than a line break and longer than a start bit, it interpret that as a received packet, and if data are transmitted immediatly after, they are corrupted. This commit is a workarround for that bug, that enable the loopback feature of the UART when UART is disconnected, so the UART module does not notice it is disconnected. A previous workarround for this bug (a forced delay after disconnection) is not needed anymore and is removed.
1 parent 7366ed0 commit e4a5b14

File tree

3 files changed

+42
-3
lines changed

3 files changed

+42
-3
lines changed

cores/arduino/UARTClass.cpp

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,6 @@
2525
#include "wiring_constants.h"
2626
#include "wiring_digital.h"
2727

28-
#define SETTLING_TIME 400
29-
3028
extern void UART_Handler(void);
3129
extern void serialEventRun(void) __attribute__((weak));
3230
extern void serialEvent(void) __attribute__((weak));
@@ -114,10 +112,13 @@ void UARTClass::end( void )
114112
opened = false;
115113
// Clear any received data
116114
_rx_buffer->_iHead = _rx_buffer->_iTail;
115+
116+
//enable loopback, needed to prevent a short disconnection to be
117+
//interpreted as a packet and corrupt receiver state
118+
uart_loop_enable(CONFIG_UART_CONSOLE_INDEX);
117119

118120
SET_PIN_MODE(17, GPIO_MUX_MODE); // Rdx SOC PIN (Arduino header pin 0)
119121
SET_PIN_MODE(16, GPIO_MUX_MODE); // Txd SOC PIN (Arduino header pin 1)
120-
delayMicroseconds(SETTLING_TIME); // wait for lines to settle
121122
}
122123

123124
void UARTClass::setInterruptPriority(uint32_t priority)

system/libarc32_arduino101/drivers/ns16550.c

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -639,3 +639,39 @@ uint8_t uart_tx_complete(int which)
639639
{
640640
return INBYTE(LSR(which)) & LSR_TEMT;
641641
}
642+
643+
/*******************************************************************************
644+
*
645+
* uart_loop_enable - enable loopback
646+
*
647+
* This function enable the local loopback.
648+
* When enabled, the output of the Transmitter Shift
649+
* Register is looped back into the Receiver Shift Register input,
650+
* and any data that is transmitted is immediately received.
651+
*
652+
* RETURNS: N/A
653+
*/
654+
655+
void uart_loop_enable(int which)
656+
{
657+
uint8_t mdc = INBYTE(MDC(which));
658+
mdc |= MCR_LOOP;
659+
OUTBYTE(MDC(which), mdc);
660+
}
661+
662+
/*******************************************************************************
663+
*
664+
* uart_loop_disable - disable loopback
665+
*
666+
* This function disable the local loopback.
667+
*
668+
* RETURNS: N/A
669+
*/
670+
671+
void uart_loop_disable(int which)
672+
{
673+
uint8_t mdc = INBYTE(MDC(which));
674+
mdc &= ~MCR_LOOP;
675+
OUTBYTE(MDC(which), mdc);
676+
}
677+

system/libarc32_arduino101/drivers/uart.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,8 @@ int uart_break_check(int port);
9292
void uart_break_send(int port, int delay);
9393
void uart_disable(int port);
9494
uint8_t uart_tx_complete(int which);
95+
void uart_loop_enable(int which);
96+
void uart_loop_disable(int which);
9597

9698
#ifdef __cplusplus
9799
}

0 commit comments

Comments
 (0)