woops fix serial

This commit is contained in:
ladyada 2025-01-08 10:15:09 -05:00
parent c0237922d3
commit 2663ca269f
2 changed files with 321 additions and 321 deletions

View File

@ -1,246 +1,246 @@
/* /*
Advanced example of using bstracted transport for reading and writing Advanced example of using bstracted transport for reading and writing
register data from a UART-based device such as a TMC2209 register data from a UART-based device such as a TMC2209
Written with help by Claude! https://claude.ai/chat/335f50b1-3dd8-435e-9139-57ec7ca26a3c Written with help by Claude! https://claude.ai/chat/335f50b1-3dd8-435e-9139-57ec7ca26a3c
(at this time chats are not shareable :( (at this time chats are not shareable :(
*/ */
#include "Adafruit_BusIO_Register.h" #include "Adafruit_BusIO_Register.h"
#include "Adafruit_GenericDevice.h" #include "Adafruit_GenericDevice.h"
// Debugging macros // Debugging macros
//#define DEBUG_SERIAL Serial //#define DEBUG_SERIAL Serial
#ifdef DEBUG_SERIAL #ifdef DEBUG_SERIAL
#define DEBUG_PRINT(x) DEBUG_SERIAL.print(x) #define DEBUG_PRINT(x) DEBUG_SERIAL.print(x)
#define DEBUG_PRINTLN(x) DEBUG_SERIAL.println(x) #define DEBUG_PRINTLN(x) DEBUG_SERIAL.println(x)
#define DEBUG_PRINT_HEX(x) \ #define DEBUG_PRINT_HEX(x) \
do { \ do { \
if (x < 0x10) \ if (x < 0x10) \
DEBUG_SERIAL.print('0'); \ DEBUG_SERIAL.print('0'); \
DEBUG_SERIAL.print(x, HEX); \ DEBUG_SERIAL.print(x, HEX); \
DEBUG_SERIAL.print(' '); \ DEBUG_SERIAL.print(' '); \
} while (0) } while (0)
#else #else
#define DEBUG_PRINT(x) #define DEBUG_PRINT(x)
#define DEBUG_PRINTLN(x) #define DEBUG_PRINTLN(x)
#define DEBUG_PRINT_HEX(x) #define DEBUG_PRINT_HEX(x)
#endif #endif
// Add IOIN register definition // Add IOIN register definition
#define TMC2209_IOIN 0x06 #define TMC2209_IOIN 0x06
class TMC2209_UART { class TMC2209_UART {
private: private:
static TMC2209_UART *_instance; static TMC2209_UART *_instance;
Stream *_uart_stream; Stream *_uart_stream;
uint8_t _addr; uint8_t _addr;
static bool uart_read_impl(uint8_t *buffer, size_t len) { static bool uart_read_impl(uint8_t *buffer, size_t len) {
return _instance->uart_read_fn(buffer, len); return _instance->uart_read_fn(buffer, len);
} }
static bool uart_write_impl(const uint8_t *buffer, size_t len) { static bool uart_write_impl(const uint8_t *buffer, size_t len) {
return _instance->uart_write_fn(buffer, len); return _instance->uart_write_fn(buffer, len);
} }
static bool uart_readreg_impl(uint8_t *addr_buf, uint8_t addrsiz, static bool uart_readreg_impl(uint8_t *addr_buf, uint8_t addrsiz,
uint8_t *data, uint16_t datalen) { uint8_t *data, uint16_t datalen) {
return _instance->uart_readreg_fn(addr_buf, addrsiz, data, datalen); return _instance->uart_readreg_fn(addr_buf, addrsiz, data, datalen);
} }
static bool uart_writereg_impl(uint8_t *addr_buf, uint8_t addrsiz, static bool uart_writereg_impl(uint8_t *addr_buf, uint8_t addrsiz,
const uint8_t *data, uint16_t datalen) { const uint8_t *data, uint16_t datalen) {
return _instance->uart_writereg_fn(addr_buf, addrsiz, data, datalen); return _instance->uart_writereg_fn(addr_buf, addrsiz, data, datalen);
} }
bool uart_read_fn(uint8_t *buffer, size_t len) { bool uart_read_fn(uint8_t *buffer, size_t len) {
uint16_t timeout = 100; uint16_t timeout = 100;
while (_uart_stream->available() < len && timeout--) { while (_uart_stream->available() < len && timeout--) {
delay(1); delay(1);
} }
if (timeout == 0) { if (timeout == 0) {
DEBUG_PRINTLN("Read timeout!"); DEBUG_PRINTLN("Read timeout!");
return false; return false;
} }
DEBUG_PRINT("Reading: "); DEBUG_PRINT("Reading: ");
for (size_t i = 0; i < len; i++) { for (size_t i = 0; i < len; i++) {
buffer[i] = _uart_stream->read(); buffer[i] = _uart_stream->read();
DEBUG_PRINT_HEX(buffer[i]); DEBUG_PRINT_HEX(buffer[i]);
} }
DEBUG_PRINTLN(""); DEBUG_PRINTLN("");
return true; return true;
} }
bool uart_write_fn(const uint8_t *buffer, size_t len) { bool uart_write_fn(const uint8_t *buffer, size_t len) {
DEBUG_PRINT("Writing: "); DEBUG_PRINT("Writing: ");
for (size_t i = 0; i < len; i++) { for (size_t i = 0; i < len; i++) {
DEBUG_PRINT_HEX(buffer[i]); DEBUG_PRINT_HEX(buffer[i]);
} }
DEBUG_PRINTLN(""); DEBUG_PRINTLN("");
_uart_stream->write(buffer, len); _uart_stream->write(buffer, len);
return true; return true;
} }
bool uart_readreg_fn(uint8_t *addr_buf, uint8_t addrsiz, uint8_t *data, bool uart_readreg_fn(uint8_t *addr_buf, uint8_t addrsiz, uint8_t *data,
uint16_t datalen) { uint16_t datalen) {
while (_uart_stream->available()) while (_uart_stream->available())
_uart_stream->read(); _uart_stream->read();
uint8_t packet[4] = {0x05, uint8_t(_addr << 1), addr_buf[0], 0x00}; uint8_t packet[4] = {0x05, uint8_t(_addr << 1), addr_buf[0], 0x00};
packet[3] = calcCRC(packet, 3); packet[3] = calcCRC(packet, 3);
if (!uart_write_impl(packet, 4)) if (!uart_write_impl(packet, 4))
return false; return false;
// Read back echo // Read back echo
uint8_t echo[4]; uint8_t echo[4];
if (!uart_read_impl(echo, 4)) if (!uart_read_impl(echo, 4))
return false; return false;
// Verify echo // Verify echo
for (uint8_t i = 0; i < 4; i++) { for (uint8_t i = 0; i < 4; i++) {
if (echo[i] != packet[i]) { if (echo[i] != packet[i]) {
DEBUG_PRINTLN("Echo mismatch"); DEBUG_PRINTLN("Echo mismatch");
return false; return false;
} }
} }
uint8_t response[8]; // sync + 0xFF + reg + 4 data bytes + CRC uint8_t response[8]; // sync + 0xFF + reg + 4 data bytes + CRC
if (!uart_read_impl(response, 8)) if (!uart_read_impl(response, 8))
return false; return false;
// Verify response // Verify response
if (response[0] != 0x05) { if (response[0] != 0x05) {
DEBUG_PRINTLN("Invalid sync byte"); DEBUG_PRINTLN("Invalid sync byte");
return false; return false;
} }
// Verify 0xFF address byte // Verify 0xFF address byte
if (response[1] != 0xFF) { if (response[1] != 0xFF) {
DEBUG_PRINTLN("Invalid reply address"); DEBUG_PRINTLN("Invalid reply address");
return false; return false;
} }
// Verify register address matches our request // Verify register address matches our request
if (response[2] != addr_buf[0]) { if (response[2] != addr_buf[0]) {
DEBUG_PRINTLN("Register mismatch"); DEBUG_PRINTLN("Register mismatch");
return false; return false;
} }
// Verify CRC // Verify CRC
uint8_t crc = calcCRC(response, 7); // Calculate CRC of all but last byte uint8_t crc = calcCRC(response, 7); // Calculate CRC of all but last byte
if (crc != response[7]) { if (crc != response[7]) {
DEBUG_PRINTLN("CRC mismatch"); DEBUG_PRINTLN("CRC mismatch");
return false; return false;
} }
// Copy the data bytes // Copy the data bytes
memcpy(data, &response[3], 4); memcpy(data, &response[3], 4);
return true; return true;
} }
bool uart_writereg_fn(uint8_t *addr_buf, uint8_t addrsiz, const uint8_t *data, bool uart_writereg_fn(uint8_t *addr_buf, uint8_t addrsiz, const uint8_t *data,
uint16_t datalen) { uint16_t datalen) {
while (_uart_stream->available()) while (_uart_stream->available())
_uart_stream->read(); _uart_stream->read();
uint8_t packet[8] = {0x05, uint8_t packet[8] = {0x05,
uint8_t(_addr << 1), uint8_t(_addr << 1),
uint8_t(addr_buf[0] | 0x80), uint8_t(addr_buf[0] | 0x80),
data[0], data[0],
data[1], data[1],
data[2], data[2],
data[3], data[3],
0x00}; 0x00};
packet[7] = calcCRC(packet, 7); packet[7] = calcCRC(packet, 7);
if (!uart_write_impl(packet, 8)) if (!uart_write_impl(packet, 8))
return false; return false;
// Read and verify echo // Read and verify echo
uint8_t echo[8]; uint8_t echo[8];
if (!uart_read_impl(echo, 8)) if (!uart_read_impl(echo, 8))
return false; return false;
// Verify echo matches what we sent // Verify echo matches what we sent
for (uint8_t i = 0; i < 8; i++) { for (uint8_t i = 0; i < 8; i++) {
if (echo[i] != packet[i]) { if (echo[i] != packet[i]) {
DEBUG_PRINTLN("Write echo mismatch"); DEBUG_PRINTLN("Write echo mismatch");
return false; return false;
} }
} }
return true; return true;
} }
static uint8_t calcCRC(uint8_t *data, uint8_t length) { static uint8_t calcCRC(uint8_t *data, uint8_t length) {
uint8_t crc = 0; uint8_t crc = 0;
for (uint8_t i = 0; i < length; i++) { for (uint8_t i = 0; i < length; i++) {
uint8_t currentByte = data[i]; uint8_t currentByte = data[i];
for (uint8_t j = 0; j < 8; j++) { for (uint8_t j = 0; j < 8; j++) {
if ((crc >> 7) ^ (currentByte & 0x01)) { if ((crc >> 7) ^ (currentByte & 0x01)) {
crc = (crc << 1) ^ 0x07; crc = (crc << 1) ^ 0x07;
} else { } else {
crc = crc << 1; crc = crc << 1;
} }
currentByte = currentByte >> 1; currentByte = currentByte >> 1;
} }
} }
return crc; return crc;
} }
public: public:
TMC2209_UART(Stream *serial, uint8_t addr) TMC2209_UART(Stream *serial, uint8_t addr)
: _uart_stream(serial), _addr(addr) { : _uart_stream(serial), _addr(addr) {
_instance = this; _instance = this;
} }
Adafruit_GenericDevice *createDevice() { Adafruit_GenericDevice *createDevice() {
return new Adafruit_GenericDevice(uart_read_impl, uart_write_impl, return new Adafruit_GenericDevice(uart_read_impl, uart_write_impl,
uart_readreg_impl, uart_writereg_impl); uart_readreg_impl, uart_writereg_impl);
} }
}; };
TMC2209_UART *TMC2209_UART::_instance = nullptr; TMC2209_UART *TMC2209_UART::_instance = nullptr;
void setup() { void setup() {
Serial.begin(115200); Serial.begin(115200);
while (!Serial) while (!Serial)
; ;
delay(100); delay(100);
Serial.println("TMC2209 Generic Device register read/write test!"); Serial.println("TMC2209 Generic Device register read/write test!");
Serial2.begin(115200); Serial1.begin(115200);
TMC2209_UART uart(&Serial2, 0); TMC2209_UART uart(&Serial1, 0);
Adafruit_GenericDevice *device = uart.createDevice(); Adafruit_GenericDevice *device = uart.createDevice();
device->begin(); device->begin();
// Create register object for IOIN // Create register object for IOIN
Adafruit_BusIO_Register ioin_reg(device, Adafruit_BusIO_Register ioin_reg(device,
TMC2209_IOIN, // device and register address TMC2209_IOIN, // device and register address
4, // width = 4 bytes 4, // width = 4 bytes
MSBFIRST, // byte order MSBFIRST, // byte order
1); // address width = 1 byte 1); // address width = 1 byte
Serial.print("IOIN = 0x"); Serial.print("IOIN = 0x");
Serial.println(ioin_reg.read(), HEX); Serial.println(ioin_reg.read(), HEX);
// Create RegisterBits for VERSION field (bits 28:24) // Create RegisterBits for VERSION field (bits 28:24)
Adafruit_BusIO_RegisterBits version_bits( Adafruit_BusIO_RegisterBits version_bits(
&ioin_reg, 8, 24); // 8 bits wide, starting at bit 24 &ioin_reg, 8, 24); // 8 bits wide, starting at bit 24
Serial.println("Reading VERSION..."); Serial.println("Reading VERSION...");
uint8_t version = version_bits.read(); uint8_t version = version_bits.read();
Serial.print("VERSION = 0x"); Serial.print("VERSION = 0x");
Serial.println(version, HEX); Serial.println(version, HEX);
} }
void loop() { delay(1000); } void loop() { delay(1000); }

View File

@ -1,75 +1,75 @@
/* /*
Abstracted transport for reading and writing data from a UART-based Abstracted transport for reading and writing data from a UART-based
device such as a TMC2209 device such as a TMC2209
Written with help by Claude! https://claude.ai/chat/335f50b1-3dd8-435e-9139-57ec7ca26a3c Written with help by Claude! https://claude.ai/chat/335f50b1-3dd8-435e-9139-57ec7ca26a3c
(at this time chats are not shareable :( (at this time chats are not shareable :(
*/ */
#include "Adafruit_GenericDevice.h" #include "Adafruit_GenericDevice.h"
Stream *uart_stream; // Will hold the pointer to our Stream object Stream *uart_stream; // Will hold the pointer to our Stream object
Adafruit_GenericDevice *create_uart_device(Stream *serial_port) { Adafruit_GenericDevice *create_uart_device(Stream *serial_port) {
uart_stream = serial_port; // Store the Stream pointer uart_stream = serial_port; // Store the Stream pointer
auto uart_write = [](const uint8_t *buffer, size_t len) -> bool { auto uart_write = [](const uint8_t *buffer, size_t len) -> bool {
uart_stream->write(buffer, len); uart_stream->write(buffer, len);
return true; return true;
}; };
auto uart_read = [](uint8_t *buffer, size_t len) -> bool { auto uart_read = [](uint8_t *buffer, size_t len) -> bool {
uint16_t timeout = 100; uint16_t timeout = 100;
while (uart_stream->available() < len && timeout--) { while (uart_stream->available() < len && timeout--) {
delay(1); delay(1);
} }
if (timeout == 0) { if (timeout == 0) {
return false; return false;
} }
for (size_t i = 0; i < len; i++) { for (size_t i = 0; i < len; i++) {
buffer[i] = uart_stream->read(); buffer[i] = uart_stream->read();
} }
return true; return true;
}; };
return new Adafruit_GenericDevice(uart_read, uart_write); return new Adafruit_GenericDevice(uart_read, uart_write);
} }
void setup() { void setup() {
Serial.begin(115200); Serial.begin(115200);
while (!Serial) while (!Serial)
; ;
delay(100); delay(100);
Serial.println("Generic Device test!"); Serial.println("Generic Device test!");
Serial2.begin(115200); Serial1.begin(115200);
Adafruit_GenericDevice *device = create_uart_device(&Serial2); Adafruit_GenericDevice *device = create_uart_device(&Serial1);
device->begin(); device->begin();
uint8_t write_buf[4] = {0x5, 0x0, 0x0, 0x48}; uint8_t write_buf[4] = {0x5, 0x0, 0x0, 0x48};
uint8_t read_buf[8]; uint8_t read_buf[8];
Serial.println("Writing data..."); Serial.println("Writing data...");
if (!device->write(write_buf, 4)) { if (!device->write(write_buf, 4)) {
Serial.println("Write failed!"); Serial.println("Write failed!");
return; return;
} }
Serial.println("Reading response..."); Serial.println("Reading response...");
if (!device->read(read_buf, 8)) { if (!device->read(read_buf, 8)) {
Serial.println("Read failed!"); Serial.println("Read failed!");
return; return;
} }
Serial.print("Got response: "); Serial.print("Got response: ");
for (int i = 0; i < 8; i++) { for (int i = 0; i < 8; i++) {
Serial.print("0x"); Serial.print("0x");
Serial.print(read_buf[i], HEX); Serial.print(read_buf[i], HEX);
Serial.print(" "); Serial.print(" ");
} }
Serial.println(); Serial.println();
} }
void loop() { delay(1000); } void loop() { delay(1000); }