|
21 | 21 | Modified 14 August 2012 by Alarus
|
22 | 22 | Modified 3 December 2013 by Matthijs Kooijman
|
23 | 23 | Modified 1 may 2023 by TempersLee
|
| 24 | + Modified 28 July 2024 by Maxint R&D |
24 | 25 | */
|
25 | 26 |
|
| 27 | + |
26 | 28 | #include <stdio.h>
|
27 | 29 | #include "Arduino.h"
|
28 | 30 | #include "HardwareSerial.h"
|
@@ -57,6 +59,31 @@ void HardwareSerial::init(PinName _rx, PinName _tx, PinName _rts, PinName _cts)
|
57 | 59 | }
|
58 | 60 |
|
59 | 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 | + |
60 | 87 |
|
61 | 88 | // Public Methods //////////////////////////////////////////////////////////////
|
62 | 89 | void HardwareSerial::begin(unsigned long baud, byte config)
|
@@ -138,32 +165,70 @@ void HardwareSerial::begin(unsigned long baud, byte config)
|
138 | 165 | break;
|
139 | 166 | }
|
140 | 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 |
141 | 178 | }
|
142 | 179 |
|
143 | 180 | void HardwareSerial::end()
|
144 | 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 | + |
145 | 186 | uart_deinit(&_serial);
|
| 187 | + |
| 188 | +#if(OPT_USART1_INT==1) |
| 189 | + // MMOLE TODO: disable interrupt handler |
| 190 | +#endif |
146 | 191 | }
|
147 | 192 |
|
148 | 193 | int HardwareSerial::available(void)
|
149 | 194 | {
|
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; |
151 | 198 | }
|
152 | 199 |
|
153 | 200 | int HardwareSerial::peek(void)
|
154 | 201 | {
|
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 | + } |
156 | 210 | }
|
157 | 211 |
|
158 | 212 | int HardwareSerial::read(void)
|
159 | 213 | {
|
160 |
| - |
161 | 214 | unsigned char c;
|
| 215 | + // MMOLE: reintroduced RX buffer to properly implement read/available/peek methods |
| 216 | +/* |
162 | 217 | if(uart_getc(&_serial, &c) == 0){
|
163 | 218 | return c;
|
164 | 219 | }else{
|
165 | 220 | return -1;
|
166 | 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 | + } |
167 | 232 | }
|
168 | 233 |
|
169 | 234 |
|
|
0 commit comments