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.

Compiler/AM3352: Using Timer to create square wave output

Part Number: AM3352

Tool/software: TI C/C++ Compiler

Hi 

I'm working on a custom board based around the beagle bone black and would like to generate a square wave from a specific pin to serve as a clock for a peripheral

that pins is GPMC_ADVN_ALE/TIMER4/GPIO2_2 and I would be looking for a frequency around 330kHz

I am wondering what would be the best way to control this?

I can see in my files system the folder /sys/kernel/debug/clk/timer4_fck but its not immediately obvious how I should be driving this

From my compiled device-tree (viewed with fdtdump) the relevant entries for timer 4 appear to be:

                          timer4_fck@510 {
                                #clock-cells = <0x00000000>;
                                compatible = "ti,mux-clock";
                                clocks = <0x00000016 0x00000009 0x00000015 0x00000000 0x00000000>;
                                reg = <0x00000510>;
                            };

                target-module@44000 {
                    compatible = "ti,sysc-omap4-timer", "ti,sysc";
                    ti,hwmods = "timer4";
                    reg = <0x00044000 0x00000004 0x00044010 0x00000004 0x00044014 0x00000004>;
                    reg-names = "rev", "sysc", "syss";
                    ti,sysc-mask = <0x00000001>;
                    ti,sysc-sidle = <0x00000000 0x00000001 0x00000002 0x00000003>;
                    clocks = <0x0000002f 0x00000050 0x00000000>;
                    clock-names = "fck";
                    #address-cells = <0x00000001>;
                    #size-cells = <0x00000001>;
                    ranges = <0x00000000 0x00044000 0x00001000>;
                    timer@0 {
                        compatible = "ti,am335x-timer";
                        reg = <0x00000000 0x00000400>;
                        interrupts = <0x0000005c>;
                        ti,timer-pwm;
                    };
                };

I would be very grateful for any suggestions as to how this might be done

Best regards,

- Richard

  • Hello Richard,

    There are multiple ways to get a PWM signal:
    * the PWM subsystem (see our Linux PWM kernel driver documentation)
    * bit-banging a PWM signal from PRU GPO pins
    * use a timer (take a look at pwm-omap-dmtimer. Documentation under Documentation/devicetree/bindings/pwm/pwm-omap-dmtimer.txt, driver at drivers/pwm/pwm-omap-dmtimer.c).

    We do not suggest using Linux to generate a PWM signal on a regular GPIO signal.

    It sounds like you would probably want to look at the timer driver first. Note that TI did not write that driver or maintain it, so I will only be able to offer limited support if you run into challenges using it.

    Regards,

    Nick

  • Thanks for the pointers

    as ever with this stuff it's finding out the intended driver that's the hard part

    after adding a pwm entry to the device tree:

      pwm4: dmtimer-pwm@4 {
              compatible = "ti,omap-dmtimer-pwm";
              ti,timers = <&timer4>;
              #pwm-cells = <3>;
              pinctrl-names = "default";
              pinctrl-0 = <&timer4_pins>;
      };

    and enabling the driver in my config

    CONFIG_PWM_OMAP_DMTIMER=y

    there is a directory in my rootfs /sys/class/pwm/pwmchip0

    root@my-board:/sys/class/pwm/pwmchip0# ls -la
    drwxr-xr-x    3 root     root             0 Jan  1 00:00 .
    drwxr-xr-x    3 root     root             0 Jan  1 00:00 ..
    lrwxrwxrwx    1 root     root             0 Jan  1 00:00 device -> ../../../dmtimer-pwm@4
    --w-------    1 root     root          4096 Jan  1 00:00 export
    -r--r--r--    1 root     root          4096 Jan  1 00:00 npwm
    drwxr-xr-x    2 root     root             0 Jan  1 00:00 power
    lrwxrwxrwx    1 root     root             0 Jan  1 00:00 subsystem -> ../../../../../class/pwm
    -rw-r--r--    1 root     root          4096 Jan  1 00:00 uevent
    --w-------    1 root     root          4096 Jan  1 00:00 unexport
    
    

    after echo-ing 0 to export there appeared

    root@my-board:/sys/class/pwm/pwmchip0/pwm0# ls -la
    drwxr-xr-x    3 root     root             0 Jan  1 00:01 .
    drwxr-xr-x    4 root     root             0 Jan  1 00:00 ..
    -r--r--r--    1 root     root          4096 Jan  1 00:01 capture
    -rw-r--r--    1 root     root          4096 Jan  1 00:01 duty_cycle
    -rw-r--r--    1 root     root          4096 Jan  1 00:02 enable
    -rw-r--r--    1 root     root          4096 Jan  1 00:01 period
    -rw-r--r--    1 root     root          4096 Jan  1 00:01 polarity
    drwxr-xr-x    2 root     root             0 Jan  1 00:01 power
    -rw-r--r--    1 root     root          4096 Jan  1 00:01 uevent

    using this was as simple as:

    # echo 3000 > period 

    # echo 1500 > duty_cycle

    # echo 1 > enable

    giving me a square wave on the pin at 333kHz

    Thanks again

    - Richard

  • Hello Richard,

    Thanks for replying back with your solution! I'll make a note on my side to point future PWM customers to your thread.

    Regards,

    Nick