Skip to content

Commit 5142275

Browse files
committed
feat/i2c: Add I2C wrapper functions
* Tested with a custom example for ADXL345 which can be found here: DhruvaG2000/Arduino-Core-Zephyr#5 (comment) * Follows latest licensing and directory structure * uses ringBuffer * TODO: Testing for multiple byte read/write * TODO: Add i2c example if required Signed-off-by: Dhruva Gole <[email protected]> wire.cpp: implement write as per suggestion wire.cpp: implement ZephyrI2C::available wire.cpp: implement ZephyrI2C::peek Wire.cpp: Change the way we include Wire.h to <> Signed-off-by: Dhruva Gole <[email protected]>
1 parent ede331f commit 5142275

File tree

5 files changed

+167
-1
lines changed

5 files changed

+167
-1
lines changed

CMakeLists.txt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
# SPDX-License-Identifier: Apache-2.0
22

33
add_subdirectory(cores)
4-
add_subdirectory(variants)
4+
add_subdirectory(variants)
5+
add_subdirectory(libraries)

libraries/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
add_subdirectory(Wire)

libraries/Wire/CMakeLists.txt

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
# SPDX-License-Identifier: Apache-2.0
2+
zephyr_include_directories(.)
3+
4+
if(NOT DEFINED ARDUINO_BUILD_PATH)
5+
6+
zephyr_sources(Wire.cpp)
7+
8+
endif()

libraries/Wire/Wire.cpp

Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
#include <Wire.h>
2+
3+
void arduino::ZephyrI2C::begin() {
4+
i2c_dev = DEVICE_DT_GET(DT_NODELABEL(i2c0));
5+
ring_buf_init(&rxRingBuffer.rb, sizeof(rxRingBuffer.buffer), rxRingBuffer.buffer);
6+
}
7+
8+
void arduino::ZephyrI2C::begin(uint8_t slaveAddr) {
9+
10+
}
11+
12+
void arduino::ZephyrI2C::end() {}
13+
14+
void arduino::ZephyrI2C::setClock(uint32_t freq) {}
15+
16+
void arduino::ZephyrI2C::beginTransmission(uint8_t address) { // TODO for ADS1115
17+
_address = address;
18+
usedTxBuffer = 0;
19+
}
20+
21+
uint8_t arduino::ZephyrI2C::endTransmission(bool stopBit) {
22+
int ret = i2c_write(i2c_dev, txBuffer, usedTxBuffer, _address);
23+
if (ret) {
24+
return 1; // fail
25+
}
26+
return 0;
27+
}
28+
29+
uint8_t arduino::ZephyrI2C::endTransmission(void) { // TODO for ADS1115
30+
return endTransmission(true);
31+
}
32+
33+
size_t arduino::ZephyrI2C::requestFrom(uint8_t address, size_t len,
34+
bool stopBit) {
35+
int ret = i2c_read(i2c_dev, rxRingBuffer.buffer, len, address);
36+
if (ret != 0)
37+
{
38+
printk("\n\nERR: i2c burst read fails\n\n\n");
39+
return 0;
40+
}
41+
ret = ring_buf_put(&rxRingBuffer.rb, rxRingBuffer.buffer, len);
42+
if (ret == 0)
43+
{
44+
printk("\n\nERR: buff put fails\n\n\n");
45+
return 0;
46+
}
47+
return len;
48+
}
49+
50+
size_t arduino::ZephyrI2C::requestFrom(uint8_t address, size_t len) { // TODO for ADS1115
51+
return requestFrom(address, len, true);
52+
}
53+
54+
size_t arduino::ZephyrI2C::write(uint8_t data) { // TODO for ADS1115
55+
txBuffer[usedTxBuffer++] = data;
56+
return 1;
57+
}
58+
59+
size_t arduino::ZephyrI2C::write(const uint8_t *buffer, size_t size) {
60+
if (usedTxBuffer + size > 256) {
61+
size = 256 - usedTxBuffer;
62+
}
63+
memcpy(txBuffer + usedTxBuffer, buffer, size);
64+
usedTxBuffer += size;
65+
return size;
66+
}
67+
68+
int arduino::ZephyrI2C::read() {
69+
uint8_t buf[1];
70+
if (ring_buf_peek(&rxRingBuffer.rb, buf, 1) > 0) {
71+
int ret = ring_buf_get(&rxRingBuffer.rb, buf, 1);
72+
if (ret == 0) {
73+
printk("\n\nERR: buff empty\n\n\n");
74+
return 0;
75+
}
76+
return (int)buf[0];
77+
}
78+
return rxBuffer[0];
79+
}
80+
81+
int arduino::ZephyrI2C::available() { // TODO for ADS1115
82+
return !ring_buf_is_empty(&rxRingBuffer.rb); // ret 0 if empty
83+
}
84+
85+
int arduino::ZephyrI2C::peek() {
86+
uint8_t buf[1];
87+
int bytes_read = ring_buf_peek(&rxRingBuffer.rb, buf, 1);
88+
if (bytes_read == 0){
89+
return 0;
90+
}
91+
return (int)buf[0];
92+
}
93+
94+
void arduino::ZephyrI2C::flush() {}
95+
96+
void arduino::ZephyrI2C::onReceive(voidFuncPtrParamInt cb) {}
97+
void arduino::ZephyrI2C::onRequest(voidFuncPtr cb) {}
98+
99+
arduino::ZephyrI2C Wire;

libraries/Wire/Wire.h

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
#pragma once
2+
3+
#include "api/ArduinoAPI.h"
4+
#include "api/HardwareI2C.h"
5+
#include "api/Print.h"
6+
#include <zephyr/drivers/i2c.h>
7+
#include <zephyr/device.h>
8+
#include <zephyr/sys/ring_buffer.h>
9+
10+
typedef void (*voidFuncPtrParamInt)(int);
11+
12+
namespace arduino {
13+
14+
class ZephyrI2C : public HardwareI2C {
15+
public:
16+
virtual void begin();
17+
virtual void end();
18+
virtual void begin(uint8_t address);
19+
virtual void setClock(uint32_t freq);
20+
21+
virtual void beginTransmission(uint8_t address);
22+
virtual uint8_t endTransmission(bool stopBit);
23+
virtual uint8_t endTransmission(void);
24+
25+
virtual size_t requestFrom(uint8_t address, size_t len, bool stopBit);
26+
virtual size_t requestFrom(uint8_t address, size_t len);
27+
28+
virtual void onReceive(void (*)(int));
29+
virtual void onRequest(void (*)(void));
30+
31+
virtual size_t write(uint8_t data);
32+
virtual size_t write(int data) { return write((uint8_t)data); };
33+
virtual size_t write(const uint8_t *buffer, size_t size);
34+
using Print::write;
35+
virtual int read();
36+
virtual int peek();
37+
virtual void flush();
38+
virtual int available();
39+
const struct device *i2c_dev;
40+
static struct i2c_dt_spec bus;
41+
42+
private:
43+
int _address;
44+
uint8_t txBuffer[256], rxBuffer[256];
45+
uint32_t usedTxBuffer;
46+
struct rx_ring_buf{
47+
struct ring_buf rb;
48+
uint8_t buffer[256];
49+
};
50+
struct rx_ring_buf rxRingBuffer;
51+
};
52+
53+
} // namespace arduino
54+
55+
extern arduino::ZephyrI2C Wire;
56+
57+
typedef arduino::ZephyrI2C TwoWire;

0 commit comments

Comments
 (0)