Uh oh!
There was an error while loading.Please reload this page.
- Notifications
You must be signed in to change notification settings - Fork218
Open
Description
Arduino Mbed OS RP2040 for Raspberry Pi Pico - Version 3.5.4
In exploring the use ofanalogWrite() anddigitalWrite() on the Raspberry Pi Pico using Arduino, I have discovered some strange behaviors when switching between those modes on the same GPIO pin.
Operational Issues:
Issue 1:
- When doing ananalogWrite() to a GPIO pin with an adjacent GPIO pin on the same PWM slice with
an active PWM already, the adjacent pin's PWM stops- Example: (GP2 and GP3 using PWM slice # 1)
- Reset Pico
// always start from known state - analogWrite(2, 64)
// pin GP2 starts at 25% PWM output - analogWrite(3, 128)
// pin GP3 starts 50% PWM output, but GP2 stops it's PWM output
Work-around: - analogWrite(2, 192)
// pin GP2 now restarts with 75% PWM output
This appears to be due to the setting of the companion pin causes the CC register counter
compare value for the 1st pin to be set to 0. In the above example, reversing the order
of the pins (i.e. GP3, then GP2) still shows the same problem. Once both pins are outputting
a PWM signal, either one can be modified without affecting the other pin's output.
- Reset Pico
- Example: (GP2 and GP3 using PWM slice # 1)
Issue 2:
- After changing a GPIO pin with an activeanalogWrite() PWM output to adigitalWrite()
digital output, attempting to then change the pin to ananalogWrite() PWM output fails
to output the PWM signal.- Example: (GP2 using PWM slice # 1)
- Reset Pico
// always start from known state - analogWrite(2, 64)
// pin GP2 starts PWM output - digitalWrite(2, 1)
// pin GP2 digital output high - analogWrite(2, 128)
// pin GP2 fails PWM output
Work-around: - gpio_set_function(2, GPIO_FUNC_PWM)
// re-activate pin GP2 PWM output - analogWrite(2, 32)
// change pin GP2 PWM output - digitalWrite(2, 0)
// pin GP2 fails digital output, but remains PWM output
This appears to be due to not automatically changing the pin's function from PWM to SIO.
Any subsequent changes to the pin's digital or analog output also requires changing the
pin's mode manually.
- Reset Pico
- Example: (GP2 using PWM slice # 1)
Issue 3:
- After changing a GPIO pin with adigitalWrite() digital output to ananalogWrite()
PWM output, attempting to then change the pin to andigitalWrite() digital output fails
to output the digital signal level.- Example: (GP2 using PWM slice # 1)
- Reset Pico
// always start from known state - digitalWrite(2, 1)
// pin GP2 digital output high - analogWrite(2, 64)
// pin GP2 starts PWM output - digitalWrite(2, 1)
// pin GP2 fails digital output, but remains PWM output
Work-around: - pinMode(2, OUTPUT)
// pin GP2 digital output low - digitalWrite(2, 1)
// change pin GP2 digital output high - analogWrite(2, 32)
// pin GP2 fails PWM output, but remains digital output
This appears to be due to not automatically changing the pin's function from SIO to PWM.
Any subsequent changes to the pin's digital or analog output also requires changing the
pin's mode manually.
- Reset Pico
- Example: (GP2 using PWM slice # 1)
It was expected that theanalogWrite() anddigitalWrite() functions would always automatically take care of ensuring the correct function mode was set for the associated GPIO pin. Instead, it appears that this only the case on the first instance of using those functions for a GPIO pin.
--------------------------------------------------------------------------------------------Detailed tracing of the above described issues follows below. This includes showing thefunction state of the specified GPIO pin before and after each operation to configurethe pin. Also, a dump of the associated PWM registers is also shown after a PWMconfiguration operation. "<---------" items note commentary items of interest.Work-arounds are also shown to restore a GPIO pin to its expected operation.--------------------------------------------------------------------------------------------Raspberry Pi Pico Arduino PWM Output TestingAvailable commands------------------pwm [<pin> [<duty> | off | on | stat]] : Output PWM on specified I/O pingpio [<pin> [<0 | 1> | out | in | off]] : Output to specified I/O pin--------------------------------------------------------------------------------------------Issue #1:=========RESET -> PWM2 -> PWM3 -> PWM2------------------------------> pwm 2 64pinFunc: GPIO_FUNC_NULL{analogWrite(2, 64)}PWM: GP2, Duty 64pinFunc: GPIO_FUNC_PWM <--------- OK, has PWM 25% output-> pwm 2 statpinFunc: GPIO_FUNC_PWMSlice: 1CSR: 0x1 - DIVMODE:FREE_RUNNING, EnabledDIV: 0xFA0 - INT:250, FRAC:0CTR: 0x3A0 (928)CC: 0xFB - B:0, A:251 <--------- OK, CHB off, CHA 25%TOP: 0x3E8 (1000)EN: 0x2 - CH2-> pwm 3 128pinFunc: GPIO_FUNC_NULL{analogWrite(3, 128)}PWM: GP3, Duty 128pinFunc: GPIO_FUNC_PWM <--------- OK, has PWM 50% output, but output 2 goes low-> pwm 3 statpinFunc: GPIO_FUNC_PWMSlice: 1CSR: 0x1 - DIVMODE:FREE_RUNNING, EnabledDIV: 0xFA0 - INT:250, FRAC:0CTR: 0x391 (913)CC: 0x1F60000 - B:502, A:0 <--------- OK, CHB 50%, Bad, CHA off (CHA should not have been modified!)TOP: 0x3E8 (1000)EN: 0x2 - CH2-> pwm 2 192pinFunc: GPIO_FUNC_PWM{analogWrite(2, 192)}PWM: GP2, Duty 192pinFunc: GPIO_FUNC_PWM <--------- OK, has PWM 75% output-> pwm 2 statpinFunc: GPIO_FUNC_PWMSlice: 1CSR: 0x1 - DIVMODE:FREE_RUNNING, EnabledDIV: 0xFA0 - INT:250, FRAC:0CTR: 0x125 (293)CC: 0x1F602F1 - B:502, A:753 <--------- OK, CHB 50%, CHA 75%TOP: 0x3E8 (1000)EN: 0x2 - CH2--------------------------------------------------------------------------------------------Issue #2:=========RESET -> PWM -> GPIO -> PWM fails----------------------------------> pwm 2 64pinFunc: GPIO_FUNC_NULL{analogWrite(2, 64)}PWM: GP2, Duty 64pinFunc: GPIO_FUNC_PWM <--------- OK, has PWM 25% output-> pwm 2 statpinFunc: GPIO_FUNC_PWMSlice: 1CSR: 0x1 - DIVMODE:FREE_RUNNING, EnabledDIV: 0xFA0 - INT:250, FRAC:0CTR: 0x1B5 (437)CC: 0xFB - B:0, A:251TOP: 0x3E8 (1000)EN: 0x2 - CH2-> gpio 2 1pinFunc: GPIO_FUNC_PWM{digitalWrite(2, 1)}GPIO: GP2, 1pinFunc: GPIO_FUNC_SIO <--------- OK, output high-> pwm 2 128pinFunc: GPIO_FUNC_SIO{analogWrite(2, 128)}PWM: GP2, Duty 128pinFunc: GPIO_FUNC_SIO <--------- FAILED, no PWM output, should be GPIO_FUNC_PWM-> pwm 2 statpinFunc: GPIO_FUNC_SIOSlice: 1CSR: 0x1 - DIVMODE:FREE_RUNNING, EnabledDIV: 0xFA0 - INT:250, FRAC:0CTR: 0x122 (290)CC: 0x1F6 - B:0, A:502TOP: 0x3E8 (1000)EN: 0x2 - CH2-> pwm 2 onpinFunc: GPIO_FUNC_SIO{gpio_set_function(2, GPIO_FUNC_PWM)}PWM: GP2, Duty OnpinFunc: GPIO_FUNC_PWM <--------- OK, now has PWM 50% output-> pwm 2 32pinFunc: GPIO_FUNC_PWM{analogWrite(2, 32)}PWM: GP2, Duty 32pinFunc: GPIO_FUNC_PWM <--------- OK, has PWM 12% output-> pwm 2 statpinFunc: GPIO_FUNC_PWMSlice: 1CSR: 0x1 - DIVMODE:FREE_RUNNING, EnabledDIV: 0xFA0 - INT:250, FRAC:0CTR: 0x1F7 (503)CC: 0x7D - B:0, A:125TOP: 0x3E8 (1000)EN: 0x2 - CH2-> gpio 2 0pinFunc: GPIO_FUNC_PWM{digitalWrite(2, 0)}GPIO: GP2, 0pinFunc: GPIO_FUNC_PWM <--------- FAILED, still PWM output, should be GPIO_FUNC_SIO--------------------------------------------------------------------------------------------Issue #3:=========RESET -> GPIO -> PWM -> GPIO fails-----------------------------------> gpio 2 1pinFunc: GPIO_FUNC_NULL{digitalWrite(2, 1)}GPIO: GP2, 1pinFunc: GPIO_FUNC_SIO <--------- OK, output high-> pwm 2 64pinFunc: GPIO_FUNC_SIO{analogWrite(2, 64)}PWM: GP2, Duty 64pinFunc: GPIO_FUNC_PWM <--------- OK, has PWM 25% output-> pwm 2 statpinFunc: GPIO_FUNC_PWMSlice: 1CSR: 0x1 - DIVMODE:FREE_RUNNING, EnabledDIV: 0xFA0 - INT:250, FRAC:0CTR: 0x253 (595)CC: 0xFB - B:0, A:251TOP: 0x3E8 (1000)EN: 0x2 - CH2-> gpio 2 1pinFunc: GPIO_FUNC_PWM{digitalWrite(2, 1)}GPIO: GP2, 1pinFunc: GPIO_FUNC_PWM <--------- FAILED, still PWM output, should be GPIO_FUNC_SIO-> gpio 2 outpinFunc: GPIO_FUNC_PWM{pinMode(2, OUTPUT)}GPIO: GP2, OutpinFunc: GPIO_FUNC_SIO <--------- OK, output low-> gpio 2 1pinFunc: GPIO_FUNC_SIO{digitalWrite(2, 1)}GPIO: GP2, 1pinFunc: GPIO_FUNC_SIO <--------- OK, output high-> pwm 2 32pinFunc: GPIO_FUNC_SIO{analogWrite(2, 32)}PWM: GP2, Duty 32pinFunc: GPIO_FUNC_SIO <--------- FAILED, no PWM output, should be GPIO_FUNC_PWM-> pwm 2 statpinFunc: GPIO_FUNC_SIOSlice: 1CSR: 0x1 - DIVMODE:FREE_RUNNING, EnabledDIV: 0xFA0 - INT:250, FRAC:0CTR: 0x3D (61)CC: 0x7D - B:0, A:125TOP: 0x3E8 (1000)EN: 0x2 - CH2--------------------------------------------------------------------------------------------