This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

PROCESSOR-SDK-AM65X: eHRPWM control via sysfs

Part Number: PROCESSOR-SDK-AM65X


Hi forum,

I'm trying to figure out how Linux maps the eHRPWM channels to the sysfs interface, accessible via /sys/class/pwm.  I have enabled the A and B pins for each PWM, and set the status for &ehrpwm0 through &ehrpwm5 to "okay".  When Linux boots, I can see the following after cd /sys/class/pwm:

# pwd
/sys/class/pwm
# ls
pwmchip0   pwmchip1   pwmchip11  pwmchip3   pwmchip5   pwmchip7   pwmchip9
# cd pwmchip0
# ls
device     export     npwm       power      subsystem  uevent     unexport
# ls device
driver           modalias         power            subsystem
driver_override  of_node          pwm              uevent
# cat device/modalias
of:NpwmT<NULL>Cti,am654-ecapCti,am3352-ecap
# cd ..
# cat pwmchip1/device/modalias
of:NpwmT<NULL>Cti,am654-ehrpwmCti,am3352-ehrpwm
# cat pwmchip3/device/modalias
of:NpwmT<NULL>Cti,am654-ehrpwmCti,am3352-ehrpwm
# cat pwmchip5/device/modalias
of:NpwmT<NULL>Cti,am654-ehrpwmCti,am3352-ehrpwm
# cat pwmchip7/device/modalias
of:NpwmT<NULL>Cti,am654-ehrpwmCti,am3352-ehrpwm
# cat pwmchip9/device/modalias
of:NpwmT<NULL>Cti,am654-ehrpwmCti,am3352-ehrpwm

From this I can figure out that pwmchip0 is controlled by eCAP, whereas pwmchip1, 3, 5, 7, and 9 are eHRPWM.

How can I figure out which pwmchipX is connected to eHRPWM0, 1, 2, 3, 4, and 5?

Also, can anyone provide an example of how to create the two PWM channels for an eHRPWM, set the duty cycle and period, and then enable the PWM?

I think that it's something like:

# Which eHRPWM is this?
cd /sys/class/pwm/pwmchipX
# Create pwm0 and pwm1
echo 0 > export
echo 1 > export
# Set up pwm0
cd pwm0
# What are the units for duty_cycle and period???
echo NNN > duty_cycle
echo MMM > period
# Set active high polarity
echo 1 > polarity
# Turn on the PWM
echo 1 > enable

Is this the correct approach?  If so, what are the allowed values for duty_cycle and period?

Thanks very much for your help - there has to be a simple answer to this!

Scott

  • Another question:  What do I need to do to enable the eHRPWM driver/module in Linux?

    Many thanks!

    Scott

  • One more, showing my lack of experience with the EHRPWM:  Does a clock source need to be set up before the PWMs will actually run?  Can someone provide an example of how  to set up a clock source if needed?

    Thanks again,

    Scott

  • Hello Scott,

    What version of Processor SDK are you using?

    Regards,

    Nick

  • Hi Nick,

    Sorry, should have specified. It's 06.00.00.07.

    Thanks!

    Scott

  • Hello Scott,

    Some of your questions are answered in our Processor SDK PWM driver documentation. Please check it out, and let me know what your remaining questions are.

    I am still looking into whether there is a way to determine which PWM is associated with which sysfs entry.

    Regards,

    Nick

  • Thanks Nick,

    In particular, I am trying to find out what the allowable range of values are for the following:

    # What are the units for duty_cycle and period???
    echo NNN > duty_cycle
    echo MMM > period

    The documentation you referred me to seems to indicate that these values are in nanoseconds, so if I perform the following, I should be able to run a 1 second PWM with a 50% duty cycle by specifying 1000000000 (1e9) for the period and 500000000 (5e8) for the duty_cycle.  However, I get invalid value parameters:

    # cd /sys/class/pwm
    # ls
    pwmchip0   pwmchip1   pwmchip11  pwmchip3   pwmchip5   pwmchip7   pwmchip9
    # cd pwmchip1
    # echo 0 > export
    # echo 1 > export
    # cd pwm0
    # echo 1000000000 > period
    [  811.530685] ehrpwm 3000000.pwm: Unsupported values
    sh: write error: Invalid argument
    # echo 1000000000 > duty_cycle
    sh: write error: Invalid argument
    

    -> Clearly there is some limit on the allowed range of the eHRPWM period and duty cycle, but I do not know what it is.  I also do not know what the units (nanoseconds, microseconds, etc.) are.

    -> Can you please clarify?  If possible, could you try an example on the AM65X-EVM board to see if some pair of eHRPWM outputs work, and let me know what the resulting period and duty cycles are?  If you could post your example in your reply, that would be a huge help.

    Also looking forward to trying to figure out how each pwmchipX is mapped to a corresponding eHRPWM instance.

    After cd /sys/class/pwm, I did an ls -al, and found the following symbolic link info:

    # pwd
    /sys/class/pwm
    # ls -al
    total 0
    drwxr-xr-x    2 root     root             0 Dec 21 18:53 .
    drwxr-xr-x   55 root     root             0 Dec 21 18:53 ..
    lrwxrwxrwx    1 root     root             0 Dec 21 18:53 pwmchip0 -> ../../devic
    es/platform/interconnect@100000/3100000.pwm/pwm/pwmchip0
    lrwxrwxrwx    1 root     root             0 Dec 21 18:53 pwmchip1 -> ../../devic
    es/platform/interconnect@100000/3000000.pwm/pwm/pwmchip1
    lrwxrwxrwx    1 root     root             0 Dec 21 18:53 pwmchip11 -> ../../devi
    ces/platform/interconnect@100000/3050000.pwm/pwm/pwmchip11
    lrwxrwxrwx    1 root     root             0 Dec 21 18:53 pwmchip3 -> ../../devic
    es/platform/interconnect@100000/3010000.pwm/pwm/pwmchip3
    lrwxrwxrwx    1 root     root             0 Dec 21 18:53 pwmchip5 -> ../../devic
    es/platform/interconnect@100000/3020000.pwm/pwm/pwmchip5
    lrwxrwxrwx    1 root     root             0 Dec 21 18:53 pwmchip7 -> ../../devic
    es/platform/interconnect@100000/3030000.pwm/pwm/pwmchip7
    lrwxrwxrwx    1 root     root             0 Dec 21 18:53 pwmchip9 -> ../../devic
    es/platform/interconnect@100000/3040000.pwm/pwm/pwmchip9
    

    From looking at the register values I have "bolded" in the Technical Reference Manual, it seems like:

    pwmchip0  -> ECAP0_CTL_STS
    pwmchip1  -> EHRPWM0_EPWM
    pwmchip3  -> EHRPWM1_EPWM
    pwmchip5  -> EHRPWM2_EPWM
    pwmchip7  -> EHRPWM3_EPWM
    pwmchip9  -> EHRPWM4_EPWM
    pwmchip11 -> EHRPWM5_EPWM
    

    I'm inferring this from entries like 3100000.pwm/pwm/pwmchip0, and then looking up address 0x0003100000 in Table 2.1 (MAIN Domain Memory Map) in the TRM.  Does this make sense?

    Thanks very much for your help!

    Best regards,

    Scott

  • Hello Scott,

    sysfs mapping

    It looks like sysfs entries are populated in the order that device tree nodes are created. Note that device tree files are read in the order that they are included. So if myBoard.dts includes myInclude1.dtsi which includes myInclude2.dtsi, then when the kernel loads myBoard.dtb, it reads myInclude2.dtsi contents, then myInclude1.dtsi contents, then myBoard.dts contents.

    The ehrpwm nodes are defined in arch/arm64/boot/dts/ti/k3-am65-main.dtsi. So the first ehrpwm node defined should have the lowest sysfs number, the second should have the next-lowest sysfs number, and so on. That matches the mapping that you figured out from the ls -al

    I'll need a bit to look at the other parts of your question. Feel free to continue to play around with it.

    Regards,

    Nick

  • Thanks, Nick,

    I think I'm pretty comfortable finding which pwmchipX number goes with which eHRPWM node.  I can create two PWM channels using

    echo 0 > export; echo 1> export

    I still have not figured out how to set the parameters for pwm0 and pwm1 correctly, and could certainly use your help with that!

    Under pwm0, there are the following entries:

    capture     enable      polarity    uevent
    duty_cycle  period      power

    I think that I need to set the period and duty_cycle, and then set enable to 1, but I still do not know what the units and limits are for period and duty_cycle.

    I'm continuing to play with it, but do not have an EVM board, so if something does not work it's not clear if that's due to a problem on our custom hardware or an error in the way I have set things up.  Again, if you could run an experiment on an AM65X-EVM board, that would be a huge help!

    I sincerely appreciate your efforts in getting me this information.  Hoping to report back to this thread with a solution that will benefit anyone wanting to create simple PWM signals from the command line interface.

    Best regards,

    Scott

  • Hello Scott,

    When tinkering around with this, I do not see any errors on the eCAP PWM with period = 1000000000 ns. I do see errors on the eHRPWM with any period above around 939000000 ns, as you report. The driver code is not super straightforward, so I'm checking in with the developer.

    Regards,

    Nick

  • Hi Nick,

    Thanks for your diligence on this. I'm looking forward to hearing about the results, and hope this thread will help everyone utilize the eHRPWM more effectively.

    Best regards and sincere thanks,

    Scott

  • Hello Scott,

    Short answer: AM65x eHRPWM max period is around 0.94s. eCAP period is 1s.

    Long answer: (quote from developer)

    These calculations are slightly complex and depends on the input functional clk(fclk) frequency of the module (which varies across SoC). Below is the calculations for AM65x

    For EHRPWM:

    Time base counter (TBCLK) clk is used to count period.

    TBCLK frequency = fclk / Prescaler

    Max value for prescaler = 1792 and Min value = 1

    On AM65, fclk = 125Mhz, so with prescaler TBCLK (min freq) =  ~70KHz

    Period counter range is 0 to 65535. So max period would be 65535/70KHz = ~.94s (max period)

    For ECAP:

    Period counter is 32 bit register (2^32 -1) so for a fclk of 125MHz so max 34s can be supported. Linux restricts this to 1s

    Follow-up: 

    Thank you for bringing this up to me. Our PWM documentation is currently written with an eCAP focus, but it also needs to be eHRPWM friendly. I am still talking with the developer about what changes should be made to the documentation, driver outputs, etc to make this more customer friendly. Any feedback is welcome.

    Regards,

    Nick