Krolyxon
Commit 1d55752

Branches

Tags

Refs →

orion-rf.piolibdepsesp32-s3-n16r8Adafruit BusIOexamplesgenericdevice_uartregtestgenericdevice_uartregtest.ino

219 lines · 6.1 KB

1/*
2 Advanced example of using bstracted transport for reading and writing
3 register data from a UART-based device such as a TMC2209
4
5 Written with help by Claude!
6 https://claude.ai/chat/335f50b1-3dd8-435e-9139-57ec7ca26a3c (at this time
7 chats are not shareable :(
8*/
9
10#include "Adafruit_BusIO_Register.h"
11#include "Adafruit_GenericDevice.h"
12
13// Debugging macros
14#define DEBUG_SERIAL Serial
15
16#ifdef DEBUG_SERIAL
17#define DEBUG_PRINT(x) DEBUG_SERIAL.print(x)
18#define DEBUG_PRINTLN(x) DEBUG_SERIAL.println(x)
19#define DEBUG_PRINT_HEX(x) \
20 do { \
21 if (x < 0x10) \
22 DEBUG_SERIAL.print('0'); \
23 DEBUG_SERIAL.print(x, HEX); \
24 DEBUG_SERIAL.print(' '); \
25 } while (0)
26#else
27#define DEBUG_PRINT(x)
28#define DEBUG_PRINTLN(x)
29#define DEBUG_PRINT_HEX(x)
30#endif
31
32#define TMC2209_IOIN 0x06
33
34class TMC2209_UART {
35private:
36 Stream *_uart_stream;
37 uint8_t _addr;
38
39 static bool uart_read(void *thiz, uint8_t *buffer, size_t len) {
40 TMC2209_UART *dev = (TMC2209_UART *)thiz;
41 uint16_t timeout = 100;
42 while (dev->_uart_stream->available() < len && timeout--) {
43 delay(1);
44 }
45 if (timeout == 0) {
46 DEBUG_PRINTLN("Read timeout!");
47 return false;
48 }
49
50 DEBUG_PRINT("Reading: ");
51 for (size_t i = 0; i < len; i++) {
52 buffer[i] = dev->_uart_stream->read();
53 DEBUG_PRINT_HEX(buffer[i]);
54 }
55 DEBUG_PRINTLN("");
56
57 return true;
58 }
59
60 static bool uart_write(void *thiz, const uint8_t *buffer, size_t len) {
61 TMC2209_UART *dev = (TMC2209_UART *)thiz;
62 DEBUG_PRINT("Writing: ");
63 for (size_t i = 0; i < len; i++) {
64 DEBUG_PRINT_HEX(buffer[i]);
65 }
66 DEBUG_PRINTLN("");
67
68 dev->_uart_stream->write(buffer, len);
69 return true;
70 }
71
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();
77
78 uint8_t packet[4] = {0x05, uint8_t(dev->_addr << 1), addr_buf[0], 0x00};
79
80 packet[3] = calcCRC(packet, 3);
81 if (!uart_write(thiz, packet, 4))
82 return false;
83
84 // Read back echo
85 uint8_t echo[4];
86 if (!uart_read(thiz, echo, 4))
87 return false;
88
89 // Verify echo
90 for (uint8_t i = 0; i < 4; i++) {
91 if (echo[i] != packet[i]) {
92 DEBUG_PRINTLN("Echo mismatch");
93 return false;
94 }
95 }
96
97 uint8_t response[8]; // sync + 0xFF + reg + 4 data bytes + CRC
98 if (!uart_read(thiz, response, 8))
99 return false;
100
101 // Verify response
102 if (response[0] != 0x05) {
103 DEBUG_PRINTLN("Invalid sync byte");
104 return false;
105 }
106
107 if (response[1] != 0xFF) {
108 DEBUG_PRINTLN("Invalid reply address");
109 return false;
110 }
111
112 if (response[2] != addr_buf[0]) {
113 DEBUG_PRINTLN("Register mismatch");
114 return false;
115 }
116
117 uint8_t crc = calcCRC(response, 7);
118 if (crc != response[7]) {
119 DEBUG_PRINTLN("CRC mismatch");
120 return false;
121 }
122
123 memcpy(data, &response[3], 4);
124 return true;
125 }
126
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();
132
133 uint8_t packet[8] = {0x05,
134 uint8_t(dev->_addr << 1),
135 uint8_t(addr_buf[0] | 0x80),
136 data[0],
137 data[1],
138 data[2],
139 data[3],
140 0x00};
141
142 packet[7] = calcCRC(packet, 7);
143 if (!uart_write(thiz, packet, 8))
144 return false;
145
146 uint8_t echo[8];
147 if (!uart_read(thiz, echo, 8))
148 return false;
149
150 for (uint8_t i = 0; i < 8; i++) {
151 if (echo[i] != packet[i]) {
152 DEBUG_PRINTLN("Write echo mismatch");
153 return false;
154 }
155 }
156
157 return true;
158 }
159
160 static uint8_t calcCRC(uint8_t *data, uint8_t length) {
161 uint8_t crc = 0;
162 for (uint8_t i = 0; i < length; i++) {
163 uint8_t currentByte = data[i];
164 for (uint8_t j = 0; j < 8; j++) {
165 if ((crc >> 7) ^ (currentByte & 0x01)) {
166 crc = (crc << 1) ^ 0x07;
167 } else {
168 crc = crc << 1;
169 }
170 currentByte = currentByte >> 1;
171 }
172 }
173 return crc;
174 }
175
176public:
177 TMC2209_UART(Stream *serial, uint8_t addr)
178 : _uart_stream(serial), _addr(addr) {}
179
180 Adafruit_GenericDevice *createDevice() {
181 return new Adafruit_GenericDevice(this, uart_read, uart_write, uart_readreg,
182 uart_writereg);
183 }
184};
185
186void setup() {
187 Serial.begin(115200);
188 while (!Serial)
189 ;
190 delay(100);
191 Serial.println("TMC2209 Generic Device register read/write test!");
192
193 Serial1.begin(115200);
194
195 TMC2209_UART uart(&Serial1, 0);
196 Adafruit_GenericDevice *device = uart.createDevice();
197 device->begin();
198
199 // Create register object for IOIN
200 Adafruit_BusIO_Register ioin_reg(device,
201 TMC2209_IOIN, // device and register address
202 4, // width = 4 bytes
203 MSBFIRST, // byte order
204 1); // address width = 1 byte
205 Serial.print("IOIN = 0x");
206 Serial.println(ioin_reg.read(), HEX);
207
208 // Create RegisterBits for VERSION field (bits 31:24)
209 Adafruit_BusIO_RegisterBits version_bits(
210 &ioin_reg, 8, 24); // 8 bits wide, starting at bit 24
211
212 Serial.println("Reading VERSION...");
213 uint8_t version = version_bits.read();
214
215 Serial.print("VERSION = 0x");
216 Serial.println(version, HEX);
217}
218
219void loop() { delay(1000); }