CHGame 0.3.0
Libraries for the CHGame handheld
Loading...
Searching...
No Matches
Wire.h
Go to the documentation of this file.
1/*
2 TwoWire.h - TWI/I2C library for Arduino & Wiring
3 Copyright (c) 2006 Nicholas Zambetti. All right reserved.
4
5 This library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Lesser General Public
7 License as published by the Free Software Foundation; either
8 version 2.1 of the License, or (at your option) any later version.
9
10 This library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Lesser General Public License for more details.
14
15 You should have received a copy of the GNU Lesser General Public
16 License along with this library; if not, write to the Free Software
17 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
18
19 Modified 2012 by Todd Krein (todd@krein.org) to implement repeated starts
20
21 Modified 6 june 2023 by Temperslee to support wch's risc-v chips
22*/
23
24/**
25 * @file
26 * @brief Arduino's Wire library (TwoWire), ported to WCH's chips: I2C master
27 * and slave on the CH32X035's I2C1.
28 */
29
30/**
31 * @defgroup core_wire Wire (I2C)
32 * @ingroup lib_core
33 * @brief The Arduino Wire API: I2C master (and slave) on I2C1.
34 *
35 * @code
36 * #include <Wire.h>
37 *
38 * Wire.begin(); // master, 100 kHz
39 * Wire.beginTransmission(0x3C);
40 * Wire.write(0x00);
41 * Wire.write(0xAF);
42 * uint8_t err = Wire.endTransmission(); // 0: done
43 * if (Wire.requestFrom(0x3C, 1) == 1) {
44 * int b = Wire.read();
45 * }
46 * @endcode
47 *
48 * On the CHGame board (rev0) the global @ref Wire uses SDA = PC18
49 * (`PIN_WIRE_SDA`) and SCL = PC19 (`PIN_WIRE_SCL`), which come out on the
50 * expansion header H1: SDA on H1.2, SCL on H1.1. The board has no pull-up
51 * resistors on them, so the device or the wiring must provide them. (They
52 * are also the chip's two-wire debug pins, DIO and DCK.) The stock
53 * CH32X035 defaults, PC17 and PC16, are the board's USB D+ and D-: never
54 * pass them to begin(sda, scl) or setSDA() / setSCL().
55 *
56 * Transfers are polled (slave mode uses the I2C interrupt) and each step
57 * gives up after about 3 ms (`I2C_TIMEOUT_TICK`). The transmit and receive
58 * buffers live on the heap: they start at @ref BUFFER_LENGTH bytes, grow as
59 * needed, and a transmission holds at most @ref WIRE_MAX_TX_BUFF_LENGTH bytes.
60 * @{
61 */
62#ifndef TwoWire_h
63#define TwoWire_h
64
65#include <functional>
66
67#include "Stream.h"
68#include "Arduino.h"
69
70extern "C" {
71#include "utility/twi.h"
72}
73
74// Minimal buffer length. Buffers length will be increased when needed,
75// but TX buffer is limited to a maximum to avoid too much stack consumption
76// Note: Buffer length and max buffer length are limited by uin16_t type
77/**
78 * @brief The smallest size of the receive and transmit buffers, in bytes
79 * (they grow on the heap when a transfer needs more).
80 */
81#define BUFFER_LENGTH 32
82/**
83 * @brief The most bytes one transmission (beginTransmission() ...
84 * endTransmission()) can hold; write() returns 0 past it. Default 1024.
85 */
86#if !defined(WIRE_MAX_TX_BUFF_LENGTH)
87 #define WIRE_MAX_TX_BUFF_LENGTH 1024U
88#endif
89
90// WIRE_HAS_END means Wire has end()
91/**
92 * @brief Defined to 1: this Wire has end().
93 */
94#define WIRE_HAS_END 1
95
96/**
97 * @brief An I2C bus: the Arduino Wire API on one of the chip's I2C
98 * peripherals (the global @ref Wire on this board).
99 *
100 * As a master: beginTransmission(), write() and endTransmission() to send;
101 * requestFrom(), then available() and read() to receive. As a slave:
102 * begin(address), with onReceive() and onRequest(). It is a `Stream`, so
103 * `print()` works inside a transmission too.
104 */
105class TwoWire : public Stream {
106 public:
107 /**
108 * @brief What onReceive() takes: called with the number of bytes received.
109 */
110 typedef std::function<void(int)> cb_function_receive_t;
111 /**
112 * @brief What onRequest() takes: called when the master asks for data.
113 */
114 typedef std::function<void(void)> cb_function_request_t;
115
116 private:
117 uint8_t *rxBuffer; //Dynamic application and release
118 uint16_t rxBufferAllocated;
119 uint16_t rxBufferIndex;
120 uint16_t rxBufferLength;
121
122 uint8_t txAddress;
123 uint8_t *txBuffer; //Dynamic application and release
124 uint16_t txBufferAllocated;
125 uint16_t txDataSize;
126
127 uint8_t transmitting;
128
129 uint8_t ownAddress;
130 i2c_t _i2c;
131
132 std::function<void(int)> user_onReceive;
133 std::function<void(void)> user_onRequest;
134
135 static void onRequestService(i2c_t *);
136 static void onReceiveService(i2c_t *);
137
138 void allocateRxBuffer(size_t length);
139 size_t allocateTxBuffer(size_t length);
140
141 void resetRxBuffer(void);
142 void resetTxBuffer(void);
143 void recoverBus(void);
144
145 public:
146 /**
147 * @brief An I2C bus on the variant's `SDA` and `SCL` (PC18 and PC19 on
148 * this board).
149 */
151 /**
152 * @brief An I2C bus on the given pins.
153 * @param sda the SDA pin (Arduino pin number).
154 * @param scl the SCL pin (Arduino pin number).
155 */
156 TwoWire(uint32_t sda, uint32_t scl);
157 // setSCL/SDA have to be called before begin()
158 /**
159 * @brief Sets the SCL pin; call before begin().
160 * @param scl the pin's Arduino number (`PC19` on this board).
161 */
162 void setSCL(uint32_t scl)
163 {
164 _i2c.scl = digitalPinToPinName(scl);
165 };
166 /**
167 * @brief Sets the SDA pin; call before begin().
168 * @param sda the pin's Arduino number (`PC18` on this board).
169 */
170 void setSDA(uint32_t sda)
171 {
172 _i2c.sda = digitalPinToPinName(sda);
173 };
174 /**
175 * @brief Sets the SCL pin; call before begin().
176 * @param scl the pin's name (`PC_19`).
177 */
178 void setSCL(PinName scl)
179 {
180 _i2c.scl = scl;
181 };
182 /**
183 * @brief Sets the SDA pin; call before begin().
184 * @param sda the pin's name (`PC_18`).
185 */
186 void setSDA(PinName sda)
187 {
188 _i2c.sda = sda;
189 };
190 /**
191 * @brief Joins the bus as the master, at 100 kHz.
192 *
193 * Sets the pins up and resets I2C1. If a device holds SDA low (stuck after
194 * a reset), clocks SCL 20 times first to free it. Call it once, or end()
195 * first: it forgets (and leaks) the buffers it had.
196 * @param generalCall stored, but not used by this port.
197 */
198 void begin(bool generalCall = false);
199 /**
200 * @brief Joins the bus as the master on the given pins, at 100 kHz.
201 * @par Parameters
202 * - `sda`: the SDA pin (Arduino pin number).
203 * - `scl`: the SCL pin (Arduino pin number).
204 */
205 void begin(uint32_t, uint32_t);
206 /**
207 * @brief Joins the bus as a slave at a 7-bit address (1 means the master,
208 * as begin() does).
209 *
210 * The I2C interrupt then answers the master: see onReceive() and
211 * onRequest(). A slave receives at most 32 bytes per message
212 * (`I2C_TXRX_BUFFER_SIZE`).
213 * @par Parameters
214 * - `address`: the slave's 7-bit address.
215 * @param generalCall stored, but not used by this port.
216 * @param NoStretchMode stored, but not used by this port.
217 */
218 void begin(uint8_t, bool generalCall = false, bool NoStretchMode = false);
219 /**
220 * @brief Joins the bus as a slave at a 7-bit address (the `int` form).
221 * @par Parameters
222 * - `address`: the slave's 7-bit address.
223 * @param generalCall stored, but not used by this port.
224 * @param NoStretchMode stored, but not used by this port.
225 */
226 void begin(int, bool generalCall = false, bool NoStretchMode = false);
227 /**
228 * @brief Leaves the bus: turns the I2C interrupts off, resets I2C1 and
229 * frees the buffers.
230 */
231 void end();
232 /**
233 * @brief Sets the bus clock; call after begin().
234 * @par Parameters
235 * - `frequency`: in Hz: up to 100000 gives 100 kHz, up to 400000 gives
236 * 400 kHz, up to 1000000 gives 1 MHz. Higher values are not
237 * valid.
238 */
239 void setClock(uint32_t);
240 /**
241 * @brief Starts collecting bytes for a slave; nothing goes on the bus until
242 * endTransmission().
243 * @par Parameters
244 * - `address`: the slave's 7-bit address.
245 */
246 void beginTransmission(uint8_t);
247 /**
248 * @brief Starts collecting bytes for a slave (the `int` form).
249 * @par Parameters
250 * - `address`: the slave's 7-bit address.
251 */
253 /**
254 * @brief Sends the bytes collected since beginTransmission(), then a STOP.
255 *
256 * Blocks until done. With no bytes it only addresses the slave, which is
257 * how an I2C scanner finds devices.
258 * @return As Arduino's: 0 sent; 2 no slave acknowledged the address;
259 * 3 the slave did not acknowledge a data byte; 4 another error
260 * (bus busy, timeout). A NACK ends the write with a STOP at once.
261 */
262 uint8_t endTransmission(void);
263 /**
264 * @brief Sends the bytes collected since beginTransmission(), with or
265 * without a STOP.
266 * @par Parameters
267 * - `sendStop`: `true`: end with a STOP; `false`: keep the bus, for a
268 * repeated start by the requestFrom() that follows.
269 * @return 0 sent; 2 address not acknowledged; 3 data not acknowledged;
270 * 4 another error (see endTransmission()).
271 */
272 uint8_t endTransmission(uint8_t);
273 /**
274 * @brief Reads bytes from a slave into the receive buffer, for available()
275 * and read().
276 *
277 * Blocks until done; the read always ends with a STOP.
278 * @par Parameters
279 * - `address`: the slave's 7-bit address.
280 * - `quantity`: how many bytes, 1 to 255.
281 * @return `quantity` if they all arrived, 0 if the read failed.
282 * @note The whole read must finish within about 3 ms (`I2C_TIMEOUT_TICK`):
283 * at 100 kHz that is about 30 bytes, at 400 kHz about 120. Raise the
284 * clock with setClock(), or read in smaller pieces, for more.
285 */
286 uint8_t requestFrom(uint8_t, uint8_t);
287 /**
288 * @brief Reads bytes from a slave (Arduino's form with `sendStop`).
289 * @par Parameters
290 * - `address`: the slave's 7-bit address.
291 * - `quantity`: how many bytes, 1 to 255.
292 * - `sendStop`: ignored: this port always ends a read with a STOP.
293 * @return `quantity` if they all arrived, 0 if the read failed.
294 */
295 uint8_t requestFrom(uint8_t, uint8_t, uint8_t);
296 /**
297 * @brief Reads bytes from a slave (Arduino's form with `sendStop`).
298 * @par Parameters
299 * - `address`: the slave's 7-bit address.
300 * - `quantity`: how many bytes, 1 to 255.
301 * - `sendStop`: ignored: this port always ends a read with a STOP.
302 * @return `quantity` if they all arrived, 0 if the read failed.
303 */
304 uint8_t requestFrom(uint8_t, size_t, bool);
305 /**
306 * @brief Writes a register address to a slave, then reads bytes from it
307 * with a repeated start.
308 * @par Parameters
309 * - `address`: the slave's 7-bit address.
310 * - `quantity`: how many bytes, 1 to 255.
311 * - `iaddress`: the register (internal) address, sent first.
312 * - `isize`: how many bytes of `iaddress` to send, most significant
313 * first: 0 (none, a plain read) to 3.
314 * - `sendStop`: ignored: this port always ends a read with a STOP.
315 * @return `quantity` if they all arrived, 0 if the read failed.
316 */
317 uint8_t requestFrom(uint8_t, uint8_t, uint32_t, uint8_t, uint8_t);
318 /**
319 * @brief Reads bytes from a slave (the `int` form).
320 * @par Parameters
321 * - `address`: the slave's 7-bit address.
322 * - `quantity`: how many bytes, 1 to 255.
323 * @return `quantity` if they all arrived, 0 if the read failed.
324 */
325 uint8_t requestFrom(int, int);
326 /**
327 * @brief Reads bytes from a slave (the `int` form with `sendStop`).
328 * @par Parameters
329 * - `address`: the slave's 7-bit address.
330 * - `quantity`: how many bytes, 1 to 255.
331 * - `sendStop`: ignored: this port always ends a read with a STOP.
332 * @return `quantity` if they all arrived, 0 if the read failed.
333 */
334 uint8_t requestFrom(int, int, int);
335 /**
336 * @brief Adds a byte to the transmission, or, in a slave's onRequest()
337 * callback, sends it to the master.
338 * @par Parameters
339 * - `data`: the byte.
340 * @return 1, or 0 if the transmission would pass
341 * @ref WIRE_MAX_TX_BUFF_LENGTH bytes (or a slave's byte was not
342 * taken).
343 */
344 virtual size_t write(uint8_t);
345 /**
346 * @brief Adds bytes to the transmission, or, in a slave's onRequest()
347 * callback, sends them to the master.
348 * @par Parameters
349 * - `data`: the bytes.
350 * - `quantity`: how many.
351 * @return `quantity`, or 0 if the transmission would pass
352 * @ref WIRE_MAX_TX_BUFF_LENGTH bytes (none are added then).
353 */
354 virtual size_t write(const uint8_t *, size_t);
355 /**
356 * @brief How many received bytes are left to read (after requestFrom(),
357 * or in an onReceive() callback).
358 * @return the number of bytes.
359 */
360 virtual int available(void);
361 /**
362 * @brief Takes the next received byte.
363 * @return the byte (0-255), or -1 if there is none.
364 */
365 virtual int read(void);
366 /**
367 * @brief The next received byte, left in the buffer.
368 * @return the byte (0-255), or -1 if there is none.
369 */
370 virtual int peek(void);
371 /**
372 * @brief Throws away the received bytes and the transmission's bytes.
373 * (Unlike `Serial.flush()`, it does not wait for anything.)
374 */
375 virtual void flush(void);
376
377 /**
378 * @brief Sets what a slave does when the master has sent it a message.
379 * @param callback called from the I2C interrupt after the master's STOP,
380 * with the number of bytes received (1-32); it reads them
381 * with read().
382 */
384 /**
385 * @brief Sets what a slave does when the master asks it for data.
386 * @param callback called from the I2C interrupt; it answers with write().
387 */
389
390 /**
391 * @brief Writes the low byte of `n` (see write(uint8_t)).
392 * @param n the value; only its low 8 bits are sent.
393 * @return 1, or 0 if it did not fit.
394 */
395 inline size_t write(unsigned long n)
396 {
397 return write((uint8_t)n);
398 }
399 /**
400 * @brief Writes the low byte of `n` (see write(uint8_t)).
401 * @param n the value; only its low 8 bits are sent.
402 * @return 1, or 0 if it did not fit.
403 */
404 inline size_t write(long n)
405 {
406 return write((uint8_t)n);
407 }
408 /**
409 * @brief Writes the low byte of `n` (see write(uint8_t)).
410 * @param n the value; only its low 8 bits are sent.
411 * @return 1, or 0 if it did not fit.
412 */
413 inline size_t write(unsigned int n)
414 {
415 return write((uint8_t)n);
416 }
417 /**
418 * @brief Writes the low byte of `n` (see write(uint8_t)).
419 * @param n the value; only its low 8 bits are sent.
420 * @return 1, or 0 if it did not fit.
421 */
422 inline size_t write(int n)
423 {
424 return write((uint8_t)n);
425 }
426 using Print::write;
427
428 /**
429 * @brief The WCH peripheral library's view of this bus: its instance and
430 * init structure, for mixing in WCH's own I2C functions. Use at your own
431 * risk.
432 * @return the handle, valid for the object's lifetime.
433 */
434 I2C_HandleTypeDef *getHandle(void)
435 {
436 return &(_i2c.handle);
437 }
438};
439
440
441
442/**
443 * @brief The I2C bus: I2C1 on PC18 (SDA, header H1.2) and PC19 (SCL, H1.1).
444 */
445extern TwoWire Wire;
446
447/** @} */
448
449#endif
An I2C bus: the Arduino Wire API on one of the chip's I2C peripherals (the global Wire on this board)...
Definition Wire.h:105
size_t write(unsigned long n)
Writes the low byte of n (see write(uint8_t)).
Definition Wire.h:395
void end()
Leaves the bus: turns the I2C interrupts off, resets I2C1 and frees the buffers.
void begin(uint8_t, bool generalCall=false, bool NoStretchMode=false)
Joins the bus as a slave at a 7-bit address (1 means the master, as begin() does).
void onRequest(cb_function_request_t callback)
Sets what a slave does when the master asks it for data.
uint8_t endTransmission(uint8_t)
Sends the bytes collected since beginTransmission(), with or without a STOP.
virtual int available(void)
How many received bytes are left to read (after requestFrom(), or in an onReceive() callback).
void setSCL(uint32_t scl)
Sets the SCL pin; call before begin().
Definition Wire.h:162
uint8_t requestFrom(uint8_t, size_t, bool)
Reads bytes from a slave (Arduino's form with sendStop).
void setClock(uint32_t)
Sets the bus clock; call after begin().
void begin(bool generalCall=false)
Joins the bus as the master, at 100 kHz.
uint8_t requestFrom(int, int, int)
Reads bytes from a slave (the int form with sendStop).
void begin(uint32_t, uint32_t)
Joins the bus as the master on the given pins, at 100 kHz.
std::function< void(int)> cb_function_receive_t
What onReceive() takes: called with the number of bytes received.
Definition Wire.h:110
uint8_t requestFrom(uint8_t, uint8_t, uint8_t)
Reads bytes from a slave (Arduino's form with sendStop).
TwoWire()
An I2C bus on the variant's SDA and SCL (PC18 and PC19 on this board).
void beginTransmission(int)
Starts collecting bytes for a slave (the int form).
size_t write(long n)
Writes the low byte of n (see write(uint8_t)).
Definition Wire.h:404
void setSDA(PinName sda)
Sets the SDA pin; call before begin().
Definition Wire.h:186
virtual size_t write(uint8_t)
Adds a byte to the transmission, or, in a slave's onRequest() callback, sends it to the master.
void begin(int, bool generalCall=false, bool NoStretchMode=false)
Joins the bus as a slave at a 7-bit address (the int form).
virtual int read(void)
Takes the next received byte.
TwoWire(uint32_t sda, uint32_t scl)
An I2C bus on the given pins.
void beginTransmission(uint8_t)
Starts collecting bytes for a slave; nothing goes on the bus until endTransmission().
size_t write(int n)
Writes the low byte of n (see write(uint8_t)).
Definition Wire.h:422
void setSDA(uint32_t sda)
Sets the SDA pin; call before begin().
Definition Wire.h:170
virtual size_t write(const uint8_t *, size_t)
Adds bytes to the transmission, or, in a slave's onRequest() callback, sends them to the master.
I2C_HandleTypeDef * getHandle(void)
The WCH peripheral library's view of this bus: its instance and init structure, for mixing in WCH's o...
Definition Wire.h:434
std::function< void(void)> cb_function_request_t
What onRequest() takes: called when the master asks for data.
Definition Wire.h:114
void onReceive(cb_function_receive_t callback)
Sets what a slave does when the master has sent it a message.
virtual int peek(void)
The next received byte, left in the buffer.
uint8_t requestFrom(uint8_t, uint8_t, uint32_t, uint8_t, uint8_t)
Writes a register address to a slave, then reads bytes from it with a repeated start.
uint8_t requestFrom(int, int)
Reads bytes from a slave (the int form).
void setSCL(PinName scl)
Sets the SCL pin; call before begin().
Definition Wire.h:178
uint8_t requestFrom(uint8_t, uint8_t)
Reads bytes from a slave into the receive buffer, for available() and read().
virtual void flush(void)
Throws away the received bytes and the transmission's bytes.
uint8_t endTransmission(void)
Sends the bytes collected since beginTransmission(), then a STOP.
size_t write(unsigned int n)
Writes the low byte of n (see write(uint8_t)).
Definition Wire.h:413
TwoWire Wire
The I2C bus: I2C1 on PC18 (SDA, header H1.2) and PC19 (SCL, H1.1).