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.

DRA829J: EHRPWM precision

Part Number: DRA829J

Hello experts,

We have a tricky situation regarding creation of a 10 MHz clock signal for an external chip.

We have successfully created the waveform using ehrpwm0, by setting period to 100 and duty-cycle to 50. The
problem is that the resulting waveform is either 9.6 MHz or 10.4 MHz, which is to coarse for the external
component to function properly.

On our custom design, we have the possibility to use either pin V29 or AB1. Is there any of the options on either
of these pins that would give us a 10 MHz clock with better precision?

The two pins have these possibilities:

V29:


AB1:

One idea is to use the spi2_clk. Could this be a plausible way? Can it be configured to be continuous?

Best regards,

/Bo

  • Can you take a look at TIMER_IO7 and TRM section "Timer Pulse-Width Modulation" to see if that would work for you. Also see TRM section "TIMER Clocks and Resets" for the list of options for the Functional Clock source.

  • Thank you B.C.

    TIMER_IO seems like a way forward. Can you point me to any examples of how to set it up?

    Regards,

    /Bo

  • Hi Bo,

    What core are you using this, and what OS is this running?

    We may not have reference PWM code for all different combinations.

    regards

    Suman

  • Hello Suman,

    This is from A72 cores. We run Linux 6.1, but we also need it for U-Boot (2023-04).

    Regards,

    /Bo

  • Hi Bo,

    The EHRPWM IP is supported in the Linux kernel through the drivers/pwm/pwm-tiehrpwm.c driver. This plugs into the Linux Kernel PWM subsystem. 

    You should be able to use the PWM sysfs interfaces to operate on it. Please see the Linux Kernel PWM documentation for more details.

    but we also need it for U-Boot (2023-04)

    PWM is not essential for boot, so I doubt we have a PWM driver in U-Boot.

    regards

    Suman

  • Hi Suman,

    Too bad that my recent edit of my post went missing. This is what I wrote:

    I have successfully configured the other pin to TIMER_IO7. Since this is per default tied to TIMER0, I booted into Linux and tampered with the registers for TIMER0:

    devmem2 0x02400040 w 0xfffffffe <-- To set the (re)load value
    devmem2 0x0240003c w 0xffffffff <-- To set the counter
    devmem2 0x02400038 w 0x1443 <-- Trigger on overflow and toggle on trigger

    This gave me a pulse train on TIMER_IO7 of about 4.8 MHz.

    My problem now is that I need a faster clock to TIMER0 since the above is a fast as I can go. I have tried to change register 0x00108100 (CTRLMMR_TIMER0_CLKSEL). This register is the mux for clock select but whatever I set it to, it stays at 0, which is WKUP_HFOSC0_CLKOUT which seems to be 19.2 MHz (hence the 4.8 MHz resulting pulse train).

    How can I change this mux to a faster clock; one that is a multiple of 10 MHz?

    EDIT: I found the LOCK0 and LOCK1 registers, unlocked partition 2 and was able to change the clock to # 0x0f, which seems to be 100 MHz. Setting my load register to 0xfffffff7 gave me a nice 10 MHz pulse train.

    I still have problems creating this in U-Boot, unfortunately.

    Regards,

    /Bo

  • Hi Bo,

    I have successfully configured the other pin to TIMER_IO7. Since this is per default tied to TIMER0, I booted into Linux and tampered with the registers for TIMER0:

    TIMER_IO7 is not associated with TIMER0, but TIMER7. I am not sure how you arrived at this being the default tie-in to TIMER0.

    Please also note that the TIMERs are also used as the RTOS OS tick sources for the MAIN R5F cores. If running these, please make sure that you are not booting any R5F cores.

    My problem now is that I need a faster clock to TIMER0 since the above is a fast as I can go. I have tried to change register 0x00108100 (CTRLMMR_TIMER0_CLKSEL). This register is the mux for clock select but whatever I set it to, it stays at 0, which is WKUP_HFOSC0_CLKOUT which seems to be 19.2 MHz (hence the 4.8 MHz resulting pulse train).

    What is the Crystal frequency you are using on your board? 4.8 MHz sounds like the Crystal is indeed 19.2 MHz. Do you use one or two crystals on your board? The first 2 input clocks to Timer are driven by the Crystal, so if it is not 20 MHz, then you would have to look for an alternate PLL divider clock that can provide you the necessary multiple clock. You can look through the J721E PLL Defaults to see which of the HSDIVs may provide you a multiple, but do note that these are lot more higher frequency clocks.

    The CTRL_MMR registers have a Protection Lock registers, you need to unlock the Kick registers to allow you to program these registers. Please see 5.1.3.3.1.2 Kick Protection Registers. You will need to unlock the CTRLMMR_LOCK2_KICK0 and CTRLMMR_LOCK2_KICK1 registers before modifying the Timer Clock Mux register.

    regards

    Suman

  • Hi Bo,

    EDIT: I found the LOCK0 and LOCK1 registers, unlocked partition 2 and was able to change the clock to # 0x0f, which seems to be 100 MHz. Setting my load register to 0xfffffff7 gave me a nice 10 MHz pulse train.

    I missed seeing this. You have already modified exactly what I was saying.

    I still have problems creating this in U-Boot, unfortunately.

    I don't think we have a driver for this at U-Boot prompt. If you modify the registers using mw, you should be able to get the same functionality. Please do verify that the PinMux is getting configured at U-Boot for your needs.

    regards

    Suman

  • Hi Suman,

    TIMER_IO7 is not associated with TIMER0, but TIMER7. I am not sure how you arrived at this being the default tie-in to TIMER0.

    I took this information from the Register Documentation:

    Also, the register reads 0x0 per default.

    Please also note that the TIMERs are also used as the RTOS OS tick sources for the MAIN R5F cores. If running these, please make sure that you are not booting any R5F cores.

    Where can I read more about this? We are going to run R5F-cores in the future.

    I don't think we have a driver for this at U-Boot prompt. If you modify the registers using mw, you should be able to get the same functionality. Please do verify that the PinMux is getting configured at U-Boot for your needs.

    I have tried this, but there seems to be something else missing in U-Boot, since I can't get a pulse out from TIMER_IO7. The pinmux is set to be the same as in the Linux setup.

    Regards,

    /Bo

  • Hi Suman,

    You were right about verifying the pinmux. Even though it is set correctly in the U-Boot dts, it seems to be default when I check the register in U-Boot. Setting it correctly to use mux 1 for TIMER_IO7 made the pulse appear on my oscilloscope.

    Is it because there is no user of the pinmux setting that makes it stay "unset"?

    Regards,

    /Bo

  • Hi Bo,

    Where can I read more about this? We are going to run R5F-cores in the future.

    The timer assignments are done statically in a header file in the OSAL layer. You can look up the assignments within the RTOS SDK in the

    <RTOS_SDK>/<PDK>/packages/ti/osal/soc/j721e/osal_soc.h file.

    The MAIN domain DMTimers 0, 1 and 2 are assigned to the DSPs, and the DMTimers 12, 13, 14 and 15 are assigned to the MAIN domain R5F cores. 

    Setting it correctly to use mux 1 for TIMER_IO7 made the pulse appear on my oscilloscope.

    Good to hear that.

    Is it because there is no user of the pinmux setting that makes it stay "unset"?

    How are you setting the pinmux in U-Boot? Can you share the dts snippet of your modification.

    The U-Boot driver probes do not happen automatically, like they would in kernel. 

    regards

    Suman

  • Hi Suman,

    How are you setting the pinmux in U-Boot? Can you share the dts snippet of your modification.

    Sure. I added main_timerio_output and main_timer0 from upstream into k3-j721e-main.dtsi:

    	/* TIMERIO pad output CTCTRLMMR_TIMERIO*_CTRL registers */
    	main_timerio_output: pinctrl@104280 {
    		compatible = "pinctrl-single";
    		reg = <0x00 0x104280 0x00 0x20>;
    		#pinctrl-cells = <1>;
    		pinctrl-single,register-width = <32>;
    		pinctrl-single,function-mask = <0x0000001f>;
    	};
    
    	main_timer0: timer@2400000 {
    		compatible = "ti,am654-timer";
    		reg = <0x00 0x2400000 0x00 0x400>;
    		interrupts = <GIC_SPI 224 IRQ_TYPE_LEVEL_HIGH>;
    		clocks = <&k3_clks 49 1>;
    		clock-names = "fck";
    		assigned-clocks = <&k3_clks 49 1>;
    		assigned-clock-parents = <&k3_clks 49 2>;
    		power-domains = <&k3_pds 49 TI_SCI_PD_EXCLUSIVE>;
    		ti,timer-pwm;
    	};

    I then referenced it in my own dts:

    &main_pmx0 {
    	lonclk_pin_default: lonclk-pin-default {
    		pinctrl-single,pins = <
    			J721E_IOPAD(0x1f4, PIN_OUTPUT, 1) /* (AB1) TIMER_IO7 */
    		>;
    	};
    };
    
    &main_timer0 {
    	status = "okay";
    	pinctrl-names = "default";
    	pinctrl-0 = <&lonclk_pin_default>;
    };
    
    &main_timerio_output {
    	status = "okay";
    };
    

    Regards,

    /Bo

  • Hi Bo,

    Thank you for the details. IIUC, you are only modifying the k3-j721e-main.dtsi and your board dts file, correct? Did you make any modifications in the corresponding <board>-u-boot.dtsi file?

    Please note that the U-Boot devicetree works slightly differently w.r.t the Linux Kernel devicetree. Nodes are not auto-probed in U-Boot and one would need to add U-Boot specific flags to have the DT nodes effective for U-Boot.

    regards

    Suman

  • Hi Suman,

    Did you make any modifications in the corresponding <board>-u-boot.dtsi file?

    No, I did not. Is that necessary?

    Nodes are not auto-probed in U-Boot and one would need to add U-Boot specific flags to have the DT nodes effective for U-Boot.

    Where can I find info on these flags?

    Regards,

    /Bo

  • Hi Bo,

    No, I did not. Is that necessary?

    I was just confirming whether you have made any changes or not. It depends on what you are trying to do.

    You can look through the U-Boot's Devicetree in U-Boot documentation. U-Boot does rely on some custom properties that are not part of the Linux kernel for it's use. You can look for details in the U-Boot doc/device-tree-bindings folder, do look at the chosen.txt and config.txt files.

    Where can I find info on these flags?

    There are some DT node properties that use a prefix "u-boot,xxxx", like u-boot,mux-autoprobe that allows a mux device to be auto-probed. Grep for u-boot, under the doc/device-tree-bindings folder

    regards

    Suman