# Getting the PWM working

The Raspberry Pi zero (1 and 2) have 2 PWM peripherals, allowing you to pulse pins without the CPU doing any additional work.  This is particuarly useful for controlling motor speeds when connected to a motor driver/H-bridge chip.


# References
- [CircuitPython Libraries on Linux and Raspberry Pi](https://learn.adafruit.com/circuitpython-on-raspberrypi-linux/installing-circuitpython-on-raspberry-pi)
- [Raspberry Pi Official Overlays information (github)](https://github.com/raspberrypi/firmware/blob/master/boot/overlays/README)
    - Line 4235 starts the description of the "pwm" overlay configuration
- [Adding Basic Audio Ouput to Raspberry Pi Zero](https://learn.adafruit.com/adding-basic-audio-ouput-to-raspberry-pi-zero/pi-zero-pwm-audio)
- [CircuitPython pwmio documentation](https://docs.circuitpython.org/en/latest/shared-bindings/pwmio/index.html)


# Important Points
1. The `gpio` program is no longer available.  It has been replaced with `pinctrl` which works a little differently.
1. The Blinka/CircuitPython interface uses `lgpio` to do hardware PWM on the pins.  This requires the `pwm-2chan` overlay to be setup correctly, which it's documented procedure does.  Details on relevant pins on line 4267 of the [overleays README](https://github.com/raspberrypi/firmware/blob/master/boot/overlays/README)

# Discussion


My raspberry pi zero W 2 wasn't working reliably with the PWM.

The `gpio` command has been depricated and is now replaced by the `pinctrl` commend.  Running it did not list any PWM0 on any of the pins, which was concerning.

[This forum post](https://forums.raspberrypi.com/viewtopic.php?t=388352) indicated the need for a `pwm-2chan` device tree overlay to get it to show up.  After adding `dtoverlay=pwm-2chan` to the `config.txt`:

```
$ pinctrl
 0: ip    -- | hi // ID_SDA/GPIO0 = input
 1: ip    -- | hi // ID_SCL/GPIO1 = input
 2: a0    -- | hi // GPIO2 = SDA1
 3: a0    -- | hi // GPIO3 = SCL1
 4: op -- -- | hi // GPIO4 = output
 5: ip    -- | hi // GPIO5 = input
 6: ip    -- | hi // GPIO6 = input
 7: op -- -- | hi // GPIO7 = output
 8: op -- -- | hi // GPIO8 = output
 9: a0    -- | lo // GPIO9 = SPI0_MISO
10: a0    -- | lo // GPIO10 = SPI0_MOSI
11: a0    -- | lo // GPIO11 = SPI0_SCLK
12: ip    -- | lo // GPIO12 = input
13: ip    -- | lo // GPIO13 = input
14: ip    -- | lo // GPIO14 = input
15: ip    -- | hi // GPIO15 = input
16: ip    -- | lo // GPIO16 = input
17: ip    -- | lo // GPIO17 = input
18: a5    -- | lo // GPIO18 = PWM0
19: a5    -- | lo // GPIO19 = PWM1
```

Which looks much better.
There is a pwm chip `in /sys/class/pwm`

After running the `lgpio/pwm-test.py`
the pin is back to being listed as an input, so I'm confused.
The PWM pin (under load) did the right values.  Without a load on the Analog Discovery 2, I just saw noise.

I commented out `dtoverlay=pwm-2chan` and `lgpio/pwm-test.py` worked.
The pwm chip is missing from `/sys/class/pwm` so I'm guess that's not needed.


