FastLED 3.10.8
Loading...
Searching...
No Matches
serial.cpp.hpp
Go to the documentation of this file.
1// Arduino-compatible Serial API implementation
2
3#pragma once
4
5#include "fl/system/serial.h"
6#include "fl/stl/cstdio.h"
7#include "fl/stl/charconv.h"
8#include "fl/stl/cstring.h"
9#include "fl/stl/chrono.h"
10#include "fl/stl/noexcept.h"
11
12namespace fl {
13
14// ============================================================================
15// SerialPort Implementation
16// ============================================================================
17
19 // Most platforms don't need explicit end() call
20 // Serial is always available for debugging
21}
22
26
28 return fl::read();
29}
30
32 return fl::peek();
33}
34
36 char str[2] = {static_cast<char>(byte), '\0'};
37 fl::print(str);
38 return 1;
39}
40
41size_t SerialPort::write(const u8* buffer, size_t size) FL_NO_EXCEPT {
42 return fl::write_bytes(buffer, size);
43}
44
45size_t SerialPort::print(const char* str) FL_NO_EXCEPT {
46 if (!str) {
47 return 0;
48 }
49
50 fl::print(str);
51 return fl::strlen(str);
52}
53
55 char buffer[12]; // Enough for "-2147483648" + null
56 fl::itoa(value, buffer, 10); // Base 10
57 return print(buffer);
58}
59
61 char buffer[21]; // Enough for 64-bit values
62 fl::itoa64(value, buffer, 10); // Base 10
63 return print(buffer);
64}
65
66// Template implementation for unsigned multi-byte integers
67// Handles both u32 and unsigned long, avoiding duplicate overloads on platforms where they're the same type
68template<typename T>
71 size_t>::type
73 char buffer[21]; // Enough for 64-bit values
74
75 // Use utoa64 for all types - it handles both 32-bit and 64-bit values
76 // This avoids needing C++17 constexpr if
77 fl::utoa64(static_cast<fl::u64>(value), buffer, 10);
78
79 return print(buffer);
80}
81
82size_t SerialPort::println(const char* str) FL_NO_EXCEPT {
83 if (!str) {
84 return println();
85 }
86
87 fl::println(str);
88 return fl::strlen(str) + 1; // +1 for newline
89}
90
92 fl::println("");
93 return 1; // Just the newline
94}
95
97 char buffer[12];
98 fl::itoa(value, buffer, 10);
99 return println(buffer);
100}
101
103 char buffer[21];
104 fl::itoa64(value, buffer, 10);
105 return println(buffer);
106}
107
108// Template implementation for unsigned multi-byte integers
109// Handles both u32 and unsigned long, avoiding duplicate overloads on platforms where they're the same type
110template<typename T>
113 size_t>::type
115 char buffer[21]; // Enough for 64-bit values
116
117 // Use utoa64 for all types - it handles both 32-bit and 64-bit values
118 // This avoids needing C++17 constexpr if
119 fl::utoa64(static_cast<fl::u64>(value), buffer, 10);
120
121 return println(buffer);
122}
123
124// Note: printf() is now implemented as an inline template in serial.h
125
126bool SerialPort::flush(u32 timeoutMs) FL_NO_EXCEPT {
127 return fl::flush(timeoutMs);
128}
129
130SerialPort::operator bool() const FL_NO_EXCEPT {
131 return fl::serial_ready();
132}
133
135 mTimeoutMs = timeoutMs;
136}
137
140 u32 startTime = fl::millis();
141
142 while (fl::millis() - startTime < mTimeoutMs) {
143 if (available() > 0) {
144 int c = read();
145 if (c != -1) {
146 result += static_cast<char>(c);
147 startTime = fl::millis(); // Reset timeout on successful read
148 }
149 }
150 }
151
152 return result;
153}
154
157 u32 startTime = fl::millis();
158
159 while (fl::millis() - startTime < mTimeoutMs) {
160 if (available() > 0) {
161 int c = read();
162 if (c == -1) {
163 continue; // No data
164 }
165 if (c == delimiter) {
166 break; // Found delimiter, stop reading
167 }
168 result += static_cast<char>(c);
169 startTime = fl::millis(); // Reset timeout on successful read
170 }
171 }
172
173 return result;
174}
175
177 if (!buffer || length == 0) {
178 return 0;
179 }
180
181 size_t count = 0;
182 u32 startTime = fl::millis();
183
184 while (count < length && (fl::millis() - startTime < mTimeoutMs)) {
185 if (available() > 0) {
186 int c = read();
187 if (c != -1) {
188 buffer[count++] = static_cast<u8>(c);
189 startTime = fl::millis(); // Reset timeout on successful read
190 }
191 }
192 }
193
194 return count;
195}
196
197size_t SerialPort::readBytesUntil(char delimiter, u8* buffer, size_t length) FL_NO_EXCEPT {
198 if (!buffer || length == 0) {
199 return 0;
200 }
201
202 size_t count = 0;
203 u32 startTime = fl::millis();
204
205 while (count < length && (fl::millis() - startTime < mTimeoutMs)) {
206 if (available() > 0) {
207 int c = read();
208 if (c == -1) {
209 continue; // No data
210 }
211 if (c == delimiter) {
212 break; // Found delimiter, stop reading
213 }
214 buffer[count++] = static_cast<u8>(c);
215 startTime = fl::millis(); // Reset timeout on successful read
216 }
217 }
218
219 return count;
220}
221
223 bool negative = false;
224 long value = 0;
225 bool foundDigit = false;
226 u32 startTime = fl::millis();
227
228 // Skip non-numeric characters
229 while (fl::millis() - startTime < mTimeoutMs) {
230 if (available() > 0) {
231 int c = peek();
232 if (c == -1) {
233 continue;
234 }
235
236 // Check for sign
237 if (c == '-') {
238 negative = true;
239 read(); // Consume the sign
240 break;
241 } else if (c == '+') {
242 read(); // Consume the sign
243 break;
244 } else if (c >= '0' && c <= '9') {
245 break; // Found a digit
246 } else {
247 read(); // Skip non-numeric character
248 startTime = fl::millis(); // Reset timeout
249 }
250 }
251 }
252
253 // Parse digits
254 startTime = fl::millis();
255 while (fl::millis() - startTime < mTimeoutMs) {
256 if (available() > 0) {
257 int c = peek();
258 if (c == -1) {
259 continue;
260 }
261
262 if (c >= '0' && c <= '9') {
263 value = value * 10 + (c - '0');
264 read(); // Consume the digit
265 foundDigit = true;
266 startTime = fl::millis(); // Reset timeout
267 } else {
268 break; // Non-digit, stop parsing
269 }
270 }
271 }
272
273 return foundDigit ? (negative ? -value : value) : 0;
274}
275
277 bool negative = false;
278 long intPart = 0;
279 long fracPart = 0;
280 int fracDigits = 0;
281 bool foundDigit = false;
282 bool inFraction = false;
283 u32 startTime = fl::millis();
284
285 // Skip non-numeric characters
286 while (fl::millis() - startTime < mTimeoutMs) {
287 if (available() > 0) {
288 int c = peek();
289 if (c == -1) {
290 continue;
291 }
292
293 // Check for sign
294 if (c == '-') {
295 negative = true;
296 read(); // Consume the sign
297 break;
298 } else if (c == '+') {
299 read(); // Consume the sign
300 break;
301 } else if (c >= '0' && c <= '9') {
302 break; // Found a digit
303 } else if (c == '.') {
304 break; // Found decimal point
305 } else {
306 read(); // Skip non-numeric character
307 startTime = fl::millis(); // Reset timeout
308 }
309 }
310 }
311
312 // Parse digits (integer and fractional parts)
313 startTime = fl::millis();
314 while (fl::millis() - startTime < mTimeoutMs) {
315 if (available() > 0) {
316 int c = peek();
317 if (c == -1) {
318 continue;
319 }
320
321 if (c == '.' && !inFraction) {
322 inFraction = true;
323 read(); // Consume decimal point
324 foundDigit = true; // Decimal point counts as finding a number
325 startTime = fl::millis(); // Reset timeout
326 } else if (c >= '0' && c <= '9') {
327 if (inFraction) {
328 fracPart = fracPart * 10 + (c - '0');
329 fracDigits++;
330 } else {
331 intPart = intPart * 10 + (c - '0');
332 }
333 read(); // Consume the digit
334 foundDigit = true;
335 startTime = fl::millis(); // Reset timeout
336 } else {
337 break; // Non-digit, stop parsing
338 }
339 }
340 }
341
342 if (!foundDigit) {
343 return 0.0f;
344 }
345
346 // Calculate float value
347 float value = static_cast<float>(intPart);
348 if (fracDigits > 0) {
349 float divisor = 1.0f;
350 for (int i = 0; i < fracDigits; i++) {
351 divisor *= 10.0f;
352 }
353 value += static_cast<float>(fracPart) / divisor;
354 }
355
356 return negative ? -value : value;
357}
358
359// ============================================================================
360// Global Serial object
361// ============================================================================
362
363// Note: FL_MAYBE_UNUSED on extern declaration (in header) is enough
364// Don't use it on definition or linker won't export the symbol
365// FL_LINT_ALLOW_GLOBAL(public API surface — `fl::fl_serial` is the FastLED-side serial-port global, referenced by name from user code and from the platform serial glue. Same source-compat rationale as `fl::cout` / `fl::cin`.)
367
368} // namespace fl
FastLED chrono implementation - duration types for time measurements.
long parseInt() FL_NO_EXCEPT
Parse integer from serial input.
size_t print(const char *str) FL_NO_EXCEPT
Print string to serial output.
fl::string readString() FL_NO_EXCEPT
Read all available bytes into a string.
size_t readBytes(u8 *buffer, size_t length) FL_NO_EXCEPT
Read fixed number of bytes into buffer.
int read() FL_NO_EXCEPT
Read next byte from serial input.
int peek() FL_NO_EXCEPT
Peek at next byte without removing it from buffer.
float parseFloat() FL_NO_EXCEPT
Parse floating-point number from serial input.
size_t write(u8 byte) FL_NO_EXCEPT
Write single byte to serial output.
void end() FL_NO_EXCEPT
Close serial communication.
void setTimeout(u32 timeoutMs) FL_NO_EXCEPT
Set timeout for read operations.
fl::string readStringUntil(char delimiter) FL_NO_EXCEPT
Read characters until delimiter is found.
bool flush(u32 timeoutMs=1000) FL_NO_EXCEPT
Wait for serial output to complete.
size_t readBytesUntil(char delimiter, u8 *buffer, size_t length) FL_NO_EXCEPT
Read bytes until delimiter is found.
int available() FL_NO_EXCEPT
Check how many bytes are available to read.
size_t println() FL_NO_EXCEPT
Print newline only.
Arduino-compatible Serial class for cross-platform serial I/O.
Definition serial.h:40
fl::UISlider length("Length", 1.0f, 0.0f, 1.0f, 0.01f)
uint8_t byte
Definition midi_Defs.h:36
unsigned char u8
Definition stdint.h:131
u8 u8 fract8 blur_amount FL_NO_EXCEPT
Definition blur.h:186
void print(const char *str) FL_NO_EXCEPT
constexpr int type_rank< T >::value
SerialPort fl_serial
bool serial_ready() FL_NO_EXCEPT
fl::u32 millis() FL_NO_EXCEPT
Universal millisecond timer - returns milliseconds since system startup.
size_t write_bytes(const u8 *buffer, size_t size) FL_NO_EXCEPT
int read() FL_NO_EXCEPT
int itoa64(i64 value, char *sp, int radix) FL_NO_EXCEPT
Convert signed 64-bit integer to string buffer in given radix.
int itoa(i32 value, char *sp, int radix) FL_NO_EXCEPT
Convert signed 32-bit integer to string buffer in given radix.
bool flush(u32 timeoutMs) FL_NO_EXCEPT
expected< T, E > result
Alias for expected (Rust-style naming)
Definition result.h:31
int utoa64(u64 value, char *sp, int radix) FL_NO_EXCEPT
Convert unsigned 64-bit integer to string buffer in given radix.
void println(const char *str) FL_NO_EXCEPT
int available() FL_NO_EXCEPT
int peek() FL_NO_EXCEPT
FASTLED_FORCE_INLINE size_t strlen(const char *s) FL_NO_EXCEPT
Definition cstring.h:56
Base definition for an LED controller.
Definition crgb.hpp:179