1
- //go:build rp2040
1
+ //go:build rp2040 || rp2350
2
2
3
3
package machine
4
4
15
15
)
16
16
17
17
const (
18
- maxPWMPins = 29
18
+ maxPWMPins = _NUMBANK0_GPIOS - 1
19
19
)
20
20
21
21
// pwmGroup is one PWM peripheral, which consists of a counter and two output
@@ -146,12 +146,13 @@ func (p *pwmGroup) Counter() uint32 {
146
146
147
147
// Period returns the used PWM period in nanoseconds.
148
148
func (p * pwmGroup ) Period () uint64 {
149
- periodPerCycle := cpuPeriod ()
149
+ freq := CPUFrequency ()
150
150
top := p .getWrap ()
151
151
phc := p .getPhaseCorrect ()
152
152
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)
155
156
}
156
157
157
158
// SetInverting sets whether to invert the output of this channel.
@@ -279,9 +280,9 @@ func (pwm *pwmGroup) setPeriod(period uint64) error {
279
280
// DIV_INT + DIV_FRAC/16 = cycles / ( (TOP+1) * (CSRPHCorrect+1) ) // DIV_FRAC/16 is always 0 in this equation
280
281
// where cycles must be converted to time:
281
282
// target_period = cycles * period_per_cycle ==> cycles = target_period/period_per_cycle
282
- periodPerCycle := uint64 (cpuPeriod ())
283
+ freq := uint64 (CPUFrequency ())
283
284
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
285
286
whole := rhs / 16
286
287
frac := rhs % 16
287
288
switch {
@@ -296,7 +297,7 @@ func (pwm *pwmGroup) setPeriod(period uint64) error {
296
297
297
298
// Step 2 is acquiring a better top value. Clearing the equation:
298
299
// 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
300
301
if top > maxTop {
301
302
top = maxTop
302
303
}
@@ -400,6 +401,9 @@ func (pwm *pwmGroup) getClockDiv() (Int, frac uint8) {
400
401
// pwmGPIOToSlice Determine the PWM channel that is attached to the specified GPIO.
401
402
// gpio must be less than 30. Returns the PWM slice number that controls the specified GPIO.
402
403
func pwmGPIOToSlice (gpio Pin ) (slicenum uint8 ) {
404
+ if is48Pin && gpio >= 32 {
405
+ return uint8 (8 + ((gpio - 32 )/ 2 )% 4 )
406
+ }
403
407
return (uint8 (gpio ) >> 1 ) & 7
404
408
}
405
409
0 commit comments