mirror of
https://github.com/tinygo-org/drivers.git
synced 2026-07-26 10:38:41 +00:00
486949686c
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
195 lines
5.9 KiB
Go
195 lines
5.9 KiB
Go
//go:build tinygo
|
|
|
|
package tmc5160
|
|
|
|
import (
|
|
"github.com/orsinium-labs/tinymath"
|
|
"machine"
|
|
)
|
|
|
|
type Driver struct {
|
|
comm RegisterComm
|
|
address uint8
|
|
enablePin machine.Pin
|
|
stepper Stepper
|
|
}
|
|
|
|
func NewDriver(comm RegisterComm, address uint8, enablePin machine.Pin, stepper Stepper) *Driver {
|
|
return &Driver{
|
|
comm: comm,
|
|
address: address,
|
|
enablePin: enablePin,
|
|
stepper: stepper,
|
|
}
|
|
}
|
|
|
|
// WriteRegister sends a register write command to the Driver.
|
|
func (driver *Driver) WriteRegister(reg uint8, value uint32) error {
|
|
if driver.comm == nil {
|
|
return CustomError("communication interface not set")
|
|
}
|
|
// Use the communication interface (RegisterComm) to write the register
|
|
return driver.comm.WriteRegister(reg, value, driver.address)
|
|
}
|
|
|
|
// ReadRegister sends a register read command to the Driver and returns the read value.
|
|
func (driver *Driver) ReadRegister(reg uint8) (uint32, error) {
|
|
if driver.comm == nil {
|
|
return 0, CustomError("communication interface not set")
|
|
}
|
|
// Use the communication interface (RegisterComm) to read the register
|
|
return driver.comm.ReadRegister(reg, driver.address)
|
|
}
|
|
|
|
// Begin initializes the Driver driver with power and motor parameters
|
|
func (driver *Driver) Begin(powerParams PowerStageParameters, motorParams MotorParameters, stepperDirection MotorDirection) bool {
|
|
// Clear the reset and charge pump undervoltage flags
|
|
gstat := NewGSTAT()
|
|
gstat.Reset = true
|
|
gstat.UvCp = true
|
|
err := driver.WriteRegister(GSTAT, gstat.Pack())
|
|
if err != nil {
|
|
return false
|
|
}
|
|
|
|
// Configure driver settings
|
|
drvConf := NewDRV_CONF()
|
|
drvConf.DrvStrength = constrain(powerParams.drvStrength, 0, 3)
|
|
drvConf.BBMTime = constrain(powerParams.bbmTime, 0, 24)
|
|
drvConf.BBMClks = constrain(powerParams.bbmClks, 0, 15)
|
|
err = driver.WriteRegister(DRV_CONF, drvConf.Pack())
|
|
if err != nil {
|
|
return false
|
|
}
|
|
|
|
// Set global scaler
|
|
err = driver.WriteRegister(GLOBAL_SCALER, uint32(constrain(motorParams.globalScaler, 32, 256)))
|
|
if err != nil {
|
|
return false
|
|
}
|
|
|
|
// Set initial currents and delay
|
|
iholdrun := NewIHOLD_IRUN()
|
|
iholdrun.Ihold = constrain(motorParams.ihold, 0, 31)
|
|
iholdrun.Ihold = constrain(motorParams.irun, 0, 31)
|
|
iholdrun.IholdDelay = 7
|
|
err = driver.WriteRegister(IHOLD_IRUN, iholdrun.Pack())
|
|
if err != nil {
|
|
return false
|
|
}
|
|
|
|
// Set PWM configuration values
|
|
pwmconf := NewPWMCONF()
|
|
err = driver.WriteRegister(PWMCONF, 0xC40C001E)
|
|
if err != nil {
|
|
return false
|
|
} // Reset default value pwm_ofs = 196,pwm_grad = 12,pwm_freq = 0, pwm_autoscale = false, pwm_autograd = false,freewheel = 3
|
|
pwmconf.PwmAutoscale = false // Temporarily set to false for setting OFS and GRAD values
|
|
_fclk := int(driver.stepper.Fclk) * 1000000
|
|
if _fclk > DEFAULT_F_CLK {
|
|
pwmconf.PwmFreq = 0
|
|
} else {
|
|
pwmconf.PwmFreq = 0b01 // Recommended: 35kHz with internal 12MHz clock
|
|
}
|
|
pwmconf.PwmGrad = uint8(motorParams.pwmGradInitial)
|
|
pwmconf.PwmOfs = uint8(motorParams.pwmOfsInitial)
|
|
pwmconf.Freewheel = motorParams.freewheeling
|
|
err = driver.WriteRegister(PWMCONF, pwmconf.Pack())
|
|
if err != nil {
|
|
return false
|
|
}
|
|
|
|
// Enable PWM auto-scaling and gradient adjustment
|
|
pwmconf.PwmAutoscale = true
|
|
pwmconf.PwmAutograd = true
|
|
err = driver.WriteRegister(PWMCONF, pwmconf.Pack())
|
|
if err != nil {
|
|
return false
|
|
}
|
|
|
|
// Recommended chop configuration settings
|
|
_chopConf := NewCHOPCONF()
|
|
_chopConf.Toff = 5
|
|
_chopConf.Tbl = 2
|
|
_chopConf.HstrtTfd = 4
|
|
_chopConf.HendOffset = 0
|
|
err = driver.WriteRegister(CHOPCONF, _chopConf.Pack())
|
|
if err != nil {
|
|
return false
|
|
}
|
|
rampMode := NewRAMPMODE(driver.comm, driver.address)
|
|
rampMode.SetMode(PositioningMode)
|
|
gconf := NewGCONF()
|
|
gconf.EnPwmMode = true // Enable stealthChop PWM mode
|
|
gconf.Shaft = stepperDirection == Clockwise
|
|
err = driver.WriteRegister(GCONF, gconf.Pack())
|
|
if err != nil {
|
|
return false
|
|
}
|
|
|
|
// Set default start, stop, threshold speeds
|
|
driver.setRampSpeeds(0.0, 0.1, 0.0) // Start, stop, threshold speeds
|
|
|
|
// Set default D1 (must not be = 0 in positioning mode even with V1=0)
|
|
err = driver.WriteRegister(D_1, 100)
|
|
if err != nil {
|
|
return false
|
|
}
|
|
|
|
return false
|
|
}
|
|
func (driver *Driver) setRampSpeeds(startSpeed float32, stopSpeed float32, transitionSpeed float32) {
|
|
str := driver.stepper.DesiredSpeedToTSTEP(uint32(startSpeed))
|
|
stp := driver.stepper.DesiredSpeedToTSTEP(uint32(stopSpeed))
|
|
ts := driver.stepper.DesiredSpeedToTSTEP(uint32(transitionSpeed))
|
|
driver.WriteRegister(VSTART, uint32(tinymath.Min(0x3FFFF, float32(str))))
|
|
driver.WriteRegister(VSTOP, uint32(tinymath.Min(0x3FFFF, float32(stp))))
|
|
driver.WriteRegister(V_1, uint32(tinymath.Min(0xFFFFF, float32(ts))))
|
|
println("Ramp set to: startSpeed:", startSpeed, "stopSpeed:", stopSpeed, "transitionSpeed:", transitionSpeed)
|
|
}
|
|
|
|
// setMaxSpeed sets the maximum speed to 0 (placeholder function)
|
|
func setMaxSpeed(speed uint32) {
|
|
// This is a placeholder function that sets the speed
|
|
// Implement the actual logic to set the maximum speed register value
|
|
println("Max Speed set to:", speed)
|
|
}
|
|
|
|
// Dump_TMC reads multiple registers from the Driver and logs their values with their names.
|
|
func (driver *Driver) Dump_TMC() error {
|
|
registers := []uint8{
|
|
GCONF, CHOPCONF, GSTAT, DRV_STATUS, FACTORY_CONF, IOIN, LOST_STEPS, MSCNT,
|
|
MSCURACT, OTP_READ, PWM_SCALE, PWM_AUTO, TSTEP,
|
|
}
|
|
registerNames := map[uint8]string{
|
|
GCONF: "GCONF",
|
|
CHOPCONF: "CHOPCONF",
|
|
GSTAT: "GSTAT",
|
|
DRV_STATUS: "DRV_STATUS",
|
|
FACTORY_CONF: "FACTORY_CONF",
|
|
IOIN: "IOIN",
|
|
LOST_STEPS: "LOST_STEPS",
|
|
MSCNT: "MSCNT",
|
|
MSCURACT: "MSCURACT",
|
|
OTP_READ: "OTP_READ",
|
|
PWM_SCALE: "PWM_SCALE",
|
|
PWM_AUTO: "PWM_AUTO",
|
|
TSTEP: "TSTEP",
|
|
}
|
|
for _, reg := range registers {
|
|
// Fetch the register name from the map
|
|
regName, exists := registerNames[reg]
|
|
if !exists {
|
|
regName = "Unknown Register"
|
|
}
|
|
val, err := driver.ReadRegister(reg)
|
|
if err != nil {
|
|
println("Error reading register", regName, err)
|
|
return err
|
|
}
|
|
println("Register", regName, "Value:", val)
|
|
}
|
|
|
|
return nil
|
|
}
|