diff --git a/examples/apa102/itsybitsy-m0/main.go b/examples/apa102/itsybitsy-m0/main.go index 7170ca101..1cfdb707e 100644 --- a/examples/apa102/itsybitsy-m0/main.go +++ b/examples/apa102/itsybitsy-m0/main.go @@ -15,7 +15,7 @@ import ( var ( apa apa102.Device - led = machine.PWM{machine.LED} + pwm = machine.TCC0 leds = make([]color.RGBA, 1) wheel = &Wheel{Brightness: 0x10} ) @@ -27,12 +27,19 @@ func init() { apa = apa102.NewSoftwareSPI(machine.PA00, machine.PA01, 1) // Configure the regular on-board LED for PWM fading - machine.InitPWM() - led.Configure() - + err := pwm.Configure(machine.PWMConfig{}) + if err != nil { + println("failed to configure PWM") + return + } } func main() { + channelLED, err := pwm.Channel(machine.LED) + if err != nil { + println("failed to configure LED PWM channel") + return + } // We'll fade the on-board LED in a goroutine to show/ensure that the APA102 // works fine with the scheduler enabled. Comment this out to test this code @@ -43,11 +50,11 @@ func main() { brightening = !brightening continue } - var brightness uint16 = uint16(i) << 8 + var brightness uint32 = uint32(i) if !brightening { - brightness = 0xFFFF - brightness + brightness = 256 - brightness } - led.Set(brightness) + pwm.Set(channelLED, pwm.Top()*brightness/256) time.Sleep(5 * time.Millisecond) } }() diff --git a/examples/l293x/speed/main.go b/examples/l293x/speed/main.go index b84ada88b..cf532ff01 100644 --- a/examples/l293x/speed/main.go +++ b/examples/l293x/speed/main.go @@ -8,19 +8,31 @@ import ( ) const ( - maxSpeed = 30000 + maxSpeed = 100 ) func main() { - machine.InitPWM() + err := machine.TCC0.Configure(machine.PWMConfig{ + Period: 16384e3, // 16.384ms + }) + if err != nil { + println(err.Error()) + return + } + + spc, err := machine.TCC0.Channel(machine.D12) + if err != nil { + println(err.Error()) + return + } - wheel := l293x.NewWithSpeed(machine.D10, machine.D11, machine.PWM{machine.D12}) + wheel := l293x.NewWithSpeed(machine.D10, machine.D11, spc, machine.TCC0) wheel.Configure() for i := 0; i <= 10; i++ { println("Forward") - var i uint16 - for i = 0; i < maxSpeed; i += 1000 { + var i uint32 + for i = 0; i < maxSpeed; i += 10 { wheel.Forward(i) time.Sleep(time.Millisecond * 100) } @@ -30,7 +42,7 @@ func main() { time.Sleep(time.Millisecond * 1000) println("Backward") - for i = 0; i < maxSpeed; i += 1000 { + for i = 0; i < maxSpeed; i += 10 { wheel.Backward(i) time.Sleep(time.Millisecond * 100) } diff --git a/examples/l9110x/speed/main.go b/examples/l9110x/speed/main.go index b2ccfabc9..b2ed9b856 100644 --- a/examples/l9110x/speed/main.go +++ b/examples/l9110x/speed/main.go @@ -8,19 +8,38 @@ import ( ) const ( - maxSpeed = 30000 + maxSpeed = 100 ) func main() { - machine.InitPWM() + machine.D11.Configure(machine.PinConfig{Mode: machine.PinOutput}) + machine.D12.Configure(machine.PinConfig{Mode: machine.PinOutput}) - wheel := l9110x.NewWithSpeed(machine.PWM{machine.D11}, machine.PWM{machine.D12}) + err := machine.TCC0.Configure(machine.PWMConfig{}) + if err != nil { + println(err.Error()) + return + } + + ca, err := machine.TCC0.Channel(machine.D11) + if err != nil { + println(err.Error()) + return + } + + cb, err := machine.TCC0.Channel(machine.D12) + if err != nil { + println(err.Error()) + return + } + + wheel := l9110x.NewWithSpeed(ca, cb, machine.TCC0) wheel.Configure() for i := 0; i <= 10; i++ { println("Forward") - var i uint16 - for i = 0; i < maxSpeed; i += 1000 { + var i uint32 + for i = 0; i < maxSpeed; i += 10 { wheel.Forward(i) time.Sleep(time.Millisecond * 100) } @@ -30,7 +49,7 @@ func main() { time.Sleep(time.Millisecond * 1000) println("Backward") - for i = 0; i < maxSpeed; i += 1000 { + for i = 0; i < maxSpeed; i += 10 { wheel.Backward(i) time.Sleep(time.Millisecond * 100) } diff --git a/l293x/l293x.go b/l293x/l293x.go index 7fe5cfdd7..f9f2c607f 100644 --- a/l293x/l293x.go +++ b/l293x/l293x.go @@ -56,49 +56,71 @@ func (d *Device) Stop() { d.en.Low() } +// PWM is the interface necessary for controlling the motor driver. +type PWM interface { + Configure(config machine.PWMConfig) error + Channel(pin machine.Pin) (channel uint8, err error) + Top() uint32 + Set(channel uint8, value uint32) + SetPeriod(period uint64) error +} + // PWMDevice is a motor with speed control. // a1 and a2 are the directional GPIO pins. // en is the PWM pin that controls the motor speed. type PWMDevice struct { a1, a2 machine.Pin - en machine.PWM + spc uint8 + pwm PWM } -// NewWithSpeed returns a new PWMMotor driver that uses a PWM pin to control speed. -func NewWithSpeed(direction1, direction2 machine.Pin, speedPin machine.PWM) PWMDevice { +// NewWithSpeed returns a new PWMMotor driver that uses an already configured PWM channel +// to control speed. +func NewWithSpeed(direction1, direction2 machine.Pin, spc uint8, pwm PWM) PWMDevice { return PWMDevice{ - a1: direction1, - a2: direction2, - en: speedPin, + a1: direction1, + a2: direction2, + spc: spc, + pwm: pwm, } } -// Configure configures the PWMDevice. -func (d *PWMDevice) Configure() { +// Configure configures the PWMDevice. Note that the PWM interface and +// channel must already be configured, this function will not do it for you. +func (d *PWMDevice) Configure() error { d.a1.Configure(machine.PinConfig{Mode: machine.PinOutput}) d.a2.Configure(machine.PinConfig{Mode: machine.PinOutput}) - d.en.Configure() d.Stop() + + return nil } -// Forward turns motor on in forward direction at specific speed. -func (d *PWMDevice) Forward(speed uint16) { +// Forward turns motor on in forward direction at specific speed as a percentage. +func (d *PWMDevice) Forward(speed uint32) { + if speed > 100 { + speed = 100 + } + d.a1.High() d.a2.Low() - d.en.Set(speed) + d.pwm.Set(d.spc, d.pwm.Top()*speed/100) } -// Backward turns motor on in backward direction at specific speed. -func (d *PWMDevice) Backward(speed uint16) { +// Backward turns motor on in backward direction at specific speed as a percentage. +func (d *PWMDevice) Backward(speed uint32) { + if speed > 100 { + speed = 100 + } + d.a1.Low() d.a2.High() - d.en.Set(speed) + d.pwm.Set(d.spc, d.pwm.Top()*speed/100) } // Stop turns motor off. func (d *PWMDevice) Stop() { d.a1.Low() d.a2.Low() - d.en.Set(0) + d.pwm.Set(d.spc, 0) } diff --git a/l9110x/l9110x.go b/l9110x/l9110x.go index 38ee91f8c..c8f5963d9 100644 --- a/l9110x/l9110x.go +++ b/l9110x/l9110x.go @@ -49,42 +49,52 @@ func (d *Device) Stop() { d.ib.Low() } +// PWM is the interface necessary for controlling the motor driver. +type PWM interface { + Configure(config machine.PWMConfig) error + Channel(pin machine.Pin) (channel uint8, err error) + Top() uint32 + Set(channel uint8, value uint32) + SetPeriod(period uint64) error +} + // PWMDevice is a motor with speed control. // ia and ib are the directional/speed PWM pins. type PWMDevice struct { - ia, ib machine.PWM + pwm PWM + ca, cb uint8 } // NewWithSpeed returns a new PWMMotor driver that uses 2 PWM pins to control both direction and speed. -func NewWithSpeed(direction1, direction2 machine.PWM) PWMDevice { +func NewWithSpeed(ca, cb uint8, pwm PWM) PWMDevice { return PWMDevice{ - ia: direction1, - ib: direction2, + pwm: pwm, + ca: ca, + cb: cb, } } -// Configure configures the PWMDevice. -func (d *PWMDevice) Configure() { - d.ia.Configure() - d.ib.Configure() - +// Configure configures the PWMDevice. Note that the pins, PWM interface, +// and channels must all already be configured. +func (d *PWMDevice) Configure() (err error) { d.Stop() + return } -// Forward turns motor on in forward direction at specific speed. -func (d *PWMDevice) Forward(speed uint16) { - d.ia.Set(speed) - d.ib.Set(0) +// Forward turns motor on in forward direction at specific speed as a percentage. +func (d *PWMDevice) Forward(speed uint32) { + d.pwm.Set(d.ca, d.pwm.Top()*speed/100) + d.pwm.Set(d.cb, 0) } -// Backward turns motor on in backward direction at specific speed. -func (d *PWMDevice) Backward(speed uint16) { - d.ia.Set(0) - d.ib.Set(speed) +// Backward turns motor on in backward direction at specific speed as a percentage. +func (d *PWMDevice) Backward(speed uint32) { + d.pwm.Set(d.ca, 0) + d.pwm.Set(d.cb, d.pwm.Top()*speed/100) } // Stop turns motor off. func (d *PWMDevice) Stop() { - d.ia.Set(0) - d.ib.Set(0) + d.pwm.Set(d.ca, 0) + d.pwm.Set(d.cb, 0) }