Skip to content

Commit f28cec9

Browse files
committed
zephyrPrint: Implements arduino::Print functions
Add implementations for adruino::Print functions.
1 parent b8d9c60 commit f28cec9

File tree

3 files changed

+273
-0
lines changed

3 files changed

+273
-0
lines changed

cores/arduino/Arduino.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,4 +12,5 @@
1212
#include <zephyr/kernel.h>
1313

1414
#include <variants.h>
15+
#include <zephyrPrint.h>
1516
#include <zephyrSerial.h>

cores/arduino/zephyrPrint.cpp

Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,89 @@
44
* SPDX-License-Identifier: Apache-2.0
55
*/
66

7+
#include <zephyr/sys/cbprintf.h>
8+
79
#include <Arduino.h>
10+
#include <api/Print.h>
11+
12+
namespace arduino
13+
{
14+
namespace zephyr
15+
{
16+
17+
int cbprintf_callback(int c, void *ctx)
18+
{
19+
return reinterpret_cast<arduino::Print *>(ctx)->write((unsigned char)c);
20+
}
21+
22+
size_t wrap_cbprintf(void *ctx, const char *format, ...)
23+
{
24+
va_list ap;
25+
int rc;
26+
27+
va_start(ap, format);
28+
rc = cbvprintf(reinterpret_cast<cbprintf_cb>(cbprintf_callback), ctx, format, ap);
29+
va_end(ap);
30+
31+
return static_cast<size_t>(rc > 0 ? rc : 0);
32+
}
33+
34+
size_t print_number_base_any(void *ctx, unsigned long long ull, int base)
35+
{
36+
arduino::Print &print = *reinterpret_cast<arduino::Print *>(ctx);
37+
char string[sizeof(unsigned long long) * 8] = {0};
38+
size_t digit = 0;
39+
unsigned value;
40+
41+
if (base < 2 || base > ('~' - 'A' + 10)) {
42+
base = 10;
43+
}
44+
45+
while (ull != 0) {
46+
value = ull % base;
47+
if (value < 10) {
48+
string[sizeof(string) - digit] = '0' + value;
49+
} else {
50+
string[sizeof(string) - digit] = 'A' + (value- 10);
51+
}
52+
53+
digit++;
54+
ull /= base;
55+
}
56+
57+
return print.write(string + (sizeof(string) - digit), digit + 1);
58+
}
59+
60+
size_t print_number_base_pow2(void *ctx, unsigned long long ull, unsigned bits)
61+
{
62+
arduino::Print &print = *reinterpret_cast<arduino::Print *>(ctx);
63+
const unsigned long long mask = (1 << bits) - 1;
64+
int digit = (((sizeof(unsigned long long) * 8) + bits) / bits);
65+
int output_count = -1;
66+
unsigned value;
67+
68+
while (digit >= 0) {
69+
value = (ull & (mask << (digit * bits))) >> (digit * bits);
70+
if (value != 0 && output_count < 0) {
71+
output_count = 0;
72+
}
73+
74+
if (output_count >= 0) {
75+
if (value < 10) {
76+
print.write('0' + value);
77+
} else {
78+
print.write('A' + (value- 10));
79+
}
80+
output_count++;
81+
}
82+
digit--;
83+
}
84+
85+
return output_count;
86+
}
87+
88+
} // namespace zephyr
89+
} // namespace arduino
890

991
/*
1092
* This is the default implementation.

cores/arduino/zephyrPrint.h

Lines changed: 190 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,190 @@
1+
/*
2+
* Copyright (c) 2022 TOKITA Hiroshi <tokita.hiroshi@fujitsu.com>
3+
*
4+
* SPDX-License-Identifier: Apache-2.0
5+
*/
6+
7+
#pragma once
8+
9+
#include <zephyr/sys/cbprintf.h>
10+
11+
#include <Arduino.h>
12+
#include <api/Print.h>
13+
14+
namespace arduino
15+
{
16+
namespace zephyr
17+
{
18+
19+
int cbprintf_callback(int c, void *ctx);
20+
size_t wrap_cbprintf(void *ctx, const char *format, ...);
21+
size_t print_number_base_any(void *ctx, unsigned long long ull, int base);
22+
size_t print_number_base_pow2(void *ctx, unsigned long long ull, unsigned bits);
23+
24+
template <class Number> size_t print_number(void *ctx, Number n, const int base, const char *decfmt)
25+
{
26+
if (base == 0) {
27+
return reinterpret_cast<arduino::Print *>(ctx)->write((char)n);
28+
} else if (base == 2) {
29+
return arduino::zephyr::print_number_base_pow2(ctx, n, 1);
30+
} else if (base == 4) {
31+
return arduino::zephyr::print_number_base_pow2(ctx, n, 2);
32+
} else if (base == 8) {
33+
return arduino::zephyr::print_number_base_pow2(ctx, n, 3);
34+
} else if (base == 10) {
35+
return arduino::zephyr::wrap_cbprintf(ctx, decfmt, n);
36+
} else if (base == 16) {
37+
return arduino::zephyr::print_number_base_pow2(ctx, n, 4);
38+
} else if (base == 32) {
39+
return arduino::zephyr::print_number_base_pow2(ctx, n, 5);
40+
} else {
41+
return arduino::zephyr::print_number_base_any(ctx, n, base);
42+
}
43+
}
44+
45+
} // namespace zephyr
46+
47+
} // namespace arduino
48+
49+
inline size_t arduino::Print::print(const __FlashStringHelper *fsh)
50+
{
51+
return write(reinterpret_cast<const char *>(fsh));
52+
}
53+
54+
inline size_t arduino::Print::print(const String &s)
55+
{
56+
return write(s.c_str(), s.length());
57+
}
58+
59+
inline size_t arduino::Print::print(const char str[])
60+
{
61+
return write(str);
62+
}
63+
64+
inline size_t arduino::Print::print(char c)
65+
{
66+
return write(c);
67+
}
68+
69+
inline size_t arduino::Print::print(unsigned char n, int base)
70+
{
71+
return arduino::zephyr::print_number(this, n, base, "%hhu");
72+
}
73+
74+
inline size_t arduino::Print::print(int n, int base)
75+
{
76+
return arduino::zephyr::print_number(this, n, base, "%d");
77+
}
78+
79+
inline size_t arduino::Print::print(unsigned int n, int base)
80+
{
81+
return arduino::zephyr::print_number(this, n, base, "%u");
82+
}
83+
84+
inline size_t arduino::Print::print(long n, int base)
85+
{
86+
return arduino::zephyr::print_number(this, n, base, "%ld");
87+
}
88+
89+
inline size_t arduino::Print::print(unsigned long n, int base)
90+
{
91+
return arduino::zephyr::print_number(this, n, base, "%lu");
92+
}
93+
94+
inline size_t arduino::Print::print(long long n, int base)
95+
{
96+
return arduino::zephyr::print_number(this, n, base, "%lld");
97+
}
98+
99+
inline size_t arduino::Print::print(unsigned long long n, int base)
100+
{
101+
return arduino::zephyr::print_number(this, n, base, "%llu");
102+
}
103+
104+
inline size_t arduino::Print::print(double n, int perception)
105+
{
106+
if (perception < 10) {
107+
const char ch_perception = static_cast<char>('0' + perception);
108+
const char format[] = {'%', '.', ch_perception, 'f', '\0'};
109+
return arduino::zephyr::wrap_cbprintf(this, format, n);
110+
} else {
111+
const char ch_perception = static_cast<char>('0' + (perception % 10));
112+
const char format[] = {'%', '.', '1', ch_perception, 'f', '\0'};
113+
return arduino::zephyr::wrap_cbprintf(this, format, n);
114+
}
115+
}
116+
117+
inline size_t arduino::Print::print(const Printable &printable)
118+
{
119+
return printable.printTo(*this);
120+
}
121+
122+
inline size_t arduino::Print::println(const __FlashStringHelper *fsh)
123+
{
124+
return print(fsh) + println();
125+
}
126+
127+
inline size_t arduino::Print::println(const String &s)
128+
{
129+
return print(s) + println();
130+
}
131+
132+
inline size_t arduino::Print::println(const char str[])
133+
{
134+
return print(str) + println();
135+
}
136+
137+
inline size_t arduino::Print::println(char c)
138+
{
139+
return print(c) + println();
140+
}
141+
142+
inline size_t arduino::Print::println(unsigned char uc, int base)
143+
{
144+
return print(uc, base) + println();
145+
}
146+
147+
inline size_t arduino::Print::println(int i, int base)
148+
{
149+
return print(i, base) + println();
150+
}
151+
152+
inline size_t arduino::Print::println(unsigned int ui, int base)
153+
{
154+
return print(ui, base) + println();
155+
}
156+
157+
inline size_t arduino::Print::println(long l, int base)
158+
{
159+
return print(l, base) + println();
160+
}
161+
162+
inline size_t arduino::Print::println(unsigned long ul, int base)
163+
{
164+
return print(ul, base) + println();
165+
}
166+
167+
inline size_t arduino::Print::println(long long ll, int base)
168+
{
169+
return print(ll, base) + println();
170+
}
171+
172+
inline size_t arduino::Print::println(unsigned long long ull, int base)
173+
{
174+
return print(ull, base) + println();
175+
}
176+
177+
inline size_t arduino::Print::println(double d, int perception)
178+
{
179+
return print(d, perception) + println();
180+
}
181+
182+
inline size_t arduino::Print::println(const Printable &printable)
183+
{
184+
return print(printable) + println();
185+
}
186+
187+
inline size_t arduino::Print::println(void)
188+
{
189+
return write("\r\n", 2);
190+
}

0 commit comments

Comments
 (0)