@@ -57,6 +57,31 @@ void HardwareSerial::init(PinName _rx, PinName _tx, PinName _rts, PinName _cts)
57
57
}
58
58
59
59
60
+ // Interrupt handler for filling rx buffer /////////////////////////////////////
61
+ #if (OPT_USART1_INT==1)
62
+
63
+ #if defined(USART1)
64
+ #ifdef __cplusplus
65
+ extern " C" {
66
+ #endif
67
+ void USART1_IRQHandler (void ) __attribute__((interrupt(" WCH-Interrupt-fast" )));
68
+ void USART1_IRQHandler (void ) {
69
+ USART_ClearITPendingBit (USART1, USART_IT_RXNE);
70
+ // Use the proper serial object to fill the RX buffer. Perhaps we should use uart_handlers[] as defined in uart.c
71
+ // Serial is most often Serial1, initialized below as HardwareSerial Serial1(USART1); DEBUG_UART may give issues.
72
+ // TODO? get_serial_obj(uart_handlers[UART1_INDEX]);
73
+ HardwareSerial *obj=&Serial1;
74
+ obj->_rx_buffer [obj->_rx_buffer_head ] = USART_ReceiveData (USART1); // maybe we should use uart_getc()?
75
+ obj->_rx_buffer_head ++;
76
+ obj->_rx_buffer_head %= SERIAL_RX_BUFFER_SIZE;
77
+ }
78
+ #ifdef __cplusplus
79
+ }
80
+ #endif
81
+ #endif
82
+
83
+ #endif
84
+
60
85
61
86
// Public Methods //////////////////////////////////////////////////////////////
62
87
void HardwareSerial::begin (unsigned long baud, byte config)
@@ -138,32 +163,133 @@ void HardwareSerial::begin(unsigned long baud, byte config)
138
163
break ;
139
164
}
140
165
uart_init (&_serial, (uint32_t )baud, databits, parity, stopbits);
166
+
167
+ #if (OPT_USART1_INT==1)
168
+ // MMOLE 240619: Enable interrupt handler for filling rx buffer
169
+ #if defined(USART1)
170
+ USART_ITConfig (USART1, USART_IT_RXNE, ENABLE);
171
+ NVIC_SetPriority (USART1_IRQn, UART_IRQ_PRIO);
172
+ NVIC_EnableIRQ (USART1_IRQn);
173
+ #endif
174
+ // MMOLE TODO: I only have CH32V003; only tested USART1, how about others?
175
+ #endif
141
176
}
142
177
178
+
179
+ #if (OPT_USART1_INT==1)
180
+ #else
181
+ // MMOLE: reintroduced RX buffer to properly implement read/available/peek methods
182
+ void HardwareSerial::fillRxBuffer (void ) // private method: read all characters that can be read
183
+ {
184
+ // Fill RX buffer during read/available calls
185
+ // Newly received characters are added to the buffer
186
+ // _rx_buffer_head is the location of the new character
187
+ // _rx_buffer_tail is the location of the oldest character that is not read yet
188
+ unsigned char c;
189
+ /*
190
+ while(uart_getc(&_serial, &c) == 0)
191
+ {
192
+ _rx_buffer[_rx_buffer_head]=c;
193
+ _rx_buffer_head = (rx_buffer_index_t)(_rx_buffer_head + 1) % SERIAL_RX_BUFFER_SIZE;
194
+ }
195
+ */
196
+ // To avoid buffer underruns, we try to read during at least a few millis.
197
+ // Perhaps there is a better way, but for now it works.
198
+ // Maybe we should also do something to handle disruption of interrupts
199
+ /*
200
+ #define SERIAL_WAIT_FOR_RX 5000L
201
+ uint32_t uStart=micros();
202
+ while((micros()-uStart)<SERIAL_WAIT_FOR_RX)
203
+ */
204
+ #define SERIAL_WAIT_FOR_RX 3
205
+ uint32_t uStart=millis ();
206
+ while ((millis ()-uStart)<SERIAL_WAIT_FOR_RX)
207
+ {
208
+ if (uart_getc (&_serial, &c) == 0 )
209
+ {
210
+ /*
211
+ _rx_buffer[_rx_buffer_head]=c;
212
+ _rx_buffer_head = (rx_buffer_index_t)(_rx_buffer_head + 1) % SERIAL_RX_BUFFER_SIZE;
213
+ /**/
214
+ rx_buffer_index_t i = (unsigned int )(_rx_buffer_head + 1 ) % SERIAL_RX_BUFFER_SIZE;
215
+
216
+ // if we should be storing the received character into the location
217
+ // just before the tail (meaning that the head would advance to the
218
+ // current location of the tail), we're about to overflow the buffer
219
+ // and so we don't write the character or advance the head.
220
+ if (i != _rx_buffer_tail) {
221
+ _rx_buffer[_rx_buffer_head] = c;
222
+ _rx_buffer_head = i;
223
+ }
224
+ /* */
225
+ }
226
+ }
227
+ }
228
+ #endif
229
+
230
+
143
231
void HardwareSerial::end ()
144
232
{
233
+ // MMOLE: reintroduced RX buffer to properly implement read/available/peek methods
234
+ // clear any received data
235
+ _rx_buffer_head = _rx_buffer_tail;
236
+
145
237
uart_deinit (&_serial);
238
+
239
+ #if (OPT_USART1_INT==1)
240
+ // MMOLE TODO: disable interrupt handler
241
+ #endif
146
242
}
147
243
148
244
int HardwareSerial::available (void )
149
245
{
150
- return -1 ;
246
+ // MMOLE: reintroduced RX buffer to properly implement read/available/peek methods
247
+ // return -1;
248
+ #if (OPT_USART1_INT==0)
249
+ fillRxBuffer (); // use polling to fill the RX buffer
250
+ #endif
251
+ return ((unsigned int )(SERIAL_RX_BUFFER_SIZE + _rx_buffer_head - _rx_buffer_tail)) % SERIAL_RX_BUFFER_SIZE;
151
252
}
152
253
153
254
int HardwareSerial::peek (void )
154
255
{
155
- return -1 ;
256
+ // MMOLE: reintroduced RX buffer to properly implement read/available/peek methods
257
+ // MMOLE 240316: Serial.parseInt() uses peek() with timeout to see if more data is available
258
+ // return -1;
259
+ #if (OPT_USART1_INT==0)
260
+ fillRxBuffer (); // use polling to fill the RX buffer
261
+ #endif
262
+ if (_rx_buffer_head == _rx_buffer_tail) {
263
+ return -1 ;
264
+ } else {
265
+ return _rx_buffer[_rx_buffer_tail];
266
+ }
156
267
}
157
268
158
269
int HardwareSerial::read (void )
159
270
{
160
-
161
271
unsigned char c;
272
+ // MMOLE: reintroduced RX buffer to properly implement read/available/peek methods
273
+ /*
162
274
if(uart_getc(&_serial, &c) == 0){
163
275
return c;
164
276
}else{
165
277
return -1;
166
278
}
279
+ */
280
+ #if (OPT_USART1_INT==0)
281
+ // Fill RX buffer during read/available calls
282
+ fillRxBuffer (); // use polling to fill the RX buffer
283
+ #endif
284
+
285
+ // if the head isn't ahead of the tail, we don't have any characters
286
+ if (_rx_buffer_head == _rx_buffer_tail) {
287
+ return -1 ;
288
+ } else {
289
+ unsigned char c = _rx_buffer[_rx_buffer_tail];
290
+ _rx_buffer_tail = (rx_buffer_index_t )(_rx_buffer_tail + 1 ) % SERIAL_RX_BUFFER_SIZE;
291
+ return c;
292
+ }
167
293
}
168
294
169
295
@@ -272,7 +398,7 @@ void HardwareSerial::setHandler(void *handler)
272
398
#endif
273
399
274
400
#if defined(HAVE_HWSERIAL6)
275
- HardwareSerial Serial6 (UART6 );
401
+ HardwareSerial Serial6 (USART6 );
276
402
#endif
277
403
278
404
#if defined(HAVE_HWSERIAL7)
0 commit comments