Files
Craig Swank e7f90166ad tmc2209 bug fixes (#755)
* Make write buffer big enough for crc
* crc according to datasheet
* fix build
* a correct crc func already exists
2025-05-20 12:27:30 +02:00

113 lines
3.0 KiB
Go

//go:build tinygo
package tmc2209
import (
"machine"
"time"
)
// CustomError is a lightweight error type used for TinyGo compatibility.
type CustomError string
func (e CustomError) Error() string {
return string(e)
}
// UARTComm implements RegisterComm for UART-based communication
type UARTComm struct {
uart machine.UART
address uint8
}
// NewUARTComm creates a new UARTComm instance.
func NewUARTComm(uart machine.UART, address uint8) *UARTComm {
return &UARTComm{
uart: uart,
address: address,
}
}
// Setup initializes the UART communication with the TMC2209.
func (comm *UARTComm) Setup() error {
// Check if UART is initialized
if comm.uart == (machine.UART{}) {
return CustomError("UART not initialized")
}
// Configure the UART interface with the desired baud rate and settings
err := comm.uart.Configure(machine.UARTConfig{
BaudRate: 115200,
})
if err != nil {
return CustomError("Failed to configure UART")
}
// No built-in timeout in TinyGo, so timeout will be handled in the read/write methods
return nil
}
// WriteRegister sends a register write command to the TMC2209 with a timeout.
func (comm *UARTComm) WriteRegister(register uint8, value uint32, driverIndex uint8) error {
buffer := []byte{
0x05, // Sync byte
comm.address, // Slave address
register | 0x80, // Write command (set MSB to 1 for write)
byte((value >> 24) & 0xFF), // MSB of value
byte((value >> 16) & 0xFF), // Middle byte
byte((value >> 8) & 0xFF), // Next byte
byte(value & 0xFF), // LSB of value
0, // CRC
}
buffer[7] = CalculateCRC(buffer[:7])
// Write the data to the TMC2209
done := make(chan error, 1)
go func() {
comm.uart.Write(buffer)
done <- nil
}()
// Implementing timeout using a 100ms timer
select {
case err := <-done:
return err
case <-time.After(100 * time.Millisecond): // Timeout after 100ms
return CustomError("write timeout")
}
}
// ReadRegister sends a register read command to the TMC2209 with a timeout.
func (comm *UARTComm) ReadRegister(register uint8, driverIndex uint8) (uint32, error) {
var writeBuffer [4]byte
writeBuffer[0] = 0x05 // Sync byte
writeBuffer[1] = 0x00 // Slave address
writeBuffer[2] = register & 0x7F // Read command (MSB clear for read)
writeBuffer[3] = CalculateCRC(writeBuffer[:3])
// Send the read command
done := make(chan []byte, 1)
go func() {
comm.uart.Write(writeBuffer[:])
readBuffer := make([]byte, 8)
comm.uart.Read(readBuffer)
done <- readBuffer
}()
// Implementing timeout using a 100ms timer
select {
case readBuffer := <-done:
checksum := CalculateCRC(readBuffer[:7])
if checksum != readBuffer[7] {
return 0, CustomError("checksum error")
}
// Return the value from the register
return uint32(readBuffer[3])<<24 | uint32(readBuffer[4])<<16 | uint32(readBuffer[5])<<8 | uint32(readBuffer[6]), nil
case <-time.After(100 * time.Millisecond): // Timeout after 100ms
return 0, CustomError("read timeout")
}
}