diff --git a/documentation/variants.md b/documentation/variants.md index 743ef6f9..ff6fe1ca 100644 --- a/documentation/variants.md +++ b/documentation/variants.md @@ -107,6 +107,26 @@ The following example instantiates `Serial` and `Serial1` with each `uart0` and }; ``` +### Configure I2C devices + +The `i2cs` node defines the I2C devices to use. +It instantiate the `Wire` with the i2c device that contained in the node. +Also instantiate as `Wire1`, `Wire2`, .. `WireN` with the devices +that is after the second in the case of the array contains plural devices. + +If the `i2cs` node is not defined, Use the node labeled `arduino-i2c`. +Boards with Arduino-shield style connectors usually label `arduino-i2c` +to i2c exposed in the connector. + +The following example instantiates `Wire` and `Wire2` with each `i2c0` and `i2c1`. + +``` +/ { + zephyr,user { + i2cs = <&i2c0, &i2c1>; + }; +}; +``` ### Overlays from scratch diff --git a/libraries/Wire/Wire.cpp b/libraries/Wire/Wire.cpp index da54ba34..7fc64b03 100644 --- a/libraries/Wire/Wire.cpp +++ b/libraries/Wire/Wire.cpp @@ -5,6 +5,11 @@ */ #include +#include + +arduino::ZephyrI2C::ZephyrI2C(const struct device *i2c) : i2c_dev(i2c) +{ +} void arduino::ZephyrI2C::begin() { ring_buf_init(&rxRingBuffer.rb, sizeof(rxRingBuffer.buffer), rxRingBuffer.buffer); @@ -101,4 +106,26 @@ void arduino::ZephyrI2C::flush() {} void arduino::ZephyrI2C::onReceive(voidFuncPtrParamInt cb) {} void arduino::ZephyrI2C::onRequest(voidFuncPtr cb) {} -arduino::ZephyrI2C Wire; \ No newline at end of file +#if DT_NODE_HAS_PROP(DT_PATH(zephyr_user), i2cs) +#if (DT_PROP_LEN(DT_PATH(zephyr_user), i2cs) > 1) +#define ARDUINO_WIRE_DEFINED_0 1 +#define DECL_WIRE_0(n, p, i) arduino::ZephyrI2C Wire(DEVICE_DT_GET(DT_PHANDLE_BY_IDX(n, p, i))); +#define DECL_WIRE_N(n, p, i) arduino::ZephyrI2C Wire##i(DEVICE_DT_GET(DT_PHANDLE_BY_IDX(n, p, i))); +#define DECLARE_WIRE_N(n, p, i) \ + COND_CODE_1(ARDUINO_WIRE_DEFINED_##i, (DECL_WIRE_0(n, p, i)), (DECL_WIRE_N(n, p, i))) + +/* Declare Wire, Wire1, Wire2, ... */ +DT_FOREACH_PROP_ELEM(DT_PATH(zephyr_user), i2cs, DECLARE_WIRE_N) + +#undef DECLARE_WIRE_N +#undef DECL_WIRE_N +#undef DECL_WIRE_0 +#undef ARDUINO_WIRE_DEFINED_0 +#else // PROP_LEN(i2cs) > 1 +/* When PROP_LEN(i2cs) == 1, DT_FOREACH_PROP_ELEM work not correctly. */ +arduino::ZephyrI2C Wire(DEVICE_DT_GET(DT_PHANDLE_BY_IDX(DT_PATH(zephyr_user), i2cs, 0))); +#endif // HAS_PORP(i2cs) +/* If i2cs node is not defined, tries to use arduino_i2c */ +#elif DT_NODE_EXISTS(DT_NODELABEL(arduino_i2c)) +arduino::ZephyrI2C Wire(DEVICE_DT_GET(DT_NODELABEL(arduino_i2c))); +#endif diff --git a/libraries/Wire/Wire.h b/libraries/Wire/Wire.h index 8d021552..6e289f8c 100644 --- a/libraries/Wire/Wire.h +++ b/libraries/Wire/Wire.h @@ -17,6 +17,8 @@ namespace arduino { class ZephyrI2C : public HardwareI2C { public: + ZephyrI2C(const struct device* i2c); + virtual void begin(); virtual void end(); virtual void begin(uint8_t address); @@ -50,10 +52,27 @@ class ZephyrI2C : public HardwareI2C { uint8_t buffer[256]; }; struct rx_ring_buf rxRingBuffer; + const struct device* i2c_dev; }; } // namespace arduino +#if DT_NODE_HAS_PROP(DT_PATH(zephyr_user), i2cs) && (DT_PROP_LEN(DT_PATH(zephyr_user), i2cs) > 1) +#define ARDUINO_WIRE_DEFINED_0 1 +#define DECL_EXTERN_WIRE_0(i) extern arduino::ZephyrI2C Wire; +#define DECL_EXTERN_WIRE_N(i) extern arduino::ZephyrI2C Wire##i; +#define DECLARE_EXTERN_WIRE_N(n, p, i) \ + COND_CODE_1(ARDUINO_WIRE_DEFINED_##i, (DECL_EXTERN_WIRE_0(i)), (DECL_EXTERN_WIRE_N(i))) + +/* Declare Wire, Wire1, Wire2, ... */ +DT_FOREACH_PROP_ELEM(DT_PATH(zephyr_user), i2cs, DECLARE_EXTERN_WIRE_N) + +#undef DECLARE_EXTERN_WIRE_N +#undef DECL_EXTERN_WIRE_N +#undef DECL_EXTERN_WIRE_0 +#undef ARDUINO_WIRE_DEFINED_0 +#else extern arduino::ZephyrI2C Wire; +#endif -typedef arduino::ZephyrI2C TwoWire; \ No newline at end of file +typedef arduino::ZephyrI2C TwoWire; diff --git a/variants/arduino_mkrzero/arduino_mkrzero.overlay b/variants/arduino_mkrzero/arduino_mkrzero.overlay index 4e34d6b2..8cc3265a 100644 --- a/variants/arduino_mkrzero/arduino_mkrzero.overlay +++ b/variants/arduino_mkrzero/arduino_mkrzero.overlay @@ -45,6 +45,7 @@ io-channel-pins = <15 16 17 18 19 20 21>; serials = <&sercom5>; + i2cs = <&sercom0>; }; }; diff --git a/variants/arduino_mkrzero/arduino_mkrzero_pinmap.h b/variants/arduino_mkrzero/arduino_mkrzero_pinmap.h index a8bc14ed..11609bd0 100644 --- a/variants/arduino_mkrzero/arduino_mkrzero_pinmap.h +++ b/variants/arduino_mkrzero/arduino_mkrzero_pinmap.h @@ -10,5 +10,3 @@ #include #define LED_BUILTIN 22 - -const static struct device *i2c_dev = DEVICE_DT_GET(DT_NODELABEL(sercom0)); diff --git a/variants/arduino_nano_33_ble/arduino_nano_33_ble.overlay b/variants/arduino_nano_33_ble/arduino_nano_33_ble.overlay index 6c259771..4e0f3775 100644 --- a/variants/arduino_nano_33_ble/arduino_nano_33_ble.overlay +++ b/variants/arduino_nano_33_ble/arduino_nano_33_ble.overlay @@ -43,6 +43,7 @@ io-channel-pins = <14 15 16 17 18 19 20 21>; serials = <&uart0>; + i2cs = <&arduino_nano_i2c>; }; }; diff --git a/variants/arduino_nano_33_ble/arduino_nano_33_ble_pinmap.h b/variants/arduino_nano_33_ble/arduino_nano_33_ble_pinmap.h index b2ff6427..d1a6d6b5 100644 --- a/variants/arduino_nano_33_ble/arduino_nano_33_ble_pinmap.h +++ b/variants/arduino_nano_33_ble/arduino_nano_33_ble_pinmap.h @@ -12,5 +12,3 @@ #include #define LED_BUILTIN 13 - -const static struct device *i2c_dev = DEVICE_DT_GET(DT_NODELABEL(i2c0)); \ No newline at end of file diff --git a/variants/arduino_nano_33_ble_sense/arduino_nano_33_ble_sense.overlay b/variants/arduino_nano_33_ble_sense/arduino_nano_33_ble_sense.overlay index 6c259771..4e0f3775 100644 --- a/variants/arduino_nano_33_ble_sense/arduino_nano_33_ble_sense.overlay +++ b/variants/arduino_nano_33_ble_sense/arduino_nano_33_ble_sense.overlay @@ -43,6 +43,7 @@ io-channel-pins = <14 15 16 17 18 19 20 21>; serials = <&uart0>; + i2cs = <&arduino_nano_i2c>; }; }; diff --git a/variants/arduino_nano_33_ble_sense/arduino_nano_33_ble_sense_pinmap.h b/variants/arduino_nano_33_ble_sense/arduino_nano_33_ble_sense_pinmap.h index b2ff6427..d1a6d6b5 100644 --- a/variants/arduino_nano_33_ble_sense/arduino_nano_33_ble_sense_pinmap.h +++ b/variants/arduino_nano_33_ble_sense/arduino_nano_33_ble_sense_pinmap.h @@ -12,5 +12,3 @@ #include #define LED_BUILTIN 13 - -const static struct device *i2c_dev = DEVICE_DT_GET(DT_NODELABEL(i2c0)); \ No newline at end of file diff --git a/variants/arduino_nano_33_iot/arduino_nano_33_iot.overlay b/variants/arduino_nano_33_iot/arduino_nano_33_iot.overlay index 69af343c..99375445 100644 --- a/variants/arduino_nano_33_iot/arduino_nano_33_iot.overlay +++ b/variants/arduino_nano_33_iot/arduino_nano_33_iot.overlay @@ -45,6 +45,7 @@ io-channel-pins = <14 15 16 17 18 19 20 21>; serials = <&sercom5>; + i2cs = <&arduino_nano_i2c>; }; }; diff --git a/variants/arduino_nano_33_iot/arduino_nano_33_iot_pinmap.h b/variants/arduino_nano_33_iot/arduino_nano_33_iot_pinmap.h index df000a96..d1a6d6b5 100644 --- a/variants/arduino_nano_33_iot/arduino_nano_33_iot_pinmap.h +++ b/variants/arduino_nano_33_iot/arduino_nano_33_iot_pinmap.h @@ -12,6 +12,3 @@ #include #define LED_BUILTIN 13 - -const static struct device *i2c_dev = - DEVICE_DT_GET(DT_NODELABEL(arduino_nano_i2c)); diff --git a/variants/nrf52840dk_nrf52840/nrf52840dk_nrf52840_pinmap.h b/variants/nrf52840dk_nrf52840/nrf52840dk_nrf52840_pinmap.h index f7fbd316..b5cc2d90 100644 --- a/variants/nrf52840dk_nrf52840/nrf52840dk_nrf52840_pinmap.h +++ b/variants/nrf52840dk_nrf52840/nrf52840dk_nrf52840_pinmap.h @@ -13,6 +13,4 @@ #define LED_BUILTIN 22 -const static struct device *i2c_dev = DEVICE_DT_GET(DT_NODELABEL(arduino_i2c)); - #endif