@@ -57,6 +57,31 @@ void HardwareSerial::init(PinName _rx, PinName _tx, PinName _rts, PinName _cts)
5757}
5858
5959
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+
6085
6186// Public Methods //////////////////////////////////////////////////////////////
6287void HardwareSerial::begin (unsigned long baud, byte config)
@@ -138,32 +163,133 @@ void HardwareSerial::begin(unsigned long baud, byte config)
138163 break ;
139164 }
140165 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
141176}
142177
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+
143231void HardwareSerial::end ()
144232{
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+
145237 uart_deinit (&_serial);
238+
239+ #if (OPT_USART1_INT==1)
240+ // MMOLE TODO: disable interrupt handler
241+ #endif
146242}
147243
148244int HardwareSerial::available (void )
149245{
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;
151252}
152253
153254int HardwareSerial::peek (void )
154255{
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+ }
156267}
157268
158269int HardwareSerial::read (void )
159270{
160-
161271 unsigned char c;
272+ // MMOLE: reintroduced RX buffer to properly implement read/available/peek methods
273+ /*
162274 if(uart_getc(&_serial, &c) == 0){
163275 return c;
164276 }else{
165277 return -1;
166278 }
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+ }
167293}
168294
169295
@@ -272,7 +398,7 @@ void HardwareSerial::setHandler(void *handler)
272398 #endif
273399
274400 #if defined(HAVE_HWSERIAL6)
275- HardwareSerial Serial6 (UART6 );
401+ HardwareSerial Serial6 (USART6 );
276402 #endif
277403
278404 #if defined(HAVE_HWSERIAL7)
0 commit comments