vsergeev / python-periphery

A pure Python 2/3 library for peripheral I/O (GPIO, LED, PWM, SPI, I2C, MMIO, Serial) in Linux.
MIT License
531 stars 142 forks source link

Fix miss-leading documents. #26

Closed CharlesCCC closed 4 years ago

CharlesCCC commented 5 years ago

Not sure if any body has followed the documents to worked with PWM, but it is totally misleading. I spent hours doing research finally was able to figure this part out by looking at the snippet code provided by @scottellis https://github.com/scottellis/pwmpy

In the code: Original mapping

PWM(channel, pin) is WRONG

instead, it actually should work like this: PWM(channel-->chip/pin, pin-->channel)

e.g. with the example from the README

# Open channel 0, for pin 10 
PWM(0,10) --> it sounds like should export the following :
/sys/class/pwm/pwmchip10/pwm0

but what it is actually doing is: (open chip/pin 0, with the 11th channel)

/sys/class/pwm/pwmchip0/pwm10 

so the paramer should be passed in as this

PWM(pin, channel)

so the the example from the README become

# Open channel 0, for pin 10 
PWM(10,0)  
/sys/class/pwm/pwmchip10/pwm0

add additional info:

# You can figure out the pin number by run  'ls /sys/class/pwm' list of pwmchip# - # will be the pin number
# You can figure out how many channel are supported for the pin 
# by run 'cat /sys/class/pwm/pwmchip0/npwm' - pwmchip0 as example
vsergeev commented 5 years ago

I see the source of the confusion. It seems that the underlying sysfs interface has one flat list of PWM channels ranging from 0 to /sys/class/pwm/npwm, which organized in chunks at various /sys/class/pwm/pwmchipN chips, each of which start at channel base N.

To fix this, the PWM constructor should really just accept a channel number and find the right channel under one of the pwmchip bases or write /sys/class/pwm/export export it. I'll fix this for 1.2.0.

I was incorrect about my analysis above. The channel numbers are namespaced under each pwmchip, not a flat list, so the solution ended up being simply renaming channel to chip and pin to channel in the constructor and documentation.