Skip to content

libraries: Wire: Instantiate Wire following dts configuration #62

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Nov 2, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 20 additions & 0 deletions documentation/variants.md
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
29 changes: 28 additions & 1 deletion libraries/Wire/Wire.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,11 @@
*/

#include <Wire.h>
#include <zephyr/sys/util_macro.h>

arduino::ZephyrI2C::ZephyrI2C(const struct device *i2c) : i2c_dev(i2c)
{
}

void arduino::ZephyrI2C::begin() {
ring_buf_init(&rxRingBuffer.rb, sizeof(rxRingBuffer.buffer), rxRingBuffer.buffer);
Expand Down Expand Up @@ -101,4 +106,26 @@ void arduino::ZephyrI2C::flush() {}
void arduino::ZephyrI2C::onReceive(voidFuncPtrParamInt cb) {}
void arduino::ZephyrI2C::onRequest(voidFuncPtr cb) {}

arduino::ZephyrI2C Wire;
#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
21 changes: 20 additions & 1 deletion libraries/Wire/Wire.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -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;
typedef arduino::ZephyrI2C TwoWire;
1 change: 1 addition & 0 deletions variants/arduino_mkrzero/arduino_mkrzero.overlay
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@
io-channel-pins = <15 16 17 18 19 20 21>;

serials = <&sercom5>;
i2cs = <&sercom0>;
};
};

Expand Down
2 changes: 0 additions & 2 deletions variants/arduino_mkrzero/arduino_mkrzero_pinmap.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,5 +10,3 @@
#include <zephyr/drivers/i2c.h>

#define LED_BUILTIN 22

const static struct device *i2c_dev = DEVICE_DT_GET(DT_NODELABEL(sercom0));
1 change: 1 addition & 0 deletions variants/arduino_nano_33_ble/arduino_nano_33_ble.overlay
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@
io-channel-pins = <14 15 16 17 18 19 20 21>;

serials = <&uart0>;
i2cs = <&arduino_nano_i2c>;
};
};

Expand Down
2 changes: 0 additions & 2 deletions variants/arduino_nano_33_ble/arduino_nano_33_ble_pinmap.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,5 +12,3 @@
#include <zephyr/device.h>

#define LED_BUILTIN 13

const static struct device *i2c_dev = DEVICE_DT_GET(DT_NODELABEL(i2c0));
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@
io-channel-pins = <14 15 16 17 18 19 20 21>;

serials = <&uart0>;
i2cs = <&arduino_nano_i2c>;
};
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,5 +12,3 @@
#include <zephyr/device.h>

#define LED_BUILTIN 13

const static struct device *i2c_dev = DEVICE_DT_GET(DT_NODELABEL(i2c0));
1 change: 1 addition & 0 deletions variants/arduino_nano_33_iot/arduino_nano_33_iot.overlay
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@
io-channel-pins = <14 15 16 17 18 19 20 21>;

serials = <&sercom5>;
i2cs = <&arduino_nano_i2c>;
};
};

Expand Down
3 changes: 0 additions & 3 deletions variants/arduino_nano_33_iot/arduino_nano_33_iot_pinmap.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,3 @@
#include <zephyr/device.h>

#define LED_BUILTIN 13

const static struct device *i2c_dev =
DEVICE_DT_GET(DT_NODELABEL(arduino_nano_i2c));
2 changes: 0 additions & 2 deletions variants/nrf52840dk_nrf52840/nrf52840dk_nrf52840_pinmap.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,4 @@

#define LED_BUILTIN 22

const static struct device *i2c_dev = DEVICE_DT_GET(DT_NODELABEL(arduino_i2c));

#endif