2121 Modified 14 August 2012 by Alarus
2222 Modified 3 December 2013 by Matthijs Kooijman
2323 Modified 1 may 2023 by TempersLee
24- Modified 28 July 2024 by Maxint R&D
24+ Modified 13 October 2023 by Maxint R&D, latest update 6 May 2025
2525*/
2626
27-
2827#include < stdio.h>
2928#include " Arduino.h"
3029#include " HardwareSerial.h"
@@ -36,10 +35,22 @@ HardwareSerial::HardwareSerial(void *peripheral)
3635{
3736 setHandler (peripheral);
3837
38+ #if defined(PIN_SERIAL_RX) && defined(PIN_SERIAL_TX)
39+ // if SERIAL_UART_INSTANCES is defined and has value 1, then PIN_SERIAL_RX and PIN_SERIAL_TX are rx/tx pins of the selected SERIAL_UART_INSTANCE
3940 setRx (PIN_SERIAL_RX);
40-
4141 setTx (PIN_SERIAL_TX);
42-
42+ #endif
43+
44+ #if defined(USART2) && defined(PIN_SERIAL_RX2) && defined(PIN_SERIAL_TX2)
45+ // if SERIAL_UART_INSTANCES is defined and is 2 or higher, multiple instances can be used simultaneously
46+ // TODO: get pin number from pinmap PinMap_UART_TX and PinMap_UART_RX
47+ if (peripheral==USART2)
48+ {
49+ setRx (PIN_SERIAL_RX2);
50+ setTx (PIN_SERIAL_TX2);
51+ }
52+ #endif
53+
4354 init (_serial.pin_rx , _serial.pin_tx );
4455}
4556
@@ -60,12 +71,13 @@ void HardwareSerial::init(PinName _rx, PinName _tx, PinName _rts, PinName _cts)
6071
6172
6273// Interrupt handler for filling rx buffer /////////////////////////////////////
63- #if (OPT_USART1_INT==1)
64-
65- #if defined(USART1)
74+ #if (OPT_USART_INT==1)
6675 #ifdef __cplusplus
6776 extern " C" {
6877 #endif
78+
79+ #if defined(USART1)
80+ #if defined(HAVE_HWSERIAL1)
6981 void USART1_IRQHandler (void ) __attribute__((interrupt(" WCH-Interrupt-fast" )));
7082 void USART1_IRQHandler (void ) {
7183 USART_ClearITPendingBit (USART1, USART_IT_RXNE);
@@ -77,13 +89,29 @@ void HardwareSerial::init(PinName _rx, PinName _tx, PinName _rts, PinName _cts)
7789 obj->_rx_buffer_head ++;
7890 obj->_rx_buffer_head %= SERIAL_RX_BUFFER_SIZE;
7991 }
80- #ifdef __cplusplus
81- }
82- #endif
92+ #endif
8393#endif
8494
95+ #if defined(USART2)
96+ #if defined(HAVE_HWSERIAL2)
97+ void USART2_IRQHandler (void ) __attribute__((interrupt(" WCH-Interrupt-fast" )));
98+ void USART2_IRQHandler (void ) {
99+ USART_ClearITPendingBit (USART2, USART_IT_RXNE);
100+ // Use the proper serial object to fill the RX buffer. Perhaps we should use uart_handlers[] as defined in uart.c
101+ // Second Serial is most often Serial2, initialized below as HardwareSerial Serial2(USART2); DEBUG_UART may give issues.
102+ // TODO? get_serial_obj(uart_handlers[UART2_INDEX]);
103+ HardwareSerial *obj=&Serial2;
104+ obj->_rx_buffer [obj->_rx_buffer_head ] = USART_ReceiveData (USART2); // maybe we should use uart_getc()?
105+ obj->_rx_buffer_head ++;
106+ obj->_rx_buffer_head %= SERIAL_RX_BUFFER_SIZE;
107+ }
108+ #endif
85109#endif
86110
111+ #ifdef __cplusplus
112+ }
113+ #endif
114+ #endif // if(OPT_USART_INT==1)
87115
88116// Public Methods //////////////////////////////////////////////////////////////
89117void HardwareSerial::begin (unsigned long baud, byte config)
@@ -166,14 +194,19 @@ void HardwareSerial::begin(unsigned long baud, byte config)
166194 }
167195 uart_init (&_serial, (uint32_t )baud, databits, parity, stopbits);
168196
169- #if (OPT_USART1_INT ==1)
197+ #if (OPT_USART_INT ==1)
170198 // MMOLE 240619: Enable interrupt handler for filling rx buffer
171199 #if defined(USART1)
172200 USART_ITConfig (USART1, USART_IT_RXNE, ENABLE);
173201 NVIC_SetPriority (USART1_IRQn, UART_IRQ_PRIO);
174202 NVIC_EnableIRQ (USART1_IRQn);
175203 #endif
176- // MMOLE TODO: I only have CH32V003; only tested USART1, how about others?
204+ // MMOLE TODO: I only have CH32V003/CH32X033; only tested USART1 and USART2, how about others?
205+ #if defined(USART2)
206+ USART_ITConfig (USART2, USART_IT_RXNE, ENABLE);
207+ NVIC_SetPriority (USART2_IRQn, UART_IRQ_PRIO);
208+ NVIC_EnableIRQ (USART2_IRQn);
209+ #endif
177210#endif
178211}
179212
@@ -185,8 +218,8 @@ void HardwareSerial::end()
185218
186219 uart_deinit (&_serial);
187220
188- #if (OPT_USART1_INT ==1)
189- // MMOLE TODO: disable interrupt handler
221+ #if (OPT_USART_INT ==1)
222+ // MMOLE TODO: disable interrupt handlers
190223#endif
191224}
192225
@@ -234,15 +267,25 @@ int HardwareSerial::read(void)
234267
235268size_t HardwareSerial::write (const uint8_t *buffer, size_t size)
236269{
237-
270+ #if OPT_PR180 // PR180: HardwareSerial: use correct UART HW for TX
271+ for (size_t i = 0 ; i < size; i++) {
272+ write (buffer[i]);
273+ }
274+ return size;
275+ #else
238276 return uart_debug_write ((uint8_t *)buffer, size);
277+ #endif
239278}
240279
241280
242281size_t HardwareSerial::write (uint8_t c)
243282{
283+ #if OPT_PR180 // PR180: HardwareSerial: use correct UART HW for TX
284+ return uart_putc (&_serial, c);
285+ #else
244286 uint8_t buff = c;
245287 return write (&buff, 1 );
288+ #endif
246289}
247290
248291void HardwareSerial::setRx (uint32_t _rx)
0 commit comments