Skip to content

Commit 8f10077

Browse files
committed
treewide: Merge remote-tracking branch 'arduino/main' into reunite-with-arduino-repo
Conflicts: .gitignore CMakeLists.txt README.md cores/arduino/Arduino.h cores/arduino/main.cpp cores/arduino/zephyrCommon.cpp cores/arduino/zephyrPrint.cpp cores/arduino/zephyrPrint.h cores/arduino/zephyrSerial.cpp cores/arduino/zephyrSerial.h documentation/variants.md samples/analog_input/CMakeLists.txt samples/attach_interrupt/CMakeLists.txt samples/blinky_arduino/CMakeLists.txt samples/button_press_led/CMakeLists.txt samples/fade/CMakeLists.txt samples/hello_arduino/CMakeLists.txt samples/i2cdemo/CMakeLists.txt samples/serial_event/CMakeLists.txt samples/spi_controller/CMakeLists.txt samples/threads_arduino/CMakeLists.txt variants/arduino_nano_33_ble_nrf52840_sense/variant.h west.yml Signed-off-by: TOKITA Hiroshi <tokita.hiroshi@gmail.com>
2 parents dc7b335 + cae7a3e commit 8f10077

File tree

155 files changed

+14825
-257
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

155 files changed

+14825
-257
lines changed

.gitignore

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,11 @@
1+
/build/
2+
/distrib/
3+
/firmwares/*
4+
/venv/
5+
llext-edk/
6+
cflags.txt
7+
cxxflags.txt
8+
includes.txt
9+
syms-dynamic.ld
10+
syms-static.ld
111
rust/Cargo.lock

CMakeLists.txt

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,11 @@ if (CONFIG_ARDUINO_API)
1313
set(variant_dir variants/default)
1414
endif()
1515

16-
add_subdirectory(cores)
17-
add_subdirectory(libraries)
18-
zephyr_include_directories(${variant_dir})
16+
if (CONFIG_ARDUINO_API AND NOT CONFIG_LLEXT)
17+
add_subdirectory(cores)
18+
add_subdirectory(libraries)
19+
zephyr_include_directories(${variant_dir})
20+
endif()
1921

2022
if (CONFIG_USE_ARDUINO_API_RUST_IMPLEMENTATION)
2123
# quote from https://github.com/zephyrproject-rtos/zephyr-lang-rust/blob/main/CMakeLists.txt

Kconfig

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,3 +42,23 @@ config ARDUINO_MAX_TONES
4242
If set to a negative value, the maximum number will be determined from the
4343
system's digital pin configuration.
4444
endif
45+
46+
if USB_DEVICE_STACK_NEXT
47+
48+
config USB_DEVICE_PRODUCT
49+
string "USB Device Product"
50+
default "Arduino Generic board"
51+
52+
config USB_DEVICE_MANUFACTURER
53+
string "USB Device Manufacturer"
54+
default "Arduino"
55+
56+
config USB_DEVICE_VID
57+
hex "USB Device Vendor ID"
58+
default 0x2341
59+
60+
config USB_DEVICE_PID
61+
hex "USB Device Product ID"
62+
default 0x0001
63+
64+
endif

README.gsoc.md

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
# GSoC 2022 Project: Arduino Core API module for Zephyr
2+
3+
![](https://dhruvag2000.github.io/Blog-GSoC22/assets/images/website_header.png)
4+
5+
The **Arduino Core API** module for zephyr leverages the power of Zephyr under an Arduino-C++ style abtraction layer thus helping zephyr new-comers to start using it without worrying about learning about new APIs and libraries. See the project documentation folder for detailed documentation on these topics:
6+
7+
* [Using external Arduino Libraries](/documentation/arduino_libs.md)
8+
* [Adding custom boards/ variants](/documentation/variants.md)
9+
10+
## Adding Arduino Core API to Zephyr
11+
12+
* **Pre requisites:** It is assumed that you have zephyrproject configured and installed on your system as per the official [Get Started Guide](https://docs.zephyrproject.org/latest/develop/getting_started/index.html). The recommended path to install is `~/zephyrproject` as specified in the guide. If you have zephyr installed in a custom path you may need to make changes to the CMakeLists.txt file in the sample code directory when building these samples.
13+
14+
* Add following entry to `west.yml` file in `manifest/projects` subtree of Zephyr:
15+
```
16+
# Arduino API repository.
17+
- name: Arduino-Core-Zephyr
18+
path: modules/lib/Arduino-Zephyr-API
19+
revision: main
20+
url: https://github.com/zephyrproject-rtos/gsoc-2022-arduino-core
21+
```
22+
23+
* Then, clone the repository by running
24+
25+
```sh
26+
west update
27+
```
28+
29+
* **Note:** For ***Linux users only*** there exists an ``install.sh`` script in this project that can be run to quickly link the ArduinoCore-API to this module.
30+
If you are able to run that script successfully then you can skip the next steps.
31+
32+
* To "complete" the core you need to copy or symlink the api folder from the [ArduinoCore-API](https://github.com/arduino/ArduinoCore-API.git) repo to the target's ``cores/arduino`` folder:
33+
```sh
34+
$ git clone git@github.com:arduino/ArduinoCore-API # Any location
35+
$ ln -s /<your>/<location>/ArduinoCore-API/api cores/arduino/.
36+
```
37+
The `cores` folder can be found at `~/zephyrproject/modules/lib/Arduino-Zephyr-API/cores`.
38+
39+
**Known Bug(s):**
40+
41+
__NOTE:__ You can skip this step as well if you ran ``install.sh``.
42+
43+
**Maintainers**:
44+
- [DhruvaG2000](https://github.com/DhruvaG2000)
45+
- [soburi](https://github.com/soburi)
46+
- [szczys](https://github.com/szczys)
47+
- [beriberikix](https://github.com/beriberikix)
48+
- [alvarowolfx](https://github.com/alvarowolfx)
49+
50+
## License
51+
Please note that the current license is Apache 2. Previously it was LGPL 2.1 but after careful review it was determined that no LGPL code or derivates was used and the more permissive license was chosen.
52+
53+
**Additional Links**
54+
* [Official Project Blog](https://dhruvag2000.github.io/Blog-GSoC22/)
55+
* Golioth's Article: [Zephyr + Arduino: a Google Summer of Code story](https://blog.golioth.io/zephyr-arduino-a-google-summer-of-code-story/)

cores/arduino/Arduino.h

Lines changed: 49 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,12 +12,16 @@
1212
#include <zephyr/drivers/gpio.h>
1313
#include <zephyr/drivers/pwm.h>
1414
#include <zephyr/drivers/adc.h>
15+
#include <zephyr/drivers/dac.h>
1516
#include <zephyr/drivers/i2c.h>
17+
#include <math.h>
1618

19+
#if DT_PROP_LEN(DT_PATH(zephyr_user), digital_pin_gpios) > 0
20+
/* Note: DT_REG_ADDR needs an expanded argument or it will not work properly */
21+
#define DIGITAL_PIN_MATCHES(dev_pha, pin, dev, num) \
22+
(((dev == DT_REG_ADDR(dev_pha)) && (num == pin)) ? 1 : 0)
1723
#define DIGITAL_PIN_EXISTS(n, p, i, dev, num) \
18-
(((dev == DT_REG_ADDR(DT_PHANDLE_BY_IDX(n, p, i))) && (num == DT_PHA_BY_IDX(n, p, i, pin))) ? \
19-
1 : \
20-
0)
24+
DIGITAL_PIN_MATCHES(DT_PHANDLE_BY_IDX(n, p, i), DT_PHA_BY_IDX(n, p, i, pin), dev, num)
2125

2226
/* Check all pins are defined only once */
2327
#define DIGITAL_PIN_CHECK_UNIQUE(i, _) \
@@ -31,6 +35,12 @@
3135
#endif
3236

3337
#undef DIGITAL_PIN_CHECK_UNIQUE
38+
#endif
39+
40+
// Helper macro to get Arduino pin number from device tree alias
41+
#define DIGITAL_PIN_GPIOS_FIND_NODE(node) \
42+
DIGITAL_PIN_GPIOS_FIND_PIN(DT_REG_ADDR(DT_PHANDLE_BY_IDX(node, gpios, 0)), \
43+
DT_PHA_BY_IDX(node, gpios, 0, pin))
3444

3545
/* Return the index of it if matched, oterwise return 0 */
3646
#define LED_BUILTIN_INDEX_BY_REG_AND_PINNUM(n, p, i, dev, num) \
@@ -79,7 +89,9 @@
7989
* enum digitalPins { D0, D1, ... LED... NUM_OF_DIGITAL_PINS };
8090
*/
8191
enum digitalPins {
92+
#if DT_PROP_LEN(DT_PATH(zephyr_user), digital_pin_gpios) > 0
8293
DT_FOREACH_PROP_ELEM_SEP(DT_PATH(zephyr_user), digital_pin_gpios, DN_ENUMS, (, )),
94+
#endif
8395
NUM_OF_DIGITAL_PINS
8496
};
8597

@@ -93,19 +105,53 @@ enum analogPins {
93105
DT_FOREACH_PROP_ELEM(DT_PATH(zephyr_user), adc_pin_gpios, AN_ENUMS)
94106
};
95107

108+
// We provide analogReadResolution APIs
109+
void analogReadResolution(int bits);
110+
111+
#endif
112+
113+
#ifdef CONFIG_DAC
114+
115+
#undef DAC0
116+
#undef DAC1
117+
#undef DAC2
118+
#undef DAC3
119+
#define DAC_ENUMS(n, p, i) DAC##i = i,
120+
121+
enum dacPins {
122+
DT_FOREACH_PROP_ELEM(DT_PATH(zephyr_user), dac_channels, DAC_ENUMS) NUM_OF_DACS
123+
};
124+
96125
#endif
97126

98127
void interrupts(void);
99128
void noInterrupts(void);
100129

101130
int digitalPinToInterrupt(pin_size_t pin);
102131

132+
#define digitalPinToPort(x) (x)
133+
#define digitalPinToBitMask(x) (x)
134+
#define portOutputRegister(x) (x)
135+
#define portInputRegister(x) (x)
136+
137+
void analogReadResolution(int bits);
138+
void analogWriteResolution(int bits);
139+
103140
#include <variant.h>
104141

105142
#if !defined(LED_BUILTIN) && defined(ZARD_LED_BUILTIN)
106143
#define LED_BUILTIN ZARD_LED_BUILTIN
107144
#endif // LED_BUILTIN
108145

109146
#ifdef __cplusplus
147+
#include <SerialUSB.h>
110148
#include <zephyrSerial.h>
149+
#include <strings.h>
150+
#include <api/itoa.h>
151+
#include <time_macros.h>
152+
#include <overloads.h>
153+
154+
// Allow namespace-less operations if Arduino.h is included
155+
using namespace arduino;
156+
111157
#endif // __cplusplus

cores/arduino/CMakeLists.txt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@ if(NOT DEFINED ARDUINO_BUILD_PATH)
1313

1414
zephyr_sources(zephyrSerial.cpp)
1515
zephyr_sources(zephyrCommon.cpp)
16+
zephyr_sources(USB.cpp)
17+
zephyr_sources(itoa.cpp)
1618

1719
if(CONFIG_USE_ARDUINO_API_RUST_IMPLEMENTATION)
1820
zephyr_sources(zephyrPrint.cpp)
@@ -21,6 +23,7 @@ endif()
2123

2224
if(DEFINED CONFIG_ARDUINO_ENTRY)
2325
zephyr_sources(main.cpp)
26+
zephyr_sources(threads.cpp)
2427
endif()
2528

2629
endif()

cores/arduino/SerialUSB.h

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
/*
2+
* Copyright (c) Arduino s.r.l. and/or its affiliated companies
3+
*
4+
* SPDX-License-Identifier: Apache-2.0
5+
*/
6+
7+
#pragma once
8+
9+
#include <zephyrSerial.h>
10+
11+
#if defined(CONFIG_USB_DEVICE_STACK_NEXT)
12+
#include <zephyr/usb/usbd.h>
13+
extern "C" struct usbd_context *usbd_init_device(usbd_msg_cb_t msg_cb);
14+
#endif
15+
16+
namespace arduino {
17+
18+
class SerialUSB_ : public ZephyrSerial {
19+
20+
public:
21+
SerialUSB_(const struct device *dev) : ZephyrSerial(dev) {
22+
}
23+
24+
void begin(unsigned long baudrate, uint16_t config);
25+
26+
void begin(unsigned long baudrate) {
27+
begin(baudrate, SERIAL_8N1);
28+
}
29+
30+
operator bool() override;
31+
size_t write(const uint8_t *buffer, size_t size) override;
32+
33+
size_t write(const uint8_t data) override {
34+
return write(&data, 1);
35+
}
36+
37+
void flush() override;
38+
39+
protected:
40+
uint32_t dtr = 0;
41+
uint32_t baudrate;
42+
static void baudChangeHandler(const struct device *dev, uint32_t rate);
43+
44+
private:
45+
bool started = false;
46+
47+
#if defined(CONFIG_USB_DEVICE_STACK_NEXT)
48+
struct usbd_context *_usbd;
49+
int enable_usb_device_next();
50+
static void usbd_next_cb(struct usbd_context *const ctx, const struct usbd_msg *msg);
51+
static int usb_disable();
52+
#endif
53+
};
54+
} // namespace arduino
55+
56+
#if (DT_NODE_HAS_PROP(DT_PATH(zephyr_user), cdc_acm) && \
57+
(CONFIG_USB_CDC_ACM || CONFIG_USBD_CDC_ACM_CLASS))
58+
extern arduino::SerialUSB_ Serial;
59+
#endif

cores/arduino/USB.cpp

Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
/*
2+
* Copyright (c) Arduino s.r.l. and/or its affiliated companies
3+
*
4+
* SPDX-License-Identifier: Apache-2.0
5+
*/
6+
7+
#include <zephyr/devicetree.h>
8+
#include <zephyr/drivers/uart.h>
9+
#include <zephyr/drivers/uart/cdc_acm.h>
10+
#include <zephyr/usb/usb_device.h>
11+
#include <SerialUSB.h>
12+
13+
#if ((DT_NODE_HAS_PROP(DT_PATH(zephyr_user), cdc_acm)) && \
14+
(CONFIG_USB_CDC_ACM || CONFIG_USBD_CDC_ACM_CLASS))
15+
const struct device *const usb_dev =
16+
DEVICE_DT_GET(DT_PHANDLE_BY_IDX(DT_PATH(zephyr_user), cdc_acm, 0));
17+
18+
void __attribute__((weak)) _on_1200_bps() {
19+
NVIC_SystemReset();
20+
}
21+
22+
void arduino::SerialUSB_::baudChangeHandler(const struct device *dev, uint32_t rate) {
23+
(void)dev; // unused
24+
if (rate == 1200) {
25+
usb_disable();
26+
_on_1200_bps();
27+
}
28+
}
29+
30+
#if defined(CONFIG_USB_DEVICE_STACK_NEXT)
31+
int arduino::SerialUSB_::usb_disable() {
32+
// To avoid Cannot perform port reset: 1200-bps touch: setting DTR to OFF: protocol error
33+
k_sleep(K_MSEC(100));
34+
return usbd_disable(Serial._usbd);
35+
}
36+
37+
void arduino::SerialUSB_::usbd_next_cb(struct usbd_context *const ctx, const struct usbd_msg *msg) {
38+
if (usbd_can_detect_vbus(ctx)) {
39+
if (msg->type == USBD_MSG_VBUS_READY) {
40+
usbd_enable(ctx);
41+
}
42+
43+
if (msg->type == USBD_MSG_VBUS_REMOVED) {
44+
usbd_disable(ctx);
45+
}
46+
}
47+
48+
if (msg->type == USBD_MSG_CDC_ACM_LINE_CODING) {
49+
uint32_t baudrate;
50+
uart_line_ctrl_get(Serial.uart, UART_LINE_CTRL_BAUD_RATE, &baudrate);
51+
Serial.baudChangeHandler(nullptr, baudrate);
52+
}
53+
}
54+
55+
int arduino::SerialUSB_::enable_usb_device_next(void) {
56+
int err;
57+
58+
_usbd = usbd_init_device(arduino::SerialUSB_::usbd_next_cb);
59+
if (_usbd == NULL) {
60+
return -ENODEV;
61+
}
62+
63+
if (!usbd_can_detect_vbus(_usbd)) {
64+
err = usbd_enable(_usbd);
65+
if (err) {
66+
return err;
67+
}
68+
}
69+
return 0;
70+
}
71+
#endif /* defined(CONFIG_USB_DEVICE_STACK_NEXT) */
72+
73+
void arduino::SerialUSB_::begin(unsigned long baudrate, uint16_t config) {
74+
if (!started) {
75+
#ifndef CONFIG_USB_DEVICE_STACK_NEXT
76+
usb_enable(NULL);
77+
#ifndef CONFIG_CDC_ACM_DTE_RATE_CALLBACK_SUPPORT
78+
#warning "Can't read CDC baud change, please enable CONFIG_CDC_ACM_DTE_RATE_CALLBACK_SUPPORT"
79+
#else
80+
cdc_acm_dte_rate_callback_set(usb_dev, SerialUSB_::baudChangeHandler);
81+
#endif
82+
#else
83+
enable_usb_device_next();
84+
#endif
85+
ZephyrSerial::begin(baudrate, config);
86+
started = true;
87+
}
88+
}
89+
90+
arduino::SerialUSB_::operator bool() {
91+
uart_line_ctrl_get(uart, UART_LINE_CTRL_DTR, &dtr);
92+
return dtr;
93+
}
94+
95+
size_t arduino::SerialUSB_::write(const uint8_t *buffer, size_t size) {
96+
if (!Serial) {
97+
return 0;
98+
}
99+
return arduino::ZephyrSerial::write(buffer, size);
100+
}
101+
102+
void arduino::SerialUSB_::flush() {
103+
if (!Serial) {
104+
return;
105+
}
106+
arduino::ZephyrSerial::flush();
107+
}
108+
109+
arduino::SerialUSB_ Serial(usb_dev);
110+
#endif

0 commit comments

Comments
 (0)