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.

Timer4 "PORTIMERPWM" signal out

Hello,

I am having trouble to get the above signal out on timer4 pin.

First I've modified CM_PER register to enable clock out.

I've configured the registers TCLR |=1+ 1<<1 + 1<<4 + 1<<5 +1<<11 + 1<<12 and put a value in TMAR register.

I read the value  of the registers again to make sure and it's ok.

But nothing comes out .

On the device tree overlay side , I've added a device tree file to mux the pin .

Any Ideas?

  • Tomer ma said:
    First I've modified CM_PER register to enable clock out.

    There's no setting in CM_PER to enable timer4's clock out, you only enable the timer itself there. Also make sure the desired clock source is selected for the timer (I've noticed the defaults in the TRM aren't necessarily still true after bootrom, and I'm not sure whether linux fixes them up).

    Tomer ma said:
    TCLR |=1+ 1<<1 + 1<<4 + 1<<5 +1<<11 + 1<<12

    << has lower precedence than +, so this would be interpreted as (1+1) << (1+1) << (4+1) << (5+1) << (11+1) << 12.  I strongly suggest compiling with -Wall -Wextra -Werror (and as needed selectively disable warnings, or make them non-fatal with e.g. -Wno-error=unused-variable) since the compiler would have complained about this.

    Combine the options using | instead, and when not using constants (sometimes it can be clearer for debugging to have the actual values easily visible in the source) I suggest the following style:

            timer4.config = 0
                    | 1 <<  0  // timer enabled
                    | 1 <<  1  // auto-reload enabled
                    | 1 <<  5  // prescale divider enabled
                    | 4 <<  2  // prescale divider 2^(1+4) = 32
                    | 0 << 14  // configure pin as pwm output
                    | 0 <<  7  // pwm output default low
                    | 1 << 12  // toggle pwm output on trigger
                    | 2 << 10  // trigger on overflow and match
                    ;

    This way you can see both the values and their purpose, and easily disable options by commenting them out. (I also describe the register map using a struct with register names that make more sense to me than the official ones, but a preference to stick to TRM terminology would also be understandable.)

    I'm actually not sure if bit 7 can be configured in the same write as enabling the timer with pwm output enabled, it may be safer to enable the timer in a separate write.

    If the timer is set to posted mode, be sure to poll the "write posted status" after a write to confirm its completion. It's not entirely clear to me whether the "TIMER clk" in the discussion of posted versus non-posted mode in the TRM refers to the functional clock or the prescaled clock. If it means the functional clock (and I think it does), main osc is selected as clock source, and main osc is >= 25 MHz, non-posted mode should be configured instead.

    Also, when bypassing the kernel and manually configuring a timer like this (and to be honest, that's what I would do too), it may be wise to give it a status="disabled" property in device tree to ensure the kernel doesn't meddle with it. Also, you may need to enable and configure the timer after the kernel has booted (through /dev/mem) rather than before (e.g. in u-boot) since the kernel will probably disable the timer if it thinks the timer is not in active use (due to the "disable unneeded clocks" config option, or whatever it's called).

  • Hi Matthijs, Thanks for your reply,
    I've verified TCLR writing with flag checking TWPS register, and as I wrote every thing is fine.
    I think the problem is the device tree overlay,(I just changed the pin mux)- as all other am335x modules do work(and have a device tree overlay)
    I can't find a proper one.
  • Hmm, device trees can sometimes still be a bit mysterious (and device tree overlays even more so)...

    If you don't mind an ugly hack you can of course also do the pinmux from userspace... see my jbang project for an example on doing that. E.g. using the padconf() function as defined in src/hw-subarctic.cc you'd use one or more of:

    padconf(  36, Pad::out( 2 ) );  // R07 (ZCZ) / V10 (ZCE)
    padconf(  69, Pad::out( 3 ) );  // J16 (ZCZ) / K17 (ZCE)
    padconf(  98, Pad::out( 1 ) );  // C17 (ZCZ) / C18 (ZCE)
    padconf( 108, Pad::out( 2 ) );  // A15 (ZCZ) / C15 (ZCE)

    depending on where you want the timer4 output.

  • Hello again,
    I got the timer to work, since tcrr register is 32bit wide, it had to be narrowed using TLDR register.
    I am only getting top 12Mhz signal, though.