mirror of
https://github.com/tinygo-org/drivers.git
synced 2026-07-26 10:38:41 +00:00
e7f90166ad
* Make write buffer big enough for crc * crc according to datasheet * fix build * a correct crc func already exists
113 lines
3.0 KiB
Go
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")
|
|
}
|
|
}
|