@@ -91,6 +91,31 @@ size_t uart_resize_rx_buffer(uart_t* uart, size_t new_size)
91
91
return uart -> rx_buffer -> size ;
92
92
}
93
93
94
+ inline size_t uart_rx_buffer_available (uart_t * uart ) {
95
+ if (uart -> rx_buffer -> wpos < uart -> rx_buffer -> rpos ) {
96
+ return (uart -> rx_buffer -> wpos + uart -> rx_buffer -> size ) - uart -> rx_buffer -> rpos ;
97
+ }
98
+ return uart -> rx_buffer -> wpos - uart -> rx_buffer -> rpos ;
99
+ }
100
+
101
+ inline size_t uart_rx_fifo_available (uart_t * uart ) {
102
+ return (USS (uart -> uart_nr ) >> USRXC ) & 0x7F ;
103
+ }
104
+
105
+ // Copy all the rx fifo bytes that fit into the rx buffer
106
+ inline void uart_rx_copy_fifo_to_buffer (uart_t * uart ) {
107
+ while (uart_rx_fifo_available (uart )){
108
+ size_t nextPos = (uart -> rx_buffer -> wpos + 1 ) % uart -> rx_buffer -> size ;
109
+ if (nextPos == uart -> rx_buffer -> rpos ) {
110
+ // Stop copying if rx buffer is full
111
+ break ;
112
+ }
113
+ uint8_t data = USF (uart -> uart_nr );
114
+ uart -> rx_buffer -> buffer [uart -> rx_buffer -> wpos ] = data ;
115
+ uart -> rx_buffer -> wpos = nextPos ;
116
+ }
117
+ }
118
+
94
119
int uart_peek_char (uart_t * uart )
95
120
{
96
121
if (uart == NULL || !uart -> rx_enabled ) {
@@ -99,6 +124,11 @@ int uart_peek_char(uart_t* uart)
99
124
if (!uart_rx_available (uart )) {
100
125
return -1 ;
101
126
}
127
+ if (uart_rx_buffer_available (uart ) == 0 ) {
128
+ ETS_UART_INTR_DISABLE ();
129
+ uart_rx_copy_fifo_to_buffer (uart );
130
+ ETS_UART_INTR_ENABLE ();
131
+ }
102
132
return uart -> rx_buffer -> buffer [uart -> rx_buffer -> rpos ];
103
133
}
104
134
@@ -119,10 +149,7 @@ size_t uart_rx_available(uart_t* uart)
119
149
if (uart == NULL || !uart -> rx_enabled ) {
120
150
return 0 ;
121
151
}
122
- if (uart -> rx_buffer -> wpos < uart -> rx_buffer -> rpos ) {
123
- return (uart -> rx_buffer -> wpos + uart -> rx_buffer -> size ) - uart -> rx_buffer -> rpos ;
124
- }
125
- return uart -> rx_buffer -> wpos - uart -> rx_buffer -> rpos ;
152
+ return uart_rx_buffer_available (uart ) + uart_rx_fifo_available (uart );
126
153
}
127
154
128
155
@@ -135,14 +162,7 @@ void ICACHE_RAM_ATTR uart_isr(void * arg)
135
162
return ;
136
163
}
137
164
if (USIS (uart -> uart_nr ) & ((1 << UIFF ) | (1 << UITO ))){
138
- while ((USS (uart -> uart_nr ) >> USRXC ) & 0x7F ){
139
- uint8_t data = USF (uart -> uart_nr );
140
- size_t nextPos = (uart -> rx_buffer -> wpos + 1 ) % uart -> rx_buffer -> size ;
141
- if (nextPos != uart -> rx_buffer -> rpos ) {
142
- uart -> rx_buffer -> buffer [uart -> rx_buffer -> wpos ] = data ;
143
- uart -> rx_buffer -> wpos = nextPos ;
144
- }
145
- }
165
+ uart_rx_copy_fifo_to_buffer (uart );
146
166
}
147
167
USIC (uart -> uart_nr ) = USIS (uart -> uart_nr );
148
168
}
@@ -152,7 +172,11 @@ void uart_start_isr(uart_t* uart)
152
172
if (uart == NULL || !uart -> rx_enabled ) {
153
173
return ;
154
174
}
155
- USC1 (uart -> uart_nr ) = (127 << UCFFT ) | (0x02 << UCTOT ) | (1 <<UCTOE );
175
+ // UCFFT value is when the RX fifo full interrupt triggers. A value of 1
176
+ // triggers the IRS very often. A value of 127 would not leave much time
177
+ // for ISR to clear fifo before the next byte is dropped. So pick a value
178
+ // in the middle.
179
+ USC1 (uart -> uart_nr ) = (100 << UCFFT ) | (0x02 << UCTOT ) | (1 <<UCTOE );
156
180
USIC (uart -> uart_nr ) = 0xffff ;
157
181
USIE (uart -> uart_nr ) = (1 << UIFF ) | (1 << UIFR ) | (1 << UITO );
158
182
ETS_UART_INTR_ATTACH (uart_isr , (void * )uart );
0 commit comments