Files
drivers/tmc5160/uartcomm.go
T
Amken USA 486949686c Added TMC5160 support (#725)
TMC5160: Added TMC5160 support

* Added example code for tmc5160 and smoke test
* Update go.mod
* Updated mod file
* Cleaned up commented out code and updated readme.
* ran go fmt
* Fixed setrampspeed func
* Removed spi1 pin setup in example.go. Renamed SPIComm to spicomm.go
* Removed unused test file
* Removed commented line
2025-01-18 07:49:00 +01:00

102 lines
2.9 KiB
Go

//go:build uart
package tmc5160
import (
"machine"
"time"
)
// UARTComm implements RegisterComm for UART-based communication with Driver.
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 Driver.
func (comm *UARTComm) Setup() error {
if comm.uart == (machine.UART{}) {
return CustomError("UART not initialized")
}
err := comm.uart.Configure(machine.UARTConfig{
BaudRate: 115200,
})
if err != nil {
return CustomError("Failed to configure UART")
}
return nil
}
// WriteRegister sends a register write command to the Driver.
// Prepare the data packet (sync byte + address + register + data + checksum)
func (comm *UARTComm) WriteRegister(register uint8, value uint32, driverIndex uint8) error {
buffer := []byte{
0x05, // Sync byte
comm.address, // Slave address
register | 0x80, // Write command (MSB set 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
}
checksum := byte(0)
for _, b := range buffer[:7] {
checksum ^= b
}
buffer[7] = checksum // Set checksum byte
// Write the data to the Driver
done := make(chan error, 1)
go func() {
comm.uart.Write(buffer)
done <- nil
}()
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 Driver.
func (comm *UARTComm) ReadRegister(register uint8, driverIndex uint8) (uint32, error) {
// Prepare the read command (sync byte + address + register + checksum)
var writeBuffer [4]byte
writeBuffer[0] = 0x05 // Sync byte
writeBuffer[1] = comm.address // Slave address
writeBuffer[2] = register & 0x7F // Read command (MSB clear for read)
writeBuffer[3] = writeBuffer[0] ^ writeBuffer[1] ^ writeBuffer[2] // Checksum
done := make(chan []byte, 1)
go func() {
comm.uart.Write(writeBuffer[:])
readBuffer := make([]byte, 8) // Prepare the buffer to read 8 bytes
comm.uart.Read(readBuffer)
done <- readBuffer
}()
select {
case readBuffer := <-done:
checksum := byte(0)
for i := 0; i < 7; i++ {
checksum ^= readBuffer[i]
}
if checksum != readBuffer[7] {
return 0, CustomError("checksum error")
}
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")
}
}