Skip to content

Commit d6308a2

Browse files
authored
1 parent 2dc26a7 commit d6308a2

File tree

2 files changed

+587
-0
lines changed

2 files changed

+587
-0
lines changed

Diff for: cores/arduino/ch32/HardwareSerial.cpp

+358
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,358 @@
1+
/*
2+
HardwareSerial.cpp - Hardware serial library for Wiring
3+
Copyright (c) 2006 Nicholas Zambetti. All right reserved.
4+
5+
This library is free software; you can redistribute it and/or
6+
modify it under the terms of the GNU Lesser General Public
7+
License as published by the Free Software Foundation; either
8+
version 2.1 of the License, or (at your option) any later version.
9+
10+
This library is distributed in the hope that it will be useful,
11+
but WITHOUT ANY WARRANTY; without even the implied warranty of
12+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13+
Lesser General Public License for more details.
14+
15+
You should have received a copy of the GNU Lesser General Public
16+
License along with this library; if not, write to the Free Software
17+
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
18+
19+
Modified 23 November 2006 by David A. Mellis
20+
Modified 28 September 2010 by Mark Sproul
21+
Modified 14 August 2012 by Alarus
22+
Modified 3 December 2013 by Matthijs Kooijman
23+
Modified 1 may 2023 by TempersLee
24+
Modified 28 July 2024 by Maxint R&D
25+
*/
26+
27+
28+
#include <stdio.h>
29+
#include "Arduino.h"
30+
#include "HardwareSerial.h"
31+
32+
#if defined(UART_MODULE_ENABLED) && !defined(UART_MODULE_ONLY)
33+
34+
35+
HardwareSerial::HardwareSerial(void *peripheral)
36+
{
37+
setHandler(peripheral);
38+
39+
setRx(PIN_SERIAL_RX);
40+
41+
setTx(PIN_SERIAL_TX);
42+
43+
init(_serial.pin_rx, _serial.pin_tx);
44+
}
45+
46+
47+
48+
49+
void HardwareSerial::init(PinName _rx, PinName _tx, PinName _rts, PinName _cts)
50+
{
51+
if (_rx == _tx) {
52+
_serial.pin_rx = NC;
53+
} else {
54+
_serial.pin_rx = _rx;
55+
}
56+
_serial.pin_tx = _tx;
57+
_serial.pin_rts = _rts;
58+
_serial.pin_cts = _cts;
59+
}
60+
61+
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+
87+
88+
// Public Methods //////////////////////////////////////////////////////////////
89+
void HardwareSerial::begin(unsigned long baud, byte config)
90+
{
91+
uint32_t databits = 0;
92+
uint32_t stopbits = 0;
93+
uint32_t parity = 0;
94+
95+
_baud = baud;
96+
_config = config;
97+
98+
// Manage databits
99+
switch (config & 0x03) {
100+
case 0x00:
101+
databits = 6;
102+
break;
103+
case 0x01:
104+
databits = 7;
105+
break;
106+
case 0x02:
107+
databits = 8;
108+
break;
109+
case 0x03:
110+
databits = 9;
111+
break;
112+
default:
113+
databits = 8;
114+
break;
115+
}
116+
117+
if ((config & 0x30) == 0x30) {
118+
parity = USART_Parity_Odd;
119+
} else if ((config & 0x20) == 0x20) {
120+
parity = USART_Parity_Even;
121+
} else {
122+
parity = USART_Parity_No;
123+
}
124+
125+
126+
switch ( (config & 0x0C) >> 2 ) {
127+
case 0x00:
128+
stopbits = USART_StopBits_1;
129+
break;
130+
case 0x01:
131+
stopbits = USART_StopBits_0_5;
132+
break;
133+
case 0x02:
134+
stopbits = USART_StopBits_2;
135+
break;
136+
case 0x03:
137+
stopbits = USART_StopBits_1_5;
138+
break;
139+
default:
140+
stopbits = USART_StopBits_1;
141+
break;
142+
}
143+
144+
switch (databits)
145+
{
146+
#ifdef USART_WordLength_6b
147+
case 6:
148+
databits = USART_WordLength_6b;
149+
break;
150+
#endif
151+
#ifdef USART_WordLength_7b
152+
case 7:
153+
databits = USART_WordLength_7b;
154+
break;
155+
#endif
156+
case 8:
157+
databits = USART_WordLength_8b;
158+
break;
159+
case 9:
160+
databits = USART_WordLength_9b;
161+
break;
162+
default:
163+
case 0:
164+
Error_Handler();
165+
break;
166+
}
167+
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
178+
}
179+
180+
void HardwareSerial::end()
181+
{
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+
186+
uart_deinit(&_serial);
187+
188+
#if(OPT_USART1_INT==1)
189+
// MMOLE TODO: disable interrupt handler
190+
#endif
191+
}
192+
193+
int HardwareSerial::available(void)
194+
{
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;
198+
}
199+
200+
int HardwareSerial::peek(void)
201+
{
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+
}
210+
}
211+
212+
int HardwareSerial::read(void)
213+
{
214+
unsigned char c;
215+
// MMOLE: reintroduced RX buffer to properly implement read/available/peek methods
216+
/*
217+
if(uart_getc(&_serial, &c) == 0){
218+
return c;
219+
}else{
220+
return -1;
221+
}
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+
}
232+
}
233+
234+
235+
size_t HardwareSerial::write(const uint8_t *buffer, size_t size)
236+
{
237+
238+
return uart_debug_write((uint8_t *)buffer, size);
239+
}
240+
241+
242+
size_t HardwareSerial::write(uint8_t c)
243+
{
244+
uint8_t buff = c;
245+
return write(&buff, 1);
246+
}
247+
248+
void HardwareSerial::setRx(uint32_t _rx)
249+
{
250+
_serial.pin_rx = digitalPinToPinName(_rx);
251+
}
252+
253+
void HardwareSerial::setTx(uint32_t _tx)
254+
{
255+
_serial.pin_tx = digitalPinToPinName(_tx);
256+
}
257+
258+
void HardwareSerial::setRx(PinName _rx)
259+
{
260+
_serial.pin_rx = _rx;
261+
}
262+
263+
void HardwareSerial::setTx(PinName _tx)
264+
{
265+
_serial.pin_tx = _tx;
266+
}
267+
268+
void HardwareSerial::setRts(uint32_t _rts)
269+
{
270+
_serial.pin_rts = digitalPinToPinName(_rts);
271+
}
272+
273+
void HardwareSerial::setCts(uint32_t _cts)
274+
{
275+
_serial.pin_cts = digitalPinToPinName(_cts);
276+
}
277+
278+
void HardwareSerial::setRtsCts(uint32_t _rts, uint32_t _cts)
279+
{
280+
_serial.pin_rts = digitalPinToPinName(_rts);
281+
_serial.pin_cts = digitalPinToPinName(_cts);
282+
}
283+
284+
void HardwareSerial::setRts(PinName _rts)
285+
{
286+
_serial.pin_rts = _rts;
287+
}
288+
289+
void HardwareSerial::setCts(PinName _cts)
290+
{
291+
_serial.pin_cts = _cts;
292+
}
293+
294+
void HardwareSerial::setRtsCts(PinName _rts, PinName _cts)
295+
{
296+
_serial.pin_rts = _rts;
297+
_serial.pin_cts = _cts;
298+
}
299+
300+
void HardwareSerial::setHandler(void *handler)
301+
{
302+
_serial.uart = (USART_TypeDef *) handler;
303+
}
304+
305+
306+
307+
308+
#if defined(HAVE_HWSERIAL1) || defined(HAVE_HWSERIAL2) || defined(HAVE_HWSERIAL3) ||\
309+
defined(HAVE_HWSERIAL4) || defined(HAVE_HWSERIAL5) || defined(HAVE_HWSERIAL6) ||\
310+
defined(HAVE_HWSERIAL7) || defined(HAVE_HWSERIAL8)
311+
// SerialEvent functions are weak, so when the user doesn't define them,
312+
// the linker just sets their address to 0 (which is checked below).
313+
#if defined(HAVE_HWSERIAL1)
314+
HardwareSerial Serial1(USART1);
315+
#endif
316+
317+
#if defined(HAVE_HWSERIAL2)
318+
HardwareSerial Serial2(USART2);
319+
#endif
320+
321+
#if defined(HAVE_HWSERIAL3)
322+
HardwareSerial Serial3(USART3);
323+
#endif
324+
325+
#if defined(HAVE_HWSERIAL4)
326+
#if defined(USART4)
327+
HardwareSerial Serial4(USART4);
328+
#else
329+
HardwareSerial Serial4(UART4);
330+
#endif
331+
#endif
332+
333+
#if defined(HAVE_HWSERIAL5)
334+
#if defined(UART5)
335+
HardwareSerial Serial5(UART5);
336+
#endif
337+
#endif
338+
339+
#if defined(HAVE_HWSERIAL6)
340+
HardwareSerial Serial6(UART6);
341+
#endif
342+
343+
#if defined(HAVE_HWSERIAL7)
344+
#if defined(UART7)
345+
HardwareSerial Serial7(UART7);
346+
#endif
347+
#endif
348+
349+
#if defined(HAVE_HWSERIAL8)
350+
#if defined(UART8)
351+
HardwareSerial Serial8(UART8);
352+
#endif
353+
#endif
354+
#endif // HAVE_HWSERIALx
355+
356+
357+
358+
#endif // UART_MODULE_ENABLED && !UART_MODULE_ONLY

0 commit comments

Comments
 (0)