-
Notifications
You must be signed in to change notification settings - Fork 217
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add PWM support for Linux 4.1+ #103
Comments
BeagleBone Bacon Cape PWM testing with Linux 4.1.15-ti-rt-r43 on Debian Jessie 8.3 from the 2016-01-24 SD card image: pwm-test-jessie-4-1.sh
Output:
|
Examination of how PWM currently works in Linux 3.8
The device tree overlay causes a directory in /sys to be created for that PWM pin:
The PWM pin is then controlled via 3 files (period, duty, polarity) inside the /sys sub-directory for the pin:
For example, this device tree overlay will configure P9_16 for PWM:
Test of PWM for P9_14:
Device tree overlays that are loaded by the library:
Kernel log:
These entries are created in /sys for P9_14:
Period and duty cycle for P9_14:
pwm_test driver comes from am33x-v3.8 branch of https://github.com/RobertCNelson/bb-kernel:
source in Github Gist for reference: EHRPWM_TEST is added to the kernel config. |
I'm reviewing Bonescript by @jadonk to see how it handles PWM on 4.1+ kernels. The current development branch is: bonescript/0.5.x @MarkAYoder has been several commits this year related to PWM: |
PWM related code from PyBBIO by @graycatlabs
|
@pdp7 Any update on progress? I am also available to work on this issue, since my company would like to update to Debian 8, but we need PWM in this library to work. Also I'm not sure where to ask, but do you have any idea who is responsible for releasing a new package version released with the 4.1+ support? |
I thought I'd do a similar summary of how PWM / IO generally works in 4.1+. /sys changesThe locations of a number of key pieces of hardware have changed. This is probably the easiest fix to make (and has been mostly made for other pieces of the library).
Capes loaded on bootThere are two main changes. First, HDMI and EMMC are no longer virtual capes loaded on boot, but are handled natively. I haven't looked in detail into how this works. Second, and more significantly, the idea of loading a separate overlay for each pin has been basically abandoned, in favor of using a Universal IO cape. The universal cape is enabled on boot by default, with an option to disable it in Depending on the Given that a universal cape is loaded at boot, attempting to load a device tree overlay which conflicts with any of its pins will fail. The universal cape uses almost all the pins on the board: all but the ADC and I2C pins, and depending on the So 4.1+ replaces the concept of loading in new device tree overlays for each pin / group of pins with a combination of a universal cape and pinmuxing. There is no need to reinvent the wheel with the pinmuxing---the BoneScript approach to PWMNow I'll describe the approach taken by BoneScript. } else if(template == 'bspwm') {
fs.writeFileSync(pinmux+"/state", 'pwm');
// Buld a path like: /sys/devices/platform/ocp/48304000.epwmss/48304200.ehrpwm/pwm/pwmchip5
// pin.pwm.chip looks up the first address and pin.pwm.addr looks up the second
// file_find figures which pwmchip to use
// pin.pwm.index tells with half of the PWM to use (0 or 1)
var pwmPath = my.file_find('/sys/devices/platform/ocp/'+pin.pwm.chip
+ '.epwmss/'+pin.pwm.addr+'.pwm/pwm', 'pwmchip', 1);
pwmPrefix[pin.pwm.name] = pwmPath + '/pwm' + pin.pwm.index;
if(debug) winston.debug("pwmPrefix[pin.pwm.name] = " + pwmPrefix[pin.pwm.name]);
if(debug) winston.debug("pin.pwm.sysfs = " + pin.pwm.sysfs);
if(!my.file_existsSync(pwmPrefix[pin.pwm.name])) {
fs.appendFileSync(pwmPath+'/export', pin.pwm.index);
}
fs.appendFileSync(pwmPrefix[pin.pwm.name]+'/enable', 1); Given a pin ("P9_21" or similar), this section of code sets the pinmux state to PWM. It finds the path to the PWM chip. I'm not sure why it uses a path with There was another step in the changes made by BoneScript at kernel version 4.1. They depended on exporting PWMs from the /sys/class/pwm directory. That strategy can still be found in src/hw_universal.js. As of kernel 4.4, that strategy no longer works, so they use the strategy shown above in src/hw_mainline.js. Implementation thoughtsWe'll need to keep track of some additional information about pins which have pwm as an output choice. Specifically, we'll need the chip address, and the device address. When initializing a pin for PWM, there are two steps: first, mux the pin to the correct value. This can be done by calling One possible implementation would be to define an interface in a header file, which is implemented by two separate source files, one for <=3.8 and the other for >=4.1. Calling @RobertCNelson - would you be willing to read through and make sure I don't have any major misunderstandings of what's going on? From what I can tell you appear to understand well how all the pieces fit together. |
@MatthewWest
|
@MatthewWest Thank you for the summary and your thoughts. That is very helpful. I think you are right that the necessary information for a pin capable of PWM can be borrowed from bonescript/src/bone.js For example, pin
I agree it would be good to get @RobertCNelson's thoughts |
I've implemented a patch which I have confirmed works for Linux 4.1+, though I haven't had a chance to test it with Linux 3.8. The pull request is at #108. |
Resolved by @MatthewWest's excellent work in #108 |
This library only supports PWM for Linux kernel 3.8. The way to utilize PWM on the TI AM3358 in newer kernels has changed.
I'm creating this issue to represent the effort add support for newer kernels, notably 4.1 and 4.4 as those are long-term kernels supported by TI. @RobertCNelson currently using 4.4 for the latest Debian Jessie images.
I'll be working on adding support in my fork and will create a pull request once I have something working.
The text was updated successfully, but these errors were encountered: