-
Notifications
You must be signed in to change notification settings - Fork 271
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
2 changed files
with
304 additions
and
0 deletions.
There are no files selected for viewing
237 changes: 237 additions & 0 deletions
237
examples/genericdevice_uartregtest/genericdevice_uartregtest.ino
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,237 @@ | ||
#include "Adafruit_BusIO_Register.h" | ||
#include "Adafruit_GenericDevice.h" | ||
|
||
// Debugging macros | ||
//#define DEBUG_SERIAL Serial | ||
|
||
#ifdef DEBUG_SERIAL | ||
#define DEBUG_PRINT(x) DEBUG_SERIAL.print(x) | ||
#define DEBUG_PRINTLN(x) DEBUG_SERIAL.println(x) | ||
#define DEBUG_PRINT_HEX(x) \ | ||
do { \ | ||
if (x < 0x10) \ | ||
DEBUG_SERIAL.print('0'); \ | ||
DEBUG_SERIAL.print(x, HEX); \ | ||
DEBUG_SERIAL.print(' '); \ | ||
} while (0) | ||
#else | ||
#define DEBUG_PRINT(x) | ||
#define DEBUG_PRINTLN(x) | ||
#define DEBUG_PRINT_HEX(x) | ||
#endif | ||
|
||
// Add IOIN register definition | ||
#define TMC2209_IOIN 0x06 | ||
|
||
class TMC2209_UART { | ||
private: | ||
static TMC2209_UART *_instance; | ||
Stream *_uart_stream; | ||
uint8_t _addr; | ||
|
||
static bool uart_read_impl(uint8_t *buffer, size_t len) { | ||
return _instance->uart_read_fn(buffer, len); | ||
} | ||
|
||
static bool uart_write_impl(const uint8_t *buffer, size_t len) { | ||
return _instance->uart_write_fn(buffer, len); | ||
} | ||
|
||
static bool uart_readreg_impl(uint8_t *addr_buf, uint8_t addrsiz, | ||
uint8_t *data, uint16_t datalen) { | ||
return _instance->uart_readreg_fn(addr_buf, addrsiz, data, datalen); | ||
} | ||
|
||
static bool uart_writereg_impl(uint8_t *addr_buf, uint8_t addrsiz, | ||
const uint8_t *data, uint16_t datalen) { | ||
return _instance->uart_writereg_fn(addr_buf, addrsiz, data, datalen); | ||
} | ||
|
||
bool uart_read_fn(uint8_t *buffer, size_t len) { | ||
uint16_t timeout = 100; | ||
while (_uart_stream->available() < len && timeout--) { | ||
delay(1); | ||
} | ||
if (timeout == 0) { | ||
DEBUG_PRINTLN("Read timeout!"); | ||
return false; | ||
} | ||
|
||
DEBUG_PRINT("Reading: "); | ||
for (size_t i = 0; i < len; i++) { | ||
buffer[i] = _uart_stream->read(); | ||
DEBUG_PRINT_HEX(buffer[i]); | ||
} | ||
DEBUG_PRINTLN(""); | ||
|
||
return true; | ||
} | ||
|
||
bool uart_write_fn(const uint8_t *buffer, size_t len) { | ||
DEBUG_PRINT("Writing: "); | ||
for (size_t i = 0; i < len; i++) { | ||
DEBUG_PRINT_HEX(buffer[i]); | ||
} | ||
DEBUG_PRINTLN(""); | ||
|
||
_uart_stream->write(buffer, len); | ||
return true; | ||
} | ||
|
||
bool uart_readreg_fn(uint8_t *addr_buf, uint8_t addrsiz, uint8_t *data, | ||
uint16_t datalen) { | ||
while (_uart_stream->available()) | ||
_uart_stream->read(); | ||
|
||
uint8_t packet[4] = {0x05, uint8_t(_addr << 1), addr_buf[0], 0x00}; | ||
|
||
packet[3] = calcCRC(packet, 3); | ||
if (!uart_write_impl(packet, 4)) | ||
return false; | ||
|
||
// Read back echo | ||
uint8_t echo[4]; | ||
if (!uart_read_impl(echo, 4)) | ||
return false; | ||
|
||
// Verify echo | ||
for (uint8_t i = 0; i < 4; i++) { | ||
if (echo[i] != packet[i]) { | ||
DEBUG_PRINTLN("Echo mismatch"); | ||
return false; | ||
} | ||
} | ||
|
||
uint8_t response[8]; // sync + 0xFF + reg + 4 data bytes + CRC | ||
if (!uart_read_impl(response, 8)) | ||
return false; | ||
|
||
// Verify response | ||
if (response[0] != 0x05) { | ||
DEBUG_PRINTLN("Invalid sync byte"); | ||
return false; | ||
} | ||
|
||
// Verify 0xFF address byte | ||
if (response[1] != 0xFF) { | ||
DEBUG_PRINTLN("Invalid reply address"); | ||
return false; | ||
} | ||
|
||
// Verify register address matches our request | ||
if (response[2] != addr_buf[0]) { | ||
DEBUG_PRINTLN("Register mismatch"); | ||
return false; | ||
} | ||
|
||
// Verify CRC | ||
uint8_t crc = calcCRC(response, 7); // Calculate CRC of all but last byte | ||
if (crc != response[7]) { | ||
DEBUG_PRINTLN("CRC mismatch"); | ||
return false; | ||
} | ||
|
||
// Copy the data bytes | ||
memcpy(data, &response[3], 4); | ||
|
||
return true; | ||
} | ||
|
||
bool uart_writereg_fn(uint8_t *addr_buf, uint8_t addrsiz, const uint8_t *data, | ||
uint16_t datalen) { | ||
while (_uart_stream->available()) | ||
_uart_stream->read(); | ||
|
||
uint8_t packet[8] = {0x05, | ||
uint8_t(_addr << 1), | ||
uint8_t(addr_buf[0] | 0x80), | ||
data[0], | ||
data[1], | ||
data[2], | ||
data[3], | ||
0x00}; | ||
|
||
packet[7] = calcCRC(packet, 7); | ||
if (!uart_write_impl(packet, 8)) | ||
return false; | ||
|
||
// Read and verify echo | ||
uint8_t echo[8]; | ||
if (!uart_read_impl(echo, 8)) | ||
return false; | ||
|
||
// Verify echo matches what we sent | ||
for (uint8_t i = 0; i < 8; i++) { | ||
if (echo[i] != packet[i]) { | ||
DEBUG_PRINTLN("Write echo mismatch"); | ||
return false; | ||
} | ||
} | ||
|
||
return true; | ||
} | ||
|
||
static uint8_t calcCRC(uint8_t *data, uint8_t length) { | ||
uint8_t crc = 0; | ||
for (uint8_t i = 0; i < length; i++) { | ||
uint8_t currentByte = data[i]; | ||
for (uint8_t j = 0; j < 8; j++) { | ||
if ((crc >> 7) ^ (currentByte & 0x01)) { | ||
crc = (crc << 1) ^ 0x07; | ||
} else { | ||
crc = crc << 1; | ||
} | ||
currentByte = currentByte >> 1; | ||
} | ||
} | ||
return crc; | ||
} | ||
|
||
public: | ||
TMC2209_UART(Stream *serial, uint8_t addr) | ||
: _uart_stream(serial), _addr(addr) { | ||
_instance = this; | ||
} | ||
|
||
Adafruit_GenericDevice *createDevice() { | ||
return new Adafruit_GenericDevice(uart_read_impl, uart_write_impl, | ||
uart_readreg_impl, uart_writereg_impl); | ||
} | ||
}; | ||
|
||
TMC2209_UART *TMC2209_UART::_instance = nullptr; | ||
|
||
void setup() { | ||
Serial.begin(115200); | ||
while (!Serial) | ||
; | ||
delay(100); | ||
Serial.println("TMC2209 Generic Device register read/write test!"); | ||
|
||
Serial2.begin(115200); | ||
|
||
TMC2209_UART uart(&Serial2, 0); | ||
Adafruit_GenericDevice *device = uart.createDevice(); | ||
device->begin(); | ||
|
||
// Create register object for IOIN | ||
Adafruit_BusIO_Register ioin_reg(device, | ||
TMC2209_IOIN, // device and register address | ||
4, // width = 4 bytes | ||
MSBFIRST, // byte order | ||
1); // address width = 1 byte | ||
Serial.print("IOIN = 0x"); | ||
Serial.println(ioin_reg.read(), HEX); | ||
|
||
// Create RegisterBits for VERSION field (bits 28:24) | ||
Adafruit_BusIO_RegisterBits version_bits( | ||
&ioin_reg, 8, 24); // 8 bits wide, starting at bit 24 | ||
|
||
Serial.println("Reading VERSION..."); | ||
uint8_t version = version_bits.read(); | ||
|
||
Serial.print("VERSION = 0x"); | ||
Serial.println(version, HEX); | ||
} | ||
|
||
void loop() { delay(1000); } |
67 changes: 67 additions & 0 deletions
67
examples/genericdevice_uarttest/genericdevice_uarttest.ino
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,67 @@ | ||
#include "Adafruit_GenericDevice.h" | ||
|
||
Stream *uart_stream; // Will hold the pointer to our Stream object | ||
|
||
Adafruit_GenericDevice *create_uart_device(Stream *serial_port) { | ||
uart_stream = serial_port; // Store the Stream pointer | ||
|
||
auto uart_write = [](const uint8_t *buffer, size_t len) -> bool { | ||
uart_stream->write(buffer, len); | ||
return true; | ||
}; | ||
|
||
auto uart_read = [](uint8_t *buffer, size_t len) -> bool { | ||
uint16_t timeout = 100; | ||
while (uart_stream->available() < len && timeout--) { | ||
delay(1); | ||
} | ||
if (timeout == 0) { | ||
return false; | ||
} | ||
for (size_t i = 0; i < len; i++) { | ||
buffer[i] = uart_stream->read(); | ||
} | ||
return true; | ||
}; | ||
|
||
return new Adafruit_GenericDevice(uart_read, uart_write); | ||
} | ||
|
||
void setup() { | ||
Serial.begin(115200); | ||
while (!Serial) | ||
; | ||
delay(100); | ||
|
||
Serial.println("Generic Device test!"); | ||
|
||
Serial2.begin(115200); | ||
|
||
Adafruit_GenericDevice *device = create_uart_device(&Serial2); | ||
device->begin(); | ||
|
||
uint8_t write_buf[4] = {0x5, 0x0, 0x0, 0x48}; | ||
uint8_t read_buf[8]; | ||
|
||
Serial.println("Writing data..."); | ||
if (!device->write(write_buf, 4)) { | ||
Serial.println("Write failed!"); | ||
return; | ||
} | ||
|
||
Serial.println("Reading response..."); | ||
if (!device->read(read_buf, 8)) { | ||
Serial.println("Read failed!"); | ||
return; | ||
} | ||
|
||
Serial.print("Got response: "); | ||
for (int i = 0; i < 8; i++) { | ||
Serial.print("0x"); | ||
Serial.print(read_buf[i], HEX); | ||
Serial.print(" "); | ||
} | ||
Serial.println(); | ||
} | ||
|
||
void loop() { delay(1000); } |