Skip to content

Commit 306350f

Browse files
authored
Interrupt driven Serial1, Serial2 or both (tested on CH32X033)
1 parent a98dc7b commit 306350f

File tree

2 files changed

+69
-25
lines changed

2 files changed

+69
-25
lines changed

cores/arduino/HardwareSerial.cpp

Lines changed: 58 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -21,10 +21,9 @@
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 //////////////////////////////////////////////////////////////
89117
void 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

235268
size_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

242281
size_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

248291
void HardwareSerial::setRx(uint32_t _rx)

cores/arduino/HardwareSerial.h

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -20,14 +20,15 @@
2020
Modified 14 August 2012 by Alarus
2121
Modified 3 December 2013 by Matthijs Kooijman
2222
Modified 1 May 2023 by TempersLee
23-
Modified 28 July 2024 by Maxint R&D
23+
Modified 13 October 2023 by Maxint R&D, latest update 6 May 2025
2424
*/
2525

2626
#ifndef HardwareSerial_h
2727
#define HardwareSerial_h
2828

29-
// MMOLE 240619: set OPT_USART1_INT to 1 if you want to use interrupts for receiving serial data.
30-
#define OPT_USART1_INT 1
29+
// MMOLE 240619: set OPT_USART_INT to 1 if you want to use interrupts for receiving serial data.
30+
#define OPT_USART_INT 1
31+
#define OPT_PR180 1 // PR180: HardwareSerial: use correct UART HW for TX
3132

3233
#if 1
3334

@@ -105,7 +106,7 @@ typedef enum {
105106

106107
class HardwareSerial : public Stream {
107108

108-
#if(OPT_USART1_INT==1)
109+
#if(OPT_USART_INT==1)
109110
public:
110111
#endif
111112
serial_t _serial;
@@ -191,30 +192,30 @@ class HardwareSerial : public Stream {
191192
#if defined(UART4) || defined(USART4)
192193
extern HardwareSerial Serial4;
193194
#endif
194-
#if defined(UART5)
195+
#if defined(UART5) || defined(USART5)
195196
extern HardwareSerial Serial5;
196197
#endif
197-
#if defined(UART6)
198+
#if defined(UART6) || defined(USART6)
198199
extern HardwareSerial Serial6;
199200
#endif
200-
#if defined(UART7)
201+
#if defined(UART7) || defined(USART7)
201202
extern HardwareSerial Serial7;
202203
#endif
203-
#if defined(UART8)
204+
#if defined(UART8) || defined(USART8)
204205
extern HardwareSerial Serial8;
205206
#endif
206207

207208

208209

209-
#else
210+
#else // #if 1
210211
211212
212213
213214
214215
215216
216217
217-
#endif
218+
#endif // #if 1
218219

219220

220221

0 commit comments

Comments
 (0)