From 982ef08655d214191f798aafd7ac0531ffab1c03 Mon Sep 17 00:00:00 2001 From: Charlie Haley Date: Sun, 9 Jan 2022 20:23:48 +0000 Subject: [PATCH] rp2040: implement PWMGroup func to get peripheral from pin --- src/machine/machine.go | 16 ++++++++++++++++ src/machine/machine_rp2040_pwm.go | 31 +++++++++++++++++++++++-------- 2 files changed, 39 insertions(+), 8 deletions(-) diff --git a/src/machine/machine.go b/src/machine/machine.go index 06274220da..5fcdf3f8c0 100644 --- a/src/machine/machine.go +++ b/src/machine/machine.go @@ -53,3 +53,19 @@ func (p Pin) Low() { type ADC struct { Pin Pin } + +type pwmer interface { + Configure(config PWMConfig) error + Channel(pin Pin) (uint8, error) + SetPeriod(period uint64) error + Top() uint32 + Counter() uint32 + Period() uint64 + SetInverting(channel uint8, inverting bool) + Set(channel uint8, value uint32) + Get(channel uint8) uint32 + SetTop(top uint32) + SetCounter(ctr uint32) + Enable(enable bool) + IsEnabled() bool +} diff --git a/src/machine/machine_rp2040_pwm.go b/src/machine/machine_rp2040_pwm.go index a355be4c8b..2160c9601d 100644 --- a/src/machine/machine_rp2040_pwm.go +++ b/src/machine/machine_rp2040_pwm.go @@ -45,8 +45,10 @@ type pwmGroup struct { } // Equivalent of -// var pwmSlice []pwmGroup = (*[8]pwmGroup)(unsafe.Pointer(rp.PWM))[:] -// return &pwmSlice[index] +// +// var pwmSlice []pwmGroup = (*[8]pwmGroup)(unsafe.Pointer(rp.PWM))[:] +// return &pwmSlice[index] +// // 0x14 is the size of a pwmGroup. func getPWMGroup(index uintptr) *pwmGroup { return (*pwmGroup)(unsafe.Pointer(uintptr(unsafe.Pointer(rp.PWM)) + 0x14*index)) @@ -94,6 +96,16 @@ func (pwm *pwmGroup) Channel(pin Pin) (channel uint8, err error) { return pwmGPIOToChannel(pin), nil } +// PWMforPin returns the RP2040 PWM Group for the given pin. If the pin does +// not belong to a PWM peripheral ErrInvalidOutputPin error is returned. +func PWMforPin(pin Pin) (pwmer pwmer, err error) { + sliceNum, err := PWMPeripheral(pin) + if err != nil { + return nil, err + } + return getPWMGroup(uintptr(sliceNum)), nil +} + // Peripheral returns the RP2040 PWM peripheral which ranges from 0 to 7. Each // PWM peripheral has 2 channels, A and B which correspond to 0 and 1 in the program. // This number corresponds to the package's PWM0 throughout PWM7 handles @@ -112,7 +124,7 @@ func (pwm *pwmGroup) peripheral() uint8 { // SetPeriod updates the period of this PWM peripheral in nanoseconds. // To set a particular frequency, use the following formula: // -// period = 1e9 / frequency +// period = 1e9 / frequency // // Where frequency is in hertz. If you use a period of 0, a period // that works well for LEDs will be picked. @@ -167,7 +179,7 @@ func (p *pwmGroup) SetInverting(channel uint8, inverting bool) { // cycle, in other words the fraction of time the channel output is high (or low // when inverted). For example, to set it to a 25% duty cycle, use: // -// pwm.Set(channel, pwm.Top() / 4) +// pwm.Set(channel, pwm.Top() / 4) // // pwm.Set(channel, 0) will set the output to low and pwm.Set(channel, // pwm.Top()) will set the output to high, assuming the output isn't inverted. @@ -238,14 +250,17 @@ func (pwm *pwmGroup) setPhaseCorrect(correct bool) { } // Takes any of the following: -// rp.PWM_CH0_CSR_DIVMODE_DIV, rp.PWM_CH0_CSR_DIVMODE_FALL, -// rp.PWM_CH0_CSR_DIVMODE_LEVEL, rp.PWM_CH0_CSR_DIVMODE_RISE +// +// rp.PWM_CH0_CSR_DIVMODE_DIV, rp.PWM_CH0_CSR_DIVMODE_FALL, +// rp.PWM_CH0_CSR_DIVMODE_LEVEL, rp.PWM_CH0_CSR_DIVMODE_RISE func (pwm *pwmGroup) setDivMode(mode uint32) { pwm.CSR.ReplaceBits(mode<