Skip to content
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

extras/replicape: support servos with linux host hardware PWM #1443

Merged
merged 1 commit into from Apr 6, 2019

Conversation

jannau
Copy link
Contributor

@jannau jannau commented Mar 24, 2019

The servo pins (P9_14/P9_16) are muxed as hardware pwm and can't be controlled by the PRU. Implement support for hardware pwm in the linux host mcu via sysfs. Verified to to work with a genuine BLTouch smart v3.0.

@KevinOConnor
Copy link
Collaborator

Thanks. Interesting.

Unfortunately, I don't think it's feasible to add a "hardware_pwm" option to the servo/bltouch extras. On the vast majority of boards, the cycle time of hardware pwm can not be set accurately enough to drive a servo. So, I fear adding the option would cause lots of people to enable it and then have confusing failures. The only use for hardware pwm in Klipper today is for emulating a DAC.

You've indicated that the root cause of the problem is that the given pins are muxed to the hardware pwm capability of the beaglebone. Do you know what it would take to not mux those pins, so that the pru could control them?

-Kevin

@jannau
Copy link
Contributor Author

jannau commented Mar 24, 2019

The pins are muxed by the replicape device tree overlay which is applied by the boot loader since a while. I'm not sure if it is still possible (or desirable) to override pin muxes defined in device tree overlays. Also I don't see a reason to not use perfectly capable HW.
Would it be acceptable to annotate pins of only hardware_pwm capable? I think that would also help on duet 2 boards. The example config states that certain fan pins need to use hardware_pwm.
The other alternative would be to make the servo pins replicape specific.

@jannau
Copy link
Contributor Author

jannau commented Mar 25, 2019

I made the servo pins replicape specific to force the hardware_pwm protocol upon them.

@KevinOConnor
Copy link
Collaborator

Thanks! In general, it looks good to me.

A couple of minor comments:

  • I think it would be preferable if the replicape.py code hardcoded the pins instead of the linux C code. For example with C code using something like:
#define HARD_PWM_START (1<<16)
#define HARD_PWM(chip, pin) (((chip)<<8) + (pin) + HARD_PWM_START)
#define HARD_PWM_TO_CHIP(hard_pwm) (((hard_pwm) - HARD_PWM_START) >> 8)
#define HARD_PWM_TO_PIN(hard_pwm)  (((hard_pwm) - HARD_PWM_START) & 0xff)

DECL_ENUMERATION_RANGE("pin", "pwmchip0/pwm0", HARD_PWM(0, 0), 256);
DECL_ENUMERATION_RANGE("pin", "pwmchip1/pwm0", HARD_PWM(1, 0), 256);
DECL_ENUMERATION_RANGE("pin", "pwmchip2/pwm0", HARD_PWM(2, 0), 256);
DECL_ENUMERATION_RANGE("pin", "pwmchip3/pwm0", HARD_PWM(3, 0), 256);
  • It would be nice (but not a requirement) if the servo0_enable/servo1_enable config items could be removed and the mere existence of a replicape:servo0/replicape:servo1 pin definition would internally cause them to be enabled. (That is, instead of defining replicape:P9_14/replicape:P9_28, define more human readable names and make them auto-activate.)

-Kevin

@jannau jannau force-pushed the replicape_servo branch 2 times, most recently from efb23a9 to 48d3eee Compare March 29, 2019 17:18
@jannau
Copy link
Contributor Author

jannau commented Mar 29, 2019

Don't merge for now. My extruder is suddenly skipping steps. Not sure if there's something wrong in the change or if I somehow managed to damage the replicape. I have unfortunately no time to investigate it before next week.

@jannau
Copy link
Contributor Author

jannau commented Apr 3, 2019

The problem was a broken stepper motor cable. The change works as expected.

@KevinOConnor
Copy link
Collaborator

Thanks. I committed the change to use 16bit integers for the pwmcmds.c code, and I also committed the Linux pwm support. I didn't commit the replicape.py code as I have a few questions.

  1. The replicape schematics refer to the pins as servo0 and servo1. Should the Klipper names really be servo1 and servo2?
  2. I'm not sure what the pin aliases are supposed to do. In general, it's preferable not to add new content to pins.py. Couldn't the replicape.py code create the hard pwm pin with the desired pwmchip0/pwm0 and pwmchip0/pwm1 names directly? For example (totally untested), something like:
SERVO_PINS = {
    "servo0": ("pwmchip0/pwm0", "gpio0_30", "gpio1_18"), # P9_11, P9_14
    "servo1": ("pwmchip0/pwm1", "gpio3_17", "gpio1_19"), # P9_28, P9_16
}

class servo_pwm:
    def __init__(self, replicape, pin_params):
        pwm_pin, resv1, resv2 = SERVO_PINS[pin_params['pin']]
        pin_params = dict(pin_params)
        pin_params[pin] = pwm_pin
        # Setup actual pwm pin using linux hardware pwm on host
        self.mcu_pwm = replicape.host_mcu.setup_pin("pwm", pin_params)
        self.get_mcu = self.mcu_pwm.get_mcu
        self.setup_max_duration = self.mcu_pwm.setup_max_duration
        self.setup_start_value = self.mcu_pwm.setup_start_value
        self.set_pwm = self.mcu_pwm.set_pwm
        # Reserve pins to warn user of conflicts
        pru_mcu = replicape.mcu_pwm_enable.get_mcu()
        ppins = printer.lookup_object('pins')
        ppins.reserve_pin(pru_mcu.get_name(), resv1, "servo")
        ppins.reserve_pin(pru_mcu.get_name(), resv2, "servo")
    def setup_cycle_time(self, cycle_time, hardware_pwm=False):
        self.mcu_pwm.setup_cycle_time(cycle_time, True);

-Kevin

@jannau
Copy link
Contributor Author

jannau commented Apr 6, 2019

Thanks.

  1. I took the names for the connectors from https://wiki.thing-printer.com/index.php?title=Replicape_rev_B#Connector_overview and was a little annoyed that both 0 and 1 are used as first index. I happily use the schematics as source for the pin names. servo0/servo1 is more consistent with how other pins are numbered.

  2. There is no need to use the pin aliases in pins.py. I thought the translation between config names and mcu names was supposed to handled this way. I'll test your code and update the PR.

The servo pins (P9_14/P9_16) are muxed to the SOCs hardware PWM unit
driven by a 13MHz GP timer. They have to be driven by the linux host
mcu. This commits adds hardware PWM support using the linux sysfs
user space interface.

The servo pins can be specified as "replicape:servo0" and
"replicape:servo1". Removes the "servo0_enable", "servo1_enable"
configuration parameters.
Fixes Klipper3d#1105.

Signed-off-by: Janne Grunau <janne-3d@jannau.net>
@jannau
Copy link
Contributor Author

jannau commented Apr 6, 2019

pin names updated to servo0/1 and implemented the proposed servo pwm init method.

@KevinOConnor KevinOConnor merged commit 478a916 into Klipper3d:master Apr 6, 2019
@KevinOConnor
Copy link
Collaborator

Thanks.

-Kevin

@jannau jannau deleted the replicape_servo branch April 6, 2019 18:50
@chappo
Copy link

chappo commented Apr 9, 2019

Thanks for all the work so far Jannau / Kevin.

Have an issue allocating the pwm device for the bltouch on a fresh Debian Stretch install, downgraded kernel to 4.4.155-ti-r154. Upgraded bb-overlays.

Any help will be greatly appreciated.

Host is unable to configure pwm device -

MCU 'host' shutdown: Unable to config pwm device
Once the underlying issue is corrected, use the
"FIRMWARE_RESTART" command to reset the firmware, reload the
config, and restart the host software.
Printer is shutdown
Klipper state: Not ready

Version.sh output -
version (2).txt
printer.cfg
printer.cfg.txt
klippy.log
klippy.log.txt

@jannau
Copy link
Contributor Author

jannau commented Apr 9, 2019

Are you sure the PRU is set up correctly? Unable to open port: [Errno 2] No such file or directory: '/dev/rpmsg_pru30' from your klippy.log is suspicious. I don't see how that could relate to the pwm error though unless uboot can't load the devicetree overlays.

Otherwise I don't see anything wrong there except for the obvious error to configure the pwm in the klippy.log. Config and Kernel are almost identical to mine. Please attach the output of following commands.

ls -l /sys/class/pwm/
ls -lH /sys/class/pwm/*
grep -r pwm /sys/kernel/debug/pinctrl/

@chappo
Copy link

chappo commented Apr 9, 2019

The Pru error was only temporary. That is working OK. Output of those commands below -

debian@beaglebone:~$ ls -l /sys/class/pwm/
total 0
lrwxrwxrwx 1 root pwm 0 Apr  8 23:56 pwmchip0 -> ../../devices/platform/ocp/48302000.epwmss/48302200.pwm/pwm/pwmchip0

debian@beaglebone:~$ ls -lH /sys/class/pwm/*
total 0
lrwxrwxrwx 1 root pwm    0 Apr  8 23:56 device -> ../../../48302200.pwm
-rw-rw---- 1 root pwm 4096 Apr  8 23:56 export
-rw-rw-r-- 1 root pwm 4096 Apr  8 23:56 npwm
drwxrwxr-x 2 root pwm    0 Apr  8 23:56 power
lrwxrwxrwx 1 root pwm    0 Apr  8 23:56 subsystem -> ../../../../../../../class/pwm
-rw-rw-r-- 1 root pwm 4096 Apr  8 23:56 uevent
-rw-rw---- 1 root pwm 4096 Apr  8 23:56 unexport

debian@beaglebone:~$ grep -r pwm /sys/kernel/debug/pinctrl/
/sys/kernel/debug/pinctrl/44e10800.pinmux/pinmux-pins:pin 18 (44e10848.0): ocp:pwm_enable (GPIO UNCLAIMED) function pinmux_servo_pins group pinmux_servo_pins
/sys/kernel/debug/pinctrl/44e10800.pinmux/pinmux-pins:pin 19 (44e1084c.0): ocp:pwm_enable (GPIO UNCLAIMED) function pinmux_servo_pins group pinmux_servo_pins
/sys/kernel/debug/pinctrl/pinctrl-handles:device: ocp:pwm_enable current state: default
/sys/kernel/debug/pinctrl/pinctrl-maps:device ocp:pwm_enable

@jannau
Copy link
Contributor Author

jannau commented Apr 10, 2019

@chappo , please try

echo -n 0 > /sys/class/pwm/pwmchip0/export
echo -n 1 > /sys/class/pwm/pwmchip0/export

After that you should have pwm0 and pwm1 in /sys/class/pwm/pwmchip0/ and everything hopefully works. I have no idea why the channels are not exported though.
Can you check if /etc/udev/rules.d/81-pwm-noroot.rules exists on your system? That one is responsible to export the pwm channels.

@chappo
Copy link

chappo commented Apr 10, 2019

Alright - so that has had resolved the issue until a reboot.

Using the above export options I then need to use the chmod and permissions mod found in the 81-pwm file before restarting klipper.

Can then get klipper running and deploy and retract the touch. The blue light only stays on for a few seconds and the endstop doesn't seem to trigger but they may be a fault of my touch (clone) - still working on that one.

81-pwm-noroot.rules.txt

@jannau
Copy link
Contributor Author

jannau commented Apr 11, 2019

Yes, it's only a momentarily fix to debug why your systems behaves differently than mine. Your 81-pwm-noroot.rules looks outdated, it looks like this for me. It looks like your system is not up to date. The pwm udev file is part of bb-customizations and I have version 1.20190403.1-0rcnee0~stretch+20190403 installed.

@chappo
Copy link

chappo commented Apr 11, 2019

Thanks, that has resolved that issue. But still unable to trigger the end stop, and pwm only appears momentary. Blue light/servo goes off after a couple of seconds.

Appreciate the work on this so far - was contemplating moving away from the replicape and back to ramps.

cruwaller pushed a commit to cruwaller/klipper that referenced this pull request Jul 11, 2019
The servo pins (P9_14/P9_16) are muxed to the SOCs hardware PWM unit
driven by a 13MHz GP timer. They have to be driven by the linux host
mcu. This commits adds hardware PWM support using the linux sysfs
user space interface.

The servo pins can be specified as "replicape:servo0" and
"replicape:servo1". Removes the "servo0_enable", "servo1_enable"
configuration parameters.
Fixes Klipper3d#1105.

Signed-off-by: Janne Grunau <janne-3d@jannau.net>
Conflicts:
	config/generic-replicape.cfg
FHeilmann pushed a commit to FHeilmann/klipper that referenced this pull request Jan 28, 2020
The servo pins (P9_14/P9_16) are muxed to the SOCs hardware PWM unit
driven by a 13MHz GP timer. They have to be driven by the linux host
mcu. This commits adds hardware PWM support using the linux sysfs
user space interface.

The servo pins can be specified as "replicape:servo0" and
"replicape:servo1". Removes the "servo0_enable", "servo1_enable"
configuration parameters.
Fixes Klipper3d#1105.

Signed-off-by: Janne Grunau <janne-3d@jannau.net>
@github-actions github-actions bot locked and limited conversation to collaborators Oct 23, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants