Fri, 17 Nov 2017 10:13:31 +0100
proper configuration, homing and planner optimization
2 | 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 | */ | |
22 | ||
23 | #include <stdlib.h> | |
24 | #include <stdio.h> | |
25 | #include <string.h> | |
26 | #include <inttypes.h> | |
27 | #include "Arduino.h" | |
28 | #include "wiring_private.h" | |
29 | ||
30 | // this next line disables the entire HardwareSerial.cpp, | |
31 | // this is so I can support Attiny series and any other chip without a uart | |
32 | #if defined(UBRRH) || defined(UBRR0H) || defined(UBRR1H) || defined(UBRR2H) || defined(UBRR3H) | |
33 | ||
34 | #include "HardwareSerial.h" | |
35 | ||
36 | // Define constants and variables for buffering incoming serial data. We're | |
37 | // using a ring buffer (I think), in which head is the index of the location | |
38 | // to which to write the next incoming character and tail is the index of the | |
39 | // location from which to read. | |
40 | #if (RAMEND < 1000) | |
41 | #define SERIAL_BUFFER_SIZE 16 | |
42 | #else | |
43 | #define SERIAL_BUFFER_SIZE 64 | |
44 | #endif | |
45 | ||
46 | struct ring_buffer | |
47 | { | |
48 | unsigned char buffer[SERIAL_BUFFER_SIZE]; | |
49 | volatile unsigned int head; | |
50 | volatile unsigned int tail; | |
51 | }; | |
52 | ||
53 | #if defined(USBCON) | |
54 | ring_buffer rx_buffer = { { 0 }, 0, 0}; | |
55 | ring_buffer tx_buffer = { { 0 }, 0, 0}; | |
56 | #endif | |
57 | #if defined(UBRRH) || defined(UBRR0H) | |
58 | ring_buffer rx_buffer = { { 0 }, 0, 0 }; | |
59 | ring_buffer tx_buffer = { { 0 }, 0, 0 }; | |
60 | #endif | |
61 | #if defined(UBRR1H) | |
62 | ring_buffer rx_buffer1 = { { 0 }, 0, 0 }; | |
63 | ring_buffer tx_buffer1 = { { 0 }, 0, 0 }; | |
64 | #endif | |
65 | #if defined(UBRR2H) | |
66 | ring_buffer rx_buffer2 = { { 0 }, 0, 0 }; | |
67 | ring_buffer tx_buffer2 = { { 0 }, 0, 0 }; | |
68 | #endif | |
69 | #if defined(UBRR3H) | |
70 | ring_buffer rx_buffer3 = { { 0 }, 0, 0 }; | |
71 | ring_buffer tx_buffer3 = { { 0 }, 0, 0 }; | |
72 | #endif | |
73 | ||
74 | inline void store_char(unsigned char c, ring_buffer *buffer) | |
75 | { | |
76 | int i = (unsigned int)(buffer->head + 1) % SERIAL_BUFFER_SIZE; | |
77 | ||
78 | // if we should be storing the received character into the location | |
79 | // just before the tail (meaning that the head would advance to the | |
80 | // current location of the tail), we're about to overflow the buffer | |
81 | // and so we don't write the character or advance the head. | |
82 | if (i != buffer->tail) { | |
83 | buffer->buffer[buffer->head] = c; | |
84 | buffer->head = i; | |
85 | } | |
86 | } | |
87 | ||
88 | #if !defined(USART0_RX_vect) && defined(USART1_RX_vect) | |
89 | // do nothing - on the 32u4 the first USART is USART1 | |
90 | #else | |
91 | #if !defined(USART_RX_vect) && !defined(SIG_USART0_RECV) && \ | |
92 | !defined(SIG_UART0_RECV) && !defined(USART0_RX_vect) && \ | |
93 | !defined(SIG_UART_RECV) | |
94 | #error "Don't know what the Data Received vector is called for the first UART" | |
95 | #else | |
96 | void serialEvent() __attribute__((weak)); | |
97 | void serialEvent() {} | |
98 | #define serialEvent_implemented | |
99 | #if defined(USART_RX_vect) | |
100 | SIGNAL(USART_RX_vect) | |
101 | #elif defined(SIG_USART0_RECV) | |
102 | SIGNAL(SIG_USART0_RECV) | |
103 | #elif defined(SIG_UART0_RECV) | |
104 | SIGNAL(SIG_UART0_RECV) | |
105 | #elif defined(USART0_RX_vect) | |
106 | SIGNAL(USART0_RX_vect) | |
107 | #elif defined(SIG_UART_RECV) | |
108 | SIGNAL(SIG_UART_RECV) | |
109 | #endif | |
110 | { | |
111 | #if defined(UDR0) | |
112 | unsigned char c = UDR0; | |
113 | #elif defined(UDR) | |
114 | unsigned char c = UDR; | |
115 | #else | |
116 | #error UDR not defined | |
117 | #endif | |
118 | store_char(c, &rx_buffer); | |
119 | } | |
120 | #endif | |
121 | #endif | |
122 | ||
123 | #if defined(USART1_RX_vect) | |
124 | void serialEvent1() __attribute__((weak)); | |
125 | void serialEvent1() {} | |
126 | #define serialEvent1_implemented | |
127 | SIGNAL(USART1_RX_vect) | |
128 | { | |
129 | unsigned char c = UDR1; | |
130 | store_char(c, &rx_buffer1); | |
131 | } | |
132 | #elif defined(SIG_USART1_RECV) | |
133 | #error SIG_USART1_RECV | |
134 | #endif | |
135 | ||
136 | #if defined(USART2_RX_vect) && defined(UDR2) | |
137 | void serialEvent2() __attribute__((weak)); | |
138 | void serialEvent2() {} | |
139 | #define serialEvent2_implemented | |
140 | SIGNAL(USART2_RX_vect) | |
141 | { | |
142 | unsigned char c = UDR2; | |
143 | store_char(c, &rx_buffer2); | |
144 | } | |
145 | #elif defined(SIG_USART2_RECV) | |
146 | #error SIG_USART2_RECV | |
147 | #endif | |
148 | ||
149 | #if defined(USART3_RX_vect) && defined(UDR3) | |
150 | void serialEvent3() __attribute__((weak)); | |
151 | void serialEvent3() {} | |
152 | #define serialEvent3_implemented | |
153 | SIGNAL(USART3_RX_vect) | |
154 | { | |
155 | unsigned char c = UDR3; | |
156 | store_char(c, &rx_buffer3); | |
157 | } | |
158 | #elif defined(SIG_USART3_RECV) | |
159 | #error SIG_USART3_RECV | |
160 | #endif | |
161 | ||
162 | void serialEventRun(void) | |
163 | { | |
164 | #ifdef serialEvent_implemented | |
165 | if (Serial.available()) serialEvent(); | |
166 | #endif | |
167 | #ifdef serialEvent1_implemented | |
168 | if (Serial1.available()) serialEvent1(); | |
169 | #endif | |
170 | #ifdef serialEvent2_implemented | |
171 | if (Serial2.available()) serialEvent2(); | |
172 | #endif | |
173 | #ifdef serialEvent3_implemented | |
174 | if (Serial3.available()) serialEvent3(); | |
175 | #endif | |
176 | } | |
177 | ||
178 | ||
179 | #if !defined(USART0_UDRE_vect) && defined(USART1_UDRE_vect) | |
180 | // do nothing - on the 32u4 the first USART is USART1 | |
181 | #else | |
182 | #if !defined(UART0_UDRE_vect) && !defined(UART_UDRE_vect) && !defined(USART0_UDRE_vect) && !defined(USART_UDRE_vect) | |
183 | #error "Don't know what the Data Register Empty vector is called for the first UART" | |
184 | #else | |
185 | #if defined(UART0_UDRE_vect) | |
186 | ISR(UART0_UDRE_vect) | |
187 | #elif defined(UART_UDRE_vect) | |
188 | ISR(UART_UDRE_vect) | |
189 | #elif defined(USART0_UDRE_vect) | |
190 | ISR(USART0_UDRE_vect) | |
191 | #elif defined(USART_UDRE_vect) | |
192 | ISR(USART_UDRE_vect) | |
193 | #endif | |
194 | { | |
195 | if (tx_buffer.head == tx_buffer.tail) { | |
196 | // Buffer empty, so disable interrupts | |
197 | #if defined(UCSR0B) | |
198 | cbi(UCSR0B, UDRIE0); | |
199 | #else | |
200 | cbi(UCSRB, UDRIE); | |
201 | #endif | |
202 | } | |
203 | else { | |
204 | // There is more data in the output buffer. Send the next byte | |
205 | unsigned char c = tx_buffer.buffer[tx_buffer.tail]; | |
206 | tx_buffer.tail = (tx_buffer.tail + 1) % SERIAL_BUFFER_SIZE; | |
207 | ||
208 | #if defined(UDR0) | |
209 | UDR0 = c; | |
210 | #elif defined(UDR) | |
211 | UDR = c; | |
212 | #else | |
213 | #error UDR not defined | |
214 | #endif | |
215 | } | |
216 | } | |
217 | #endif | |
218 | #endif | |
219 | ||
220 | #ifdef USART1_UDRE_vect | |
221 | ISR(USART1_UDRE_vect) | |
222 | { | |
223 | if (tx_buffer1.head == tx_buffer1.tail) { | |
224 | // Buffer empty, so disable interrupts | |
225 | cbi(UCSR1B, UDRIE1); | |
226 | } | |
227 | else { | |
228 | // There is more data in the output buffer. Send the next byte | |
229 | unsigned char c = tx_buffer1.buffer[tx_buffer1.tail]; | |
230 | tx_buffer1.tail = (tx_buffer1.tail + 1) % SERIAL_BUFFER_SIZE; | |
231 | ||
232 | UDR1 = c; | |
233 | } | |
234 | } | |
235 | #endif | |
236 | ||
237 | #ifdef USART2_UDRE_vect | |
238 | ISR(USART2_UDRE_vect) | |
239 | { | |
240 | if (tx_buffer2.head == tx_buffer2.tail) { | |
241 | // Buffer empty, so disable interrupts | |
242 | cbi(UCSR2B, UDRIE2); | |
243 | } | |
244 | else { | |
245 | // There is more data in the output buffer. Send the next byte | |
246 | unsigned char c = tx_buffer2.buffer[tx_buffer2.tail]; | |
247 | tx_buffer2.tail = (tx_buffer2.tail + 1) % SERIAL_BUFFER_SIZE; | |
248 | ||
249 | UDR2 = c; | |
250 | } | |
251 | } | |
252 | #endif | |
253 | ||
254 | #ifdef USART3_UDRE_vect | |
255 | ISR(USART3_UDRE_vect) | |
256 | { | |
257 | if (tx_buffer3.head == tx_buffer3.tail) { | |
258 | // Buffer empty, so disable interrupts | |
259 | cbi(UCSR3B, UDRIE3); | |
260 | } | |
261 | else { | |
262 | // There is more data in the output buffer. Send the next byte | |
263 | unsigned char c = tx_buffer3.buffer[tx_buffer3.tail]; | |
264 | tx_buffer3.tail = (tx_buffer3.tail + 1) % SERIAL_BUFFER_SIZE; | |
265 | ||
266 | UDR3 = c; | |
267 | } | |
268 | } | |
269 | #endif | |
270 | ||
271 | ||
272 | // Constructors //////////////////////////////////////////////////////////////// | |
273 | ||
274 | HardwareSerial::HardwareSerial(ring_buffer *rx_buffer, ring_buffer *tx_buffer, | |
275 | volatile uint8_t *ubrrh, volatile uint8_t *ubrrl, | |
276 | volatile uint8_t *ucsra, volatile uint8_t *ucsrb, | |
277 | volatile uint8_t *udr, | |
278 | uint8_t rxen, uint8_t txen, uint8_t rxcie, uint8_t udrie, uint8_t u2x) | |
279 | { | |
280 | _rx_buffer = rx_buffer; | |
281 | _tx_buffer = tx_buffer; | |
282 | _ubrrh = ubrrh; | |
283 | _ubrrl = ubrrl; | |
284 | _ucsra = ucsra; | |
285 | _ucsrb = ucsrb; | |
286 | _udr = udr; | |
287 | _rxen = rxen; | |
288 | _txen = txen; | |
289 | _rxcie = rxcie; | |
290 | _udrie = udrie; | |
291 | _u2x = u2x; | |
292 | } | |
293 | ||
294 | // Public Methods ////////////////////////////////////////////////////////////// | |
295 | ||
296 | void HardwareSerial::begin(unsigned long baud) | |
297 | { | |
298 | uint16_t baud_setting; | |
299 | bool use_u2x = true; | |
300 | ||
301 | #if F_CPU == 16000000UL | |
302 | // hardcoded exception for compatibility with the bootloader shipped | |
303 | // with the Duemilanove and previous boards and the firmware on the 8U2 | |
304 | // on the Uno and Mega 2560. | |
305 | if (baud == 57600) { | |
306 | use_u2x = false; | |
307 | } | |
308 | #endif | |
309 | ||
310 | try_again: | |
311 | ||
312 | if (use_u2x) { | |
313 | *_ucsra = 1 << _u2x; | |
314 | baud_setting = (F_CPU / 4 / baud - 1) / 2; | |
315 | } else { | |
316 | *_ucsra = 0; | |
317 | baud_setting = (F_CPU / 8 / baud - 1) / 2; | |
318 | } | |
319 | ||
320 | if ((baud_setting > 4095) && use_u2x) | |
321 | { | |
322 | use_u2x = false; | |
323 | goto try_again; | |
324 | } | |
325 | ||
326 | // assign the baud_setting, a.k.a. ubbr (USART Baud Rate Register) | |
327 | *_ubrrh = baud_setting >> 8; | |
328 | *_ubrrl = baud_setting; | |
329 | ||
330 | sbi(*_ucsrb, _rxen); | |
331 | sbi(*_ucsrb, _txen); | |
332 | sbi(*_ucsrb, _rxcie); | |
333 | cbi(*_ucsrb, _udrie); | |
334 | } | |
335 | ||
336 | void HardwareSerial::end() | |
337 | { | |
338 | // wait for transmission of outgoing data | |
339 | while (_tx_buffer->head != _tx_buffer->tail) | |
340 | ; | |
341 | ||
342 | cbi(*_ucsrb, _rxen); | |
343 | cbi(*_ucsrb, _txen); | |
344 | cbi(*_ucsrb, _rxcie); | |
345 | cbi(*_ucsrb, _udrie); | |
346 | ||
347 | // clear any received data | |
348 | _rx_buffer->head = _rx_buffer->tail; | |
349 | } | |
350 | ||
351 | int HardwareSerial::available(void) | |
352 | { | |
353 | return (unsigned int)(SERIAL_BUFFER_SIZE + _rx_buffer->head - _rx_buffer->tail) % SERIAL_BUFFER_SIZE; | |
354 | } | |
355 | ||
356 | int HardwareSerial::peek(void) | |
357 | { | |
358 | if (_rx_buffer->head == _rx_buffer->tail) { | |
359 | return -1; | |
360 | } else { | |
361 | return _rx_buffer->buffer[_rx_buffer->tail]; | |
362 | } | |
363 | } | |
364 | ||
365 | int HardwareSerial::read(void) | |
366 | { | |
367 | // if the head isn't ahead of the tail, we don't have any characters | |
368 | if (_rx_buffer->head == _rx_buffer->tail) { | |
369 | return -1; | |
370 | } else { | |
371 | unsigned char c = _rx_buffer->buffer[_rx_buffer->tail]; | |
372 | _rx_buffer->tail = (unsigned int)(_rx_buffer->tail + 1) % SERIAL_BUFFER_SIZE; | |
373 | return c; | |
374 | } | |
375 | } | |
376 | ||
377 | void HardwareSerial::flush() | |
378 | { | |
379 | while (_tx_buffer->head != _tx_buffer->tail) | |
380 | ; | |
381 | } | |
382 | ||
383 | size_t HardwareSerial::write(uint8_t c) | |
384 | { | |
385 | int i = (_tx_buffer->head + 1) % SERIAL_BUFFER_SIZE; | |
386 | ||
387 | // If the output buffer is full, there's nothing for it other than to | |
388 | // wait for the interrupt handler to empty it a bit | |
389 | // ???: return 0 here instead? | |
390 | while (i == _tx_buffer->tail) | |
391 | ; | |
392 | ||
393 | _tx_buffer->buffer[_tx_buffer->head] = c; | |
394 | _tx_buffer->head = i; | |
395 | ||
396 | sbi(*_ucsrb, _udrie); | |
397 | ||
398 | return 1; | |
399 | } | |
400 | ||
401 | HardwareSerial::operator bool() { | |
402 | return true; | |
403 | } | |
404 | ||
405 | // Preinstantiate Objects ////////////////////////////////////////////////////// | |
406 | ||
407 | #if defined(UBRRH) && defined(UBRRL) | |
408 | HardwareSerial Serial(&rx_buffer, &tx_buffer, &UBRRH, &UBRRL, &UCSRA, &UCSRB, &UDR, RXEN, TXEN, RXCIE, UDRIE, U2X); | |
409 | #elif defined(UBRR0H) && defined(UBRR0L) | |
410 | HardwareSerial Serial(&rx_buffer, &tx_buffer, &UBRR0H, &UBRR0L, &UCSR0A, &UCSR0B, &UDR0, RXEN0, TXEN0, RXCIE0, UDRIE0, U2X0); | |
411 | #elif defined(USBCON) | |
412 | // do nothing - Serial object and buffers are initialized in CDC code | |
413 | #else | |
414 | #error no serial port defined (port 0) | |
415 | #endif | |
416 | ||
417 | #if defined(UBRR1H) | |
418 | HardwareSerial Serial1(&rx_buffer1, &tx_buffer1, &UBRR1H, &UBRR1L, &UCSR1A, &UCSR1B, &UDR1, RXEN1, TXEN1, RXCIE1, UDRIE1, U2X1); | |
419 | #endif | |
420 | #if defined(UBRR2H) | |
421 | HardwareSerial Serial2(&rx_buffer2, &tx_buffer2, &UBRR2H, &UBRR2L, &UCSR2A, &UCSR2B, &UDR2, RXEN2, TXEN2, RXCIE2, UDRIE2, U2X2); | |
422 | #endif | |
423 | #if defined(UBRR3H) | |
424 | HardwareSerial Serial3(&rx_buffer3, &tx_buffer3, &UBRR3H, &UBRR3L, &UCSR3A, &UCSR3B, &UDR3, RXEN3, TXEN3, RXCIE3, UDRIE3, U2X3); | |
425 | #endif | |
426 | ||
427 | #endif // whole file | |
428 |