1- //go:build rp2040
1+ //go:build rp2040 || rp2350
22
33package machine
44
1515)
1616
1717const (
18- maxPWMPins = 29
18+ maxPWMPins = _NUMBANK0_GPIOS - 1
1919)
2020
2121// pwmGroup is one PWM peripheral, which consists of a counter and two output
@@ -146,12 +146,13 @@ func (p *pwmGroup) Counter() uint32 {
146146
147147// Period returns the used PWM period in nanoseconds.
148148func (p * pwmGroup ) Period () uint64 {
149- periodPerCycle := cpuPeriod ()
149+ freq := CPUFrequency ()
150150 top := p .getWrap ()
151151 phc := p .getPhaseCorrect ()
152152 Int , frac := p .getClockDiv ()
153- // Line below can overflow if operations done without care.
154- return (16 * uint64 (Int ) + uint64 (frac )) * uint64 ((top + 1 )* (phc + 1 )* periodPerCycle ) / 16 // cycles = (TOP+1) * (CSRPHCorrect + 1) * (DIV_INT + DIV_FRAC/16)
153+ // Lines below can overflow if operations done without care.
154+ term2 := 16 * uint64 ((top + 1 )* (phc + 1 )) * 1e9 / uint64 (freq ) // 1e9/freq == CPU period in nanoseconds.
155+ return (uint64 (Int ) + uint64 (frac )) * term2 / 16 // cycles = (TOP+1) * (CSRPHCorrect + 1) * (DIV_INT + DIV_FRAC/16)
155156}
156157
157158// SetInverting sets whether to invert the output of this channel.
@@ -279,9 +280,9 @@ func (pwm *pwmGroup) setPeriod(period uint64) error {
279280 // DIV_INT + DIV_FRAC/16 = cycles / ( (TOP+1) * (CSRPHCorrect+1) ) // DIV_FRAC/16 is always 0 in this equation
280281 // where cycles must be converted to time:
281282 // target_period = cycles * period_per_cycle ==> cycles = target_period/period_per_cycle
282- periodPerCycle := uint64 (cpuPeriod ())
283+ freq := uint64 (CPUFrequency ())
283284 phc := uint64 (pwm .getPhaseCorrect ())
284- rhs := 16 * period / ((1 + phc ) * periodPerCycle * (1 + topStart )) // right-hand-side of equation, scaled so frac is not divided
285+ rhs := 16e9 * period / ((1 + phc ) * freq * (1 + topStart )) // right-hand-side of equation, scaled so frac is not divided
285286 whole := rhs / 16
286287 frac := rhs % 16
287288 switch {
@@ -296,7 +297,7 @@ func (pwm *pwmGroup) setPeriod(period uint64) error {
296297
297298 // Step 2 is acquiring a better top value. Clearing the equation:
298299 // TOP = cycles / ( (DIVINT+DIVFRAC/16) * (CSRPHCorrect+1) ) - 1
299- top := 16 * period / ((16 * whole + frac )* periodPerCycle * (1 + phc )) - 1
300+ top := 16e9 * period / ((16 * whole + frac )* freq * (1 + phc )) - 1
300301 if top > maxTop {
301302 top = maxTop
302303 }
@@ -400,6 +401,9 @@ func (pwm *pwmGroup) getClockDiv() (Int, frac uint8) {
400401// pwmGPIOToSlice Determine the PWM channel that is attached to the specified GPIO.
401402// gpio must be less than 30. Returns the PWM slice number that controls the specified GPIO.
402403func pwmGPIOToSlice (gpio Pin ) (slicenum uint8 ) {
404+ if is48Pin && gpio >= 32 {
405+ return uint8 (8 + ((gpio - 32 )/ 2 )% 4 )
406+ }
403407 return (uint8 (gpio ) >> 1 ) & 7
404408}
405409
0 commit comments