UdonLibrary 1.0.0
機械システム研究部 C++ ライブラリ
読み取り中…
検索中…
一致する文字列を見つけられません
I2cBus.hpp
[詳解]
1//
2// I2c バス
3//
4// Copyright (c) 2022-2024 udonrobo
5//
6
7#pragma once
8
9#ifdef UDON_TEENSY_I2C_SLAVE_MODE
10# include <i2c_driver.h>
11# include <i2c_driver_wire.h>
12#else
13# include <Wire.h>
14#endif
15
16namespace Udon
17{
18
20 class II2cBus
21 {
22 public:
23 virtual ~II2cBus() = default;
24
26 virtual explicit operator bool() const = 0;
27
29 virtual bool update() = 0;
30
32 virtual void show() const = 0;
33
34 // 以下メンバは Arduino TwoWire クラスと同等
35
36 virtual void begin() = 0;
37
38 virtual void begin(uint8_t address) = 0;
39
40 virtual void end() = 0;
41
42 virtual void restart() = 0;
43
44 virtual void setClock(uint32_t clock) = 0;
45
46 virtual void beginTransmission(uint8_t address) = 0;
47
48 virtual uint8_t endTransmission() = 0;
49
50 virtual uint8_t endTransmission(uint8_t sendStop) = 0;
51
52 virtual uint8_t requestFrom(uint8_t address, uint8_t quantity) = 0;
53
54 virtual uint8_t requestFrom(uint8_t address, uint8_t quantity, uint8_t sendStop) = 0;
55
56 virtual size_t write(uint8_t data) = 0;
57
58 virtual size_t write(const uint8_t* data, size_t quantity) = 0;
59
60 virtual int available() = 0;
61
62 virtual int read() = 0;
63
64 virtual int peek() = 0;
65
66 virtual void flush() = 0;
67
68 virtual void onReceive(void (*function)(int)) = 0;
69
70 virtual void onRequest(void (*function)()) = 0;
71 };
72
76 template <int Counter>
78 : public II2cBus
79 {
80
81 static I2cBusImpl* self;
82
83 TwoWire& wire;
84
85 const uint32_t timeoutMs;
86
87 uint32_t transmitMs;
88
89 uint32_t restartCount;
90
92 void (*userOnReceive)(int);
93 void (*userOnRequest)();
94
96 void invokeOnReceive(int n)
97 {
98 if (userOnReceive)
99 {
100 transmitMs = millis();
101 userOnReceive(n);
102 }
103 }
104 void invokeOnRequest()
105 {
106 if (userOnRequest)
107 {
108 transmitMs = millis();
109 userOnRequest();
110 }
111 }
112
113 // TwoWire::onReceive 割り込み発火
114 // ↓
115 // I2cBusImpl::invokeOnReceive 呼び出し
116 // ↓
117 // userOnReceive(I2cBusImpl::onReceiveで登録したコールバック関数) 呼び出し
118
119 public:
123 I2cBusImpl(TwoWire& wire, uint32_t timeoutMs = 100)
124 : wire(wire)
125 , timeoutMs(timeoutMs)
126 , transmitMs()
127 , restartCount()
128 , userOnReceive()
129 , userOnRequest()
130 {
131 self = this;
132 }
133
136 I2cBusImpl(const I2cBusImpl&) = delete;
137
140 : wire(other.wire)
141 , timeoutMs(other.timeoutMs)
142 , transmitMs(other.transmitMs)
143 , restartCount(other.restartCount)
144 , userOnReceive()
145 , userOnRequest()
146 {
147 self = this;
148 }
149
151 explicit operator bool() const override
152 {
153 return millis() - transmitMs < timeoutMs;
154 }
155
156#if defined(__MK64FX512__) // Teensy 3.5 ではバスの再起動が適切に行えなかった。
157
159 bool update() override
160 {
161 Serial.print(F("This board does not support I2C bus restart.\n"));
162 return false;
163 }
164
165#else
166
168 bool update() override
169 {
170 if (operator bool())
171 {
172 return true;
173 }
174 else
175 {
176 restart();
177 return false;
178 }
179 }
180
181#endif
182
184 void show() const override
185 {
186 if (operator bool())
187 {
188 Serial.print(F("I2C: OK "));
189 }
190 else
191 {
192 Serial.print(F("I2C: NG "));
193 }
194 Serial.print(F("restart[n]: "));
195
196#if defined(__MK64FX512__)
197 Serial.print('-');
198#else
199 Serial.print(restartCount);
200#endif
201
202 Serial.print(F("\t transmit[ms]: "));
203 Serial.print(transmitMs);
204 Serial.print('\t');
205 }
206
208 inline void begin() override
209 {
210 wire.begin();
211 }
212
214 inline void begin(uint8_t address) override
215 {
216 wire.begin(address);
217 }
218
219#ifdef ARDUINO_ARCH_RP2040
220
223 inline void setSDA(uint8_t pin)
224 {
225 wire.setSDA(pin);
226 }
227
230 inline void setSCL(uint8_t pin)
231 {
232 wire.setSCL(pin);
233 }
234
235#endif
236
238 inline void end() override
239 {
240 wire.end();
241 }
242
244 inline void restart() override
245 {
246 ++restartCount;
247 end();
248 begin();
249 }
250
252 inline void setClock(uint32_t clock) override
253 {
254 wire.setClock(clock);
255 }
256
258 inline void beginTransmission(uint8_t address) override
259 {
260 wire.beginTransmission(address);
261 }
262
264 inline uint8_t endTransmission() override
265 {
266 return endTransmission(true);
267 }
268
270 inline uint8_t endTransmission(uint8_t sendStop) override
271 {
272 const auto ret = wire.endTransmission(sendStop);
273 if (ret == 0) // 送信成功
274 {
275 transmitMs = millis();
276 }
277 return ret;
278 }
279
281 inline uint8_t requestFrom(uint8_t address, uint8_t quantity) override
282 {
283 const auto ret = wire.requestFrom(address, quantity);
284 if (ret == quantity) // 送信成功
285 {
286 transmitMs = millis();
287 }
288 return ret;
289 }
290
292 inline uint8_t requestFrom(uint8_t address, uint8_t quantity, uint8_t sendStop) override
293 {
294 const auto ret = wire.requestFrom(address, quantity, sendStop);
295 if (ret == quantity) // 送信成功
296 {
297 transmitMs = millis();
298 }
299 return ret;
300 }
301
303 inline size_t write(uint8_t data) override
304 {
305 return wire.write(data);
306 }
307
309 inline size_t write(const uint8_t* data, size_t quantity) override
310 {
311 return wire.write(data, quantity);
312 }
313
315 inline int available() override
316 {
317 return wire.available();
318 }
319
321 inline int read() override
322 {
323 return wire.read();
324 }
325
327 inline int peek() override
328 {
329 return wire.peek();
330 }
331
333 inline void flush() override
334 {
335 wire.flush();
336 }
337
339 inline void onReceive(void (*function)(int)) override
340 {
341 userOnReceive = function;
342 wire.onReceive([](int n)
343 { self->invokeOnReceive(n); });
344 }
345
347 inline void onRequest(void (*function)()) override
348 {
349 userOnRequest = function;
350 wire.onRequest([]()
351 { self->invokeOnRequest(); });
352 }
353 };
354
355 template <int Counter>
356 I2cBusImpl<Counter>* I2cBusImpl<Counter>::self;
357
358} // namespace Udon
359
361#define I2cBus \
362 I2cBusImpl<__COUNTER__>
#define F(x)
Definition Show.hpp:17
I2cBus クラス実装部
Definition I2cBus.hpp:79
uint8_t endTransmission() override
TwoWire::endTransmission() と同等
Definition I2cBus.hpp:264
int read() override
TwoWire::read() と同等
Definition I2cBus.hpp:321
size_t write(const uint8_t *data, size_t quantity) override
TwoWire::write(data, quantity) と同等
Definition I2cBus.hpp:309
void setClock(uint32_t clock) override
TwoWire::setClock(clock) と同等
Definition I2cBus.hpp:252
I2cBusImpl(TwoWire &wire, uint32_t timeoutMs=100)
コンストラクタ
Definition I2cBus.hpp:123
void onReceive(void(*function)(int)) override
TwoWire::onReceive(function) と同等
Definition I2cBus.hpp:339
void begin(uint8_t address) override
TwoWire::begin(address) と同等
Definition I2cBus.hpp:214
uint8_t requestFrom(uint8_t address, uint8_t quantity, uint8_t sendStop) override
TwoWire::requestFrom(address, quantity, sendStop) と同等
Definition I2cBus.hpp:292
void show() const override
バスの状態を表示
Definition I2cBus.hpp:184
void onRequest(void(*function)()) override
TwoWire::onRequest(function) と同等
Definition I2cBus.hpp:347
I2cBusImpl(I2cBusImpl &&other)
ムーブコンストラクタ
Definition I2cBus.hpp:139
int peek() override
TwoWire::peek() と同等
Definition I2cBus.hpp:327
size_t write(uint8_t data) override
TwoWire::write(data) と同等
Definition I2cBus.hpp:303
void flush() override
TwoWire::flush() と同等
Definition I2cBus.hpp:333
bool update() override
更新
Definition I2cBus.hpp:168
uint8_t requestFrom(uint8_t address, uint8_t quantity) override
TwoWire::requestFrom(address, quantity) と同等
Definition I2cBus.hpp:281
void beginTransmission(uint8_t address) override
TwoWire::beginTransmission(address) と同等
Definition I2cBus.hpp:258
void begin() override
TwoWire::begin() と同等
Definition I2cBus.hpp:208
void end() override
TwoWire::end() と同等
Definition I2cBus.hpp:238
uint8_t endTransmission(uint8_t sendStop) override
TwoWire::endTransmission(sendStop) と同等
Definition I2cBus.hpp:270
int available() override
TwoWire::available() と同等
Definition I2cBus.hpp:315
void restart() override
バス再起動
Definition I2cBus.hpp:244
I2cBusImpl(const I2cBusImpl &)=delete
コピーコンストラクタ
I2cBus クラスのインターフェース
Definition I2cBus.hpp:21
virtual uint8_t endTransmission()=0
virtual void onReceive(void(*function)(int))=0
virtual size_t write(const uint8_t *data, size_t quantity)=0
virtual uint8_t requestFrom(uint8_t address, uint8_t quantity, uint8_t sendStop)=0
virtual int available()=0
virtual void restart()=0
virtual int read()=0
virtual bool update()=0
更新
virtual void show() const =0
バスの状態を表示
virtual size_t write(uint8_t data)=0
virtual void begin(uint8_t address)=0
virtual void begin()=0
virtual uint8_t endTransmission(uint8_t sendStop)=0
virtual uint8_t requestFrom(uint8_t address, uint8_t quantity)=0
virtual void end()=0
virtual void flush()=0
virtual void beginTransmission(uint8_t address)=0
virtual ~II2cBus()=default
virtual int peek()=0
virtual void setClock(uint32_t clock)=0
virtual void onRequest(void(*function)())=0
Definition Bit.hpp:12