Skip to content

Commit 8a32dc7

Browse files
committed
refactor the whole thing to get rid of static-ness. also clang examples
1 parent cc66c42 commit 8a32dc7

File tree

12 files changed

+410
-301
lines changed

12 files changed

+410
-301
lines changed

Adafruit_GenericDevice.cpp

Lines changed: 32 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -6,73 +6,77 @@
66

77
#include "Adafruit_GenericDevice.h"
88

9-
/*! @brief Create a Generic device with the provided read/write functions
10-
@param read_func Function pointer for reading raw data
11-
@param write_func Function pointer for writing raw data
12-
@param readreg_func Function pointer for reading registers (optional)
13-
@param writereg_func Function pointer for writing registers (optional) */
9+
/*!
10+
* @brief Create a Generic device with the provided read/write functions
11+
* @param obj Pointer to object instance
12+
* @param read_func Function pointer for reading raw data
13+
* @param write_func Function pointer for writing raw data
14+
* @param readreg_func Function pointer for reading registers (optional)
15+
* @param writereg_func Function pointer for writing registers (optional) */
1416
Adafruit_GenericDevice::Adafruit_GenericDevice(
15-
busio_genericdevice_read_t read_func,
17+
void *obj, busio_genericdevice_read_t read_func,
1618
busio_genericdevice_write_t write_func,
1719
busio_genericdevice_readreg_t readreg_func,
1820
busio_genericdevice_writereg_t writereg_func) {
21+
_obj = obj;
1922
_read_func = read_func;
2023
_write_func = write_func;
2124
_readreg_func = readreg_func;
2225
_writereg_func = writereg_func;
2326
_begun = false;
2427
}
2528

26-
/*! @brief Initializes the device
27-
@return true if initialization was successful, otherwise false */
29+
/*! @brief Simple begin function (doesn't do much at this time)
30+
@return true always
31+
*/
2832
bool Adafruit_GenericDevice::begin(void) {
2933
_begun = true;
3034
return true;
3135
}
3236

3337
/*! @brief Write a buffer of data
34-
@param buffer Pointer to buffer of data to write
35-
@param len Number of bytes to write
36-
@return true if write was successful, otherwise false */
38+
@param buffer Pointer to buffer of data to write
39+
@param len Number of bytes to write
40+
@return true if write was successful, otherwise false */
3741
bool Adafruit_GenericDevice::write(const uint8_t *buffer, size_t len) {
3842
if (!_begun)
3943
return false;
40-
return _write_func(buffer, len);
44+
return _write_func(_obj, buffer, len);
4145
}
4246

4347
/*! @brief Read data into a buffer
44-
@param buffer Pointer to buffer to read data into
45-
@param len Number of bytes to read
46-
@return true if read was successful, otherwise false */
48+
@param buffer Pointer to buffer to read data into
49+
@param len Number of bytes to read
50+
@return true if read was successful, otherwise false */
4751
bool Adafruit_GenericDevice::read(uint8_t *buffer, size_t len) {
4852
if (!_begun)
4953
return false;
50-
return _read_func(buffer, len);
54+
return _read_func(_obj, buffer, len);
5155
}
5256

5357
/*! @brief Read from a register location
54-
@param addr_buf Buffer containing register address
55-
@param addrsiz Size of register address in bytes
56-
@param buf Buffer to store read data
57-
@param bufsiz Size of data to read in bytes
58-
@return true if read was successful, otherwise false */
58+
@param addr_buf Buffer containing register address
59+
@param addrsiz Size of register address in bytes
60+
@param buf Buffer to store read data
61+
@param bufsiz Size of data to read in bytes
62+
@return true if read was successful, otherwise false */
5963
bool Adafruit_GenericDevice::readRegister(uint8_t *addr_buf, uint8_t addrsiz,
6064
uint8_t *buf, uint16_t bufsiz) {
6165
if (!_begun || !_readreg_func)
6266
return false;
63-
return _readreg_func(addr_buf, addrsiz, buf, bufsiz);
67+
return _readreg_func(_obj, addr_buf, addrsiz, buf, bufsiz);
6468
}
6569

6670
/*! @brief Write to a register location
67-
@param addr_buf Buffer containing register address
68-
@param addrsiz Size of register address in bytes
69-
@param buf Buffer containing data to write
70-
@param bufsiz Size of data to write in bytes
71-
@return true if write was successful, otherwise false */
71+
@param addr_buf Buffer containing register address
72+
@param addrsiz Size of register address in bytes
73+
@param buf Buffer containing data to write
74+
@param bufsiz Size of data to write in bytes
75+
@return true if write was successful, otherwise false */
7276
bool Adafruit_GenericDevice::writeRegister(uint8_t *addr_buf, uint8_t addrsiz,
7377
const uint8_t *buf,
7478
uint16_t bufsiz) {
7579
if (!_begun || !_writereg_func)
7680
return false;
77-
return _writereg_func(addr_buf, addrsiz, buf, bufsiz);
81+
return _writereg_func(_obj, addr_buf, addrsiz, buf, bufsiz);
7882
}

Adafruit_GenericDevice.h

Lines changed: 14 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3,23 +3,25 @@
33

44
#include <Arduino.h>
55

6-
typedef bool (*busio_genericdevice_read_t)(uint8_t *buffer, size_t len);
7-
typedef bool (*busio_genericdevice_write_t)(const uint8_t *buffer, size_t len);
8-
typedef bool (*busio_genericdevice_readreg_t)(uint8_t *addr_buf,
9-
uint8_t addrsiz, uint8_t *buf,
10-
uint16_t bufsiz);
11-
typedef bool (*busio_genericdevice_writereg_t)(uint8_t *addr_buf,
6+
typedef bool (*busio_genericdevice_read_t)(void *obj, uint8_t *buffer,
7+
size_t len);
8+
typedef bool (*busio_genericdevice_write_t)(void *obj, const uint8_t *buffer,
9+
size_t len);
10+
typedef bool (*busio_genericdevice_readreg_t)(void *obj, uint8_t *addr_buf,
11+
uint8_t addrsiz, uint8_t *data,
12+
uint16_t datalen);
13+
typedef bool (*busio_genericdevice_writereg_t)(void *obj, uint8_t *addr_buf,
1214
uint8_t addrsiz,
13-
const uint8_t *buf,
14-
uint16_t bufsiz);
15+
const uint8_t *data,
16+
uint16_t datalen);
1517

1618
/*!
1719
* @brief Class for communicating with a device via generic read/write functions
1820
*/
1921
class Adafruit_GenericDevice {
2022
public:
2123
Adafruit_GenericDevice(
22-
busio_genericdevice_read_t read_func,
24+
void *obj, busio_genericdevice_read_t read_func,
2325
busio_genericdevice_write_t write_func,
2426
busio_genericdevice_readreg_t readreg_func = nullptr,
2527
busio_genericdevice_writereg_t writereg_func = nullptr);
@@ -45,6 +47,9 @@ class Adafruit_GenericDevice {
4547

4648
bool _begun; ///< whether we have initialized yet (in case the function needs
4749
///< to do something)
50+
51+
private:
52+
void *_obj; ///< Pointer to object instance
4853
};
4954

5055
#endif // ADAFRUIT_GENERICDEVICE_H
Lines changed: 35 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,17 @@
11
/*
2-
Advanced example of using bstracted transport for reading and writing
2+
Advanced example of using bstracted transport for reading and writing
33
register data from a UART-based device such as a TMC2209
44
5-
Written with help by Claude! https://claude.ai/chat/335f50b1-3dd8-435e-9139-57ec7ca26a3c
6-
(at this time chats are not shareable :(
5+
Written with help by Claude!
6+
https://claude.ai/chat/335f50b1-3dd8-435e-9139-57ec7ca26a3c (at this time
7+
chats are not shareable :(
78
*/
89

9-
1010
#include "Adafruit_BusIO_Register.h"
1111
#include "Adafruit_GenericDevice.h"
1212

1313
// Debugging macros
14-
//#define DEBUG_SERIAL Serial
14+
#define DEBUG_SERIAL Serial
1515

1616
#ifdef DEBUG_SERIAL
1717
#define DEBUG_PRINT(x) DEBUG_SERIAL.print(x)
@@ -29,36 +29,17 @@
2929
#define DEBUG_PRINT_HEX(x)
3030
#endif
3131

32-
// Add IOIN register definition
3332
#define TMC2209_IOIN 0x06
3433

3534
class TMC2209_UART {
3635
private:
37-
static TMC2209_UART *_instance;
3836
Stream *_uart_stream;
3937
uint8_t _addr;
4038

41-
static bool uart_read_impl(uint8_t *buffer, size_t len) {
42-
return _instance->uart_read_fn(buffer, len);
43-
}
44-
45-
static bool uart_write_impl(const uint8_t *buffer, size_t len) {
46-
return _instance->uart_write_fn(buffer, len);
47-
}
48-
49-
static bool uart_readreg_impl(uint8_t *addr_buf, uint8_t addrsiz,
50-
uint8_t *data, uint16_t datalen) {
51-
return _instance->uart_readreg_fn(addr_buf, addrsiz, data, datalen);
52-
}
53-
54-
static bool uart_writereg_impl(uint8_t *addr_buf, uint8_t addrsiz,
55-
const uint8_t *data, uint16_t datalen) {
56-
return _instance->uart_writereg_fn(addr_buf, addrsiz, data, datalen);
57-
}
58-
59-
bool uart_read_fn(uint8_t *buffer, size_t len) {
39+
static bool uart_read(void *thiz, uint8_t *buffer, size_t len) {
40+
TMC2209_UART *dev = (TMC2209_UART *)thiz;
6041
uint16_t timeout = 100;
61-
while (_uart_stream->available() < len && timeout--) {
42+
while (dev->_uart_stream->available() < len && timeout--) {
6243
delay(1);
6344
}
6445
if (timeout == 0) {
@@ -68,39 +49,41 @@ private:
6849

6950
DEBUG_PRINT("Reading: ");
7051
for (size_t i = 0; i < len; i++) {
71-
buffer[i] = _uart_stream->read();
52+
buffer[i] = dev->_uart_stream->read();
7253
DEBUG_PRINT_HEX(buffer[i]);
7354
}
7455
DEBUG_PRINTLN("");
7556

7657
return true;
7758
}
7859

79-
bool uart_write_fn(const uint8_t *buffer, size_t len) {
60+
static bool uart_write(void *thiz, const uint8_t *buffer, size_t len) {
61+
TMC2209_UART *dev = (TMC2209_UART *)thiz;
8062
DEBUG_PRINT("Writing: ");
8163
for (size_t i = 0; i < len; i++) {
8264
DEBUG_PRINT_HEX(buffer[i]);
8365
}
8466
DEBUG_PRINTLN("");
8567

86-
_uart_stream->write(buffer, len);
68+
dev->_uart_stream->write(buffer, len);
8769
return true;
8870
}
8971

90-
bool uart_readreg_fn(uint8_t *addr_buf, uint8_t addrsiz, uint8_t *data,
91-
uint16_t datalen) {
92-
while (_uart_stream->available())
93-
_uart_stream->read();
72+
static bool uart_readreg(void *thiz, uint8_t *addr_buf, uint8_t addrsiz,
73+
uint8_t *data, uint16_t datalen) {
74+
TMC2209_UART *dev = (TMC2209_UART *)thiz;
75+
while (dev->_uart_stream->available())
76+
dev->_uart_stream->read();
9477

95-
uint8_t packet[4] = {0x05, uint8_t(_addr << 1), addr_buf[0], 0x00};
78+
uint8_t packet[4] = {0x05, uint8_t(dev->_addr << 1), addr_buf[0], 0x00};
9679

9780
packet[3] = calcCRC(packet, 3);
98-
if (!uart_write_impl(packet, 4))
81+
if (!uart_write(thiz, packet, 4))
9982
return false;
10083

10184
// Read back echo
10285
uint8_t echo[4];
103-
if (!uart_read_impl(echo, 4))
86+
if (!uart_read(thiz, echo, 4))
10487
return false;
10588

10689
// Verify echo
@@ -112,7 +95,7 @@ private:
11295
}
11396

11497
uint8_t response[8]; // sync + 0xFF + reg + 4 data bytes + CRC
115-
if (!uart_read_impl(response, 8))
98+
if (!uart_read(thiz, response, 8))
11699
return false;
117100

118101
// Verify response
@@ -121,38 +104,34 @@ private:
121104
return false;
122105
}
123106

124-
// Verify 0xFF address byte
125107
if (response[1] != 0xFF) {
126108
DEBUG_PRINTLN("Invalid reply address");
127109
return false;
128110
}
129111

130-
// Verify register address matches our request
131112
if (response[2] != addr_buf[0]) {
132113
DEBUG_PRINTLN("Register mismatch");
133114
return false;
134115
}
135116

136-
// Verify CRC
137-
uint8_t crc = calcCRC(response, 7); // Calculate CRC of all but last byte
117+
uint8_t crc = calcCRC(response, 7);
138118
if (crc != response[7]) {
139119
DEBUG_PRINTLN("CRC mismatch");
140120
return false;
141121
}
142122

143-
// Copy the data bytes
144123
memcpy(data, &response[3], 4);
145-
146124
return true;
147125
}
148126

149-
bool uart_writereg_fn(uint8_t *addr_buf, uint8_t addrsiz, const uint8_t *data,
150-
uint16_t datalen) {
151-
while (_uart_stream->available())
152-
_uart_stream->read();
127+
static bool uart_writereg(void *thiz, uint8_t *addr_buf, uint8_t addrsiz,
128+
const uint8_t *data, uint16_t datalen) {
129+
TMC2209_UART *dev = (TMC2209_UART *)thiz;
130+
while (dev->_uart_stream->available())
131+
dev->_uart_stream->read();
153132

154133
uint8_t packet[8] = {0x05,
155-
uint8_t(_addr << 1),
134+
uint8_t(dev->_addr << 1),
156135
uint8_t(addr_buf[0] | 0x80),
157136
data[0],
158137
data[1],
@@ -161,15 +140,13 @@ private:
161140
0x00};
162141

163142
packet[7] = calcCRC(packet, 7);
164-
if (!uart_write_impl(packet, 8))
143+
if (!uart_write(thiz, packet, 8))
165144
return false;
166145

167-
// Read and verify echo
168146
uint8_t echo[8];
169-
if (!uart_read_impl(echo, 8))
147+
if (!uart_read(thiz, echo, 8))
170148
return false;
171149

172-
// Verify echo matches what we sent
173150
for (uint8_t i = 0; i < 8; i++) {
174151
if (echo[i] != packet[i]) {
175152
DEBUG_PRINTLN("Write echo mismatch");
@@ -198,18 +175,14 @@ private:
198175

199176
public:
200177
TMC2209_UART(Stream *serial, uint8_t addr)
201-
: _uart_stream(serial), _addr(addr) {
202-
_instance = this;
203-
}
178+
: _uart_stream(serial), _addr(addr) {}
204179

205180
Adafruit_GenericDevice *createDevice() {
206-
return new Adafruit_GenericDevice(uart_read_impl, uart_write_impl,
207-
uart_readreg_impl, uart_writereg_impl);
181+
return new Adafruit_GenericDevice(this, uart_read, uart_write, uart_readreg,
182+
uart_writereg);
208183
}
209184
};
210185

211-
TMC2209_UART *TMC2209_UART::_instance = nullptr;
212-
213186
void setup() {
214187
Serial.begin(115200);
215188
while (!Serial)
@@ -232,7 +205,7 @@ void setup() {
232205
Serial.print("IOIN = 0x");
233206
Serial.println(ioin_reg.read(), HEX);
234207

235-
// Create RegisterBits for VERSION field (bits 28:24)
208+
// Create RegisterBits for VERSION field (bits 31:24)
236209
Adafruit_BusIO_RegisterBits version_bits(
237210
&ioin_reg, 8, 24); // 8 bits wide, starting at bit 24
238211

@@ -243,4 +216,4 @@ void setup() {
243216
Serial.println(version, HEX);
244217
}
245218

246-
void loop() { delay(1000); }
219+
void loop() { delay(1000); }

0 commit comments

Comments
 (0)