|
1 | 1 | /* |
2 | 2 | * Copyright (c) 2022 Dhruva Gole |
| 3 | + * Copyright (c) Arduino s.r.l. and/or its affiliated companies |
3 | 4 | * |
4 | 5 | * SPDX-License-Identifier: Apache-2.0 |
5 | 6 | */ |
@@ -115,26 +116,90 @@ class ZephyrSerial : public HardwareSerial { |
115 | 116 |
|
116 | 117 | } // namespace arduino |
117 | 118 |
|
118 | | -#if DT_NODE_HAS_PROP(DT_PATH(zephyr_user), serials) |
119 | | -#if !(DT_NODE_HAS_PROP(DT_PATH(zephyr_user), cdc_acm) && \ |
120 | | - (CONFIG_USB_CDC_ACM || CONFIG_USBD_CDC_ACM_CLASS)) |
121 | | -// If CDC USB, use that object as Serial (and SerialUSB) |
122 | | -extern arduino::ZephyrSerial Serial; |
| 119 | +/* Return the index of it if matched, oterwise return an empty string. */ |
| 120 | +#define ZARD_SERIAL_MATCH(n, p, i, node) \ |
| 121 | + COND_CODE_1(DT_SAME_NODE(DT_PHANDLE_BY_IDX(n, p, i), node), (i), ()) |
| 122 | + |
| 123 | +/* Only matched device returns non-empty value, so the overall expansion is |
| 124 | + * matched device's index. |
| 125 | + */ |
| 126 | +#define ZARD_SERIAL_INDEXOF(node) \ |
| 127 | + DT_FOREACH_PROP_ELEM_VARGS(DT_PATH(zephyr_user), serials, ZARD_SERIAL_MATCH, node) |
| 128 | + |
| 129 | +/* Serial object associated with the Zephyr console. */ |
| 130 | +#define ARDUINO_CONSOLE_SERIAL ZARD_SERIAL_NAME(ZARD_SERIAL_INDEXOF(DT_CHOSEN(zephyr_console))) |
| 131 | + |
| 132 | +/* Serial object associated with the first HW serial (usually on D0/D1). */ |
| 133 | +#define ARDUINO_HARDWARE_SERIAL ZARD_SERIAL_NAME(0) |
| 134 | + |
| 135 | +#if DT_NODE_HAS_PROP(DT_PATH(zephyr_user), cdc_acm_serial) |
| 136 | +/* Devicetree requires a SerialUSB object for 'Serial'. */ |
| 137 | +#define ZARD_SKIP_FIRST_SERIAL 1 |
| 138 | +#if (CONFIG_USB_CDC_ACM || CONFIG_USBD_CDC_ACM_CLASS) |
| 139 | +/* SerialUSB can be compiled in the project. */ |
| 140 | +#define ZARD_FIRST_SERIAL_IS_SERIALUSB 1 |
| 141 | +#else |
| 142 | +/* SerialUSB is required but no driver was enabled for the USB CDC ACM device. |
| 143 | + * Define a stub Serial object to avoid build errors. |
| 144 | + */ |
| 145 | +#define ZARD_FIRST_SERIAL_IS_STUB 1 |
| 146 | +#endif |
| 147 | +#endif |
| 148 | + |
| 149 | +#if DT_NODE_HAS_PROP(DT_PATH(zephyr_user), arduino_router_serial) |
| 150 | +/* If the board has an arduino,router-serial node, and the currently used |
| 151 | + * library has the support, then the 'Serial' object is actually the same as |
| 152 | + * the Monitor object in the Arduino_RouterBridge library. |
| 153 | + */ |
| 154 | +#define ZARD_SKIP_FIRST_SERIAL 1 |
| 155 | +#define ZARD_FIRST_SERIAL_IS_ARDUINO_ROUTER 1 |
| 156 | +#define ARDUINO_ROUTER_PHANDLE DT_PROP(DT_PATH(zephyr_user), arduino_router_serial) |
| 157 | +#define ARDUINO_ROUTER_SERIAL ZARD_SERIAL_NAME(ZARD_SERIAL_INDEXOF(ARDUINO_ROUTER_PHANDLE)) |
123 | 158 | #endif |
124 | | -#if (DT_PROP_LEN(DT_PATH(zephyr_user), serials) > 1) |
125 | | -#define SERIAL_DEFINED_0 1 |
126 | | -#define EXTERN_SERIAL_N(i) extern arduino::ZephyrSerial Serial##i; |
127 | | -#define DECLARE_EXTERN_SERIAL_N(n, p, i) COND_CODE_1(SERIAL_DEFINED_##i, (), (EXTERN_SERIAL_N(i))) |
128 | 159 |
|
129 | | -/* Declare Serial1, Serial2, ... */ |
130 | | -DT_FOREACH_PROP_ELEM(DT_PATH(zephyr_user), serials, DECLARE_EXTERN_SERIAL_N) |
| 160 | +/* Name of a Serial object for a given index. */ |
| 161 | +#define ZARD_SERIAL_NAME(n) CONCAT(Serial, ZARD_SERIAL_STEM(n)) |
| 162 | + |
| 163 | +/* |
| 164 | + * Determine the number of generic ZephyrSerial objects to instantiate. |
| 165 | + */ |
| 166 | + |
| 167 | +#if DT_NODE_HAS_PROP(DT_PATH(zephyr_user), serials) |
| 168 | +/* The array property; the total number is the length of the array. */ |
| 169 | +#define ZARD_GENERIC_SERIAL_COUNT DT_PROP_LEN(DT_PATH(zephyr_user), serials) |
131 | 170 |
|
132 | | -#undef DECLARE_EXTERN_SERIAL_N |
133 | | -#undef EXTERN_SERIAL_N |
134 | | -#undef SERIAL_DEFINED_0 |
| 171 | +#elif DT_NODE_HAS_STATUS_OKAY(DT_NODELABEL(arduino_serial)) |
| 172 | +/* A single node with compatible "arduino,serial" is present. */ |
| 173 | +#define ZARD_GENERIC_SERIAL_COUNT 1 |
| 174 | + |
| 175 | +#elif ZARD_SKIP_FIRST_SERIAL |
| 176 | +/* Only a special Serial is present. */ |
| 177 | +#define ZARD_GENERIC_SERIAL_COUNT 0 |
| 178 | + |
| 179 | +#else |
| 180 | +/* Neither 'serials' property, nor 'arduino,serial' node, nor a special Serial |
| 181 | + * is present. Define a stub Serial object to avoid build errors. |
| 182 | + */ |
| 183 | +#define ZARD_GENERIC_SERIAL_COUNT 0 |
| 184 | +#define ZARD_SKIP_FIRST_SERIAL 1 |
| 185 | +#define ZARD_FIRST_SERIAL_IS_STUB 1 |
135 | 186 | #endif |
136 | | -#elif DT_NODE_HAS_STATUS(DT_NODELABEL(arduino_serial), okay) |
137 | | -extern arduino::ZephyrSerial Serial; |
| 187 | + |
| 188 | +#if ZARD_SKIP_FIRST_SERIAL |
| 189 | +// Map index 0 to 'Serial1', index 1 to 'Serial2', etc. |
| 190 | +#define ZARD_SERIAL_STEM(i) UTIL_INC(i) |
138 | 191 | #else |
| 192 | +// Map index 0 to 'Serial', index 1 to 'Serial1', etc. |
| 193 | +#define ZARD_SERIAL_STEM(i) COND_CODE_0(i, (), (i)) |
| 194 | +#endif |
| 195 | + |
| 196 | +#if ZARD_FIRST_SERIAL_IS_STUB |
139 | 197 | extern arduino::ZephyrSerialStub Serial; |
140 | 198 | #endif |
| 199 | + |
| 200 | +#if ZARD_GENERIC_SERIAL_COUNT > 0 |
| 201 | +/* Declare all generic ZephyrSerial objects */ |
| 202 | +#define DECLARE_SERIAL_N(n, s) extern arduino::ZephyrSerial ZARD_SERIAL_NAME(n); |
| 203 | +LISTIFY(ZARD_GENERIC_SERIAL_COUNT, DECLARE_SERIAL_N, ()) |
| 204 | +#undef DECLARE_SERIAL_N |
| 205 | +#endif |
0 commit comments