Skip to content

Commit a8bb304

Browse files
authored
patch PR#145 from openwch/arduino_core_ch32
openwch#145
1 parent 1a6767a commit a8bb304

File tree

2 files changed

+91
-8
lines changed

2 files changed

+91
-8
lines changed

Diff for: cores/arduino/HardwareSerial.cpp

+68-3
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,10 @@
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
2425
*/
2526

27+
2628
#include <stdio.h>
2729
#include "Arduino.h"
2830
#include "HardwareSerial.h"
@@ -57,6 +59,31 @@ void HardwareSerial::init(PinName _rx, PinName _tx, PinName _rts, PinName _cts)
5759
}
5860

5961

62+
// Interrupt handler for filling rx buffer /////////////////////////////////////
63+
#if(OPT_USART1_INT==1)
64+
65+
#if defined(USART1)
66+
#ifdef __cplusplus
67+
extern "C" {
68+
#endif
69+
void USART1_IRQHandler(void) __attribute__((interrupt("WCH-Interrupt-fast")));
70+
void USART1_IRQHandler(void) {
71+
USART_ClearITPendingBit(USART1, USART_IT_RXNE);
72+
// Use the proper serial object to fill the RX buffer. Perhaps we should use uart_handlers[] as defined in uart.c
73+
// Serial is most often Serial1, initialized below as HardwareSerial Serial1(USART1); DEBUG_UART may give issues.
74+
// TODO? get_serial_obj(uart_handlers[UART1_INDEX]);
75+
HardwareSerial *obj=&Serial1;
76+
obj->_rx_buffer[obj->_rx_buffer_head] = USART_ReceiveData(USART1); // maybe we should use uart_getc()?
77+
obj->_rx_buffer_head++;
78+
obj->_rx_buffer_head %= SERIAL_RX_BUFFER_SIZE;
79+
}
80+
#ifdef __cplusplus
81+
}
82+
#endif
83+
#endif
84+
85+
#endif
86+
6087

6188
// Public Methods //////////////////////////////////////////////////////////////
6289
void HardwareSerial::begin(unsigned long baud, byte config)
@@ -138,32 +165,70 @@ void HardwareSerial::begin(unsigned long baud, byte config)
138165
break;
139166
}
140167
uart_init(&_serial, (uint32_t)baud, databits, parity, stopbits);
168+
169+
#if(OPT_USART1_INT==1)
170+
// MMOLE 240619: Enable interrupt handler for filling rx buffer
171+
#if defined(USART1)
172+
USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);
173+
NVIC_SetPriority(USART1_IRQn, UART_IRQ_PRIO);
174+
NVIC_EnableIRQ(USART1_IRQn);
175+
#endif
176+
// MMOLE TODO: I only have CH32V003; only tested USART1, how about others?
177+
#endif
141178
}
142179

143180
void HardwareSerial::end()
144181
{
182+
// MMOLE: reintroduced RX buffer to properly implement read/available/peek methods
183+
// clear any received data
184+
_rx_buffer_head = _rx_buffer_tail;
185+
145186
uart_deinit(&_serial);
187+
188+
#if(OPT_USART1_INT==1)
189+
// MMOLE TODO: disable interrupt handler
190+
#endif
146191
}
147192

148193
int HardwareSerial::available(void)
149194
{
150-
return -1;
195+
// MMOLE: reintroduced RX buffer to properly implement read/available/peek methods
196+
//return -1;
197+
return ((unsigned int)(SERIAL_RX_BUFFER_SIZE + _rx_buffer_head - _rx_buffer_tail)) % SERIAL_RX_BUFFER_SIZE;
151198
}
152199

153200
int HardwareSerial::peek(void)
154201
{
155-
return -1;
202+
// MMOLE: reintroduced RX buffer to properly implement read/available/peek methods
203+
// MMOLE 240316: Serial.parseInt() uses peek() with timeout to see if more data is available
204+
//return -1;
205+
if (_rx_buffer_head == _rx_buffer_tail) {
206+
return -1;
207+
} else {
208+
return _rx_buffer[_rx_buffer_tail];
209+
}
156210
}
157211

158212
int HardwareSerial::read(void)
159213
{
160-
161214
unsigned char c;
215+
// MMOLE: reintroduced RX buffer to properly implement read/available/peek methods
216+
/*
162217
if(uart_getc(&_serial, &c) == 0){
163218
return c;
164219
}else{
165220
return -1;
166221
}
222+
*/
223+
224+
// if the head isn't ahead of the tail, we don't have any characters
225+
if (_rx_buffer_head == _rx_buffer_tail) {
226+
return -1;
227+
} else {
228+
unsigned char c = _rx_buffer[_rx_buffer_tail];
229+
_rx_buffer_tail = (rx_buffer_index_t)(_rx_buffer_tail + 1) % SERIAL_RX_BUFFER_SIZE;
230+
return c;
231+
}
167232
}
168233

169234

Diff for: cores/arduino/HardwareSerial.h

+23-5
Original file line numberDiff line numberDiff line change
@@ -19,12 +19,16 @@
1919
Modified 28 September 2010 by Mark Sproul
2020
Modified 14 August 2012 by Alarus
2121
Modified 3 December 2013 by Matthijs Kooijman
22-
Modified 1 may 2023 by TempersLee
22+
Modified 1 May 2023 by TempersLee
23+
Modified 28 July 2024 by Maxint R&D
2324
*/
2425

2526
#ifndef HardwareSerial_h
2627
#define HardwareSerial_h
2728

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
31+
2832
#if 1
2933

3034
#include <inttypes.h>
@@ -101,6 +105,9 @@ typedef enum {
101105

102106
class HardwareSerial : public Stream {
103107

108+
#if(OPT_USART1_INT==1)
109+
public:
110+
#endif
104111
serial_t _serial;
105112
public:
106113
HardwareSerial(void *peripheral);
@@ -109,6 +116,17 @@ class HardwareSerial : public Stream {
109116
{
110117
begin(baud, SERIAL_8N1); //SERIAL_9E1_5 SERIAL_8N1
111118
}
119+
// MMOLE: reintroduced RX buffer to properly implement read/available/peek methods
120+
volatile rx_buffer_index_t _rx_buffer_head;
121+
volatile rx_buffer_index_t _rx_buffer_tail;
122+
//volatile tx_buffer_index_t _tx_buffer_head;
123+
//volatile tx_buffer_index_t _tx_buffer_tail;
124+
125+
// Don't put any members after these buffers, since only the first
126+
// 32 bytes of this struct can be accessed quickly using the ldd
127+
// instruction.
128+
unsigned char _rx_buffer[SERIAL_RX_BUFFER_SIZE];
129+
//unsigned char _tx_buffer[SERIAL_TX_BUFFER_SIZE];
112130
void begin(unsigned long, uint8_t);
113131
void end();
114132

@@ -173,16 +191,16 @@ class HardwareSerial : public Stream {
173191
#if defined(UART4) || defined(USART4)
174192
extern HardwareSerial Serial4;
175193
#endif
176-
#if defined(UART5)
194+
#if defined(UART5)
177195
extern HardwareSerial Serial5;
178196
#endif
179-
#if defined(UART6)
197+
#if defined(UART6)
180198
extern HardwareSerial Serial6;
181199
#endif
182-
#if defined(UART7)
200+
#if defined(UART7)
183201
extern HardwareSerial Serial7;
184202
#endif
185-
#if defined(UART8)
203+
#if defined(UART8)
186204
extern HardwareSerial Serial8;
187205
#endif
188206

0 commit comments

Comments
 (0)