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.

Timer one-shot with immediate clear and then set on time-out

Hello,

I am having trouble getting a timer to run in one-shot mode with the action mode configured to immediately clear the CCP pin and then set the pin on time-out of the timer.

Here is the code where I initialize the timer:

 

/**
 * Initializes Timers for one shot operation of the LDAC pulse
 *
 * \param enForcer - enables the LDAC_FORCER timer
 * \param enQuad - enables the LDAC_QUAD timer
 * \param pulseWidth - Number of clock cycles to pulse the LDAC signal low.
 *
 * \note Not available on the GTBE-TM4C123GXL
 **/
void DAC_initTimersLDAC(bool enForcer, bool enQuad, uint32_t pulseWidth) {
	// LDAC_FORCER Timer
	MAP_SysCtlPeripheralEnable(DAC_LDAC_GPIO_PERIPH);
	if(enForcer) {
		MAP_GPIOPinTypeTimer(DAC_LDAC_GPIO_BASE, DAC_LDAC_FORCER_PIN);
		MAP_GPIOPinConfigure(DAC_LDAC_FORCER_PIN_CONFIG);
		MAP_SysCtlPeripheralEnable(DAC_LDAC_FORCER_TIMER_PERIPH);
		MAP_TimerConfigure(DAC_LDAC_FORCER_TIMER_BASE, TIMER_CFG_SPLIT_PAIR | TIMER_CFG_B_ONE_SHOT | TIMER_CFG_B_ACT_CLRSETTO);
		MAP_TimerLoadSet(DAC_LDAC_FORCER_TIMER_BASE, DAC_LDAC_FORCER_TIMER, pulseWidth);
	}
	// LDAC_QUAD Timer
	if(enQuad) {
		MAP_GPIOPinTypeTimer(DAC_LDAC_GPIO_BASE, DAC_LDAC_QUAD_PIN);
		MAP_GPIOPinConfigure(DAC_LDAC_QUAD_PIN_CONFIG);
		MAP_SysCtlPeripheralEnable(DAC_LDAC_QUAD_TIMER_PERIPH);
		MAP_TimerConfigure(DAC_LDAC_QUAD_TIMER_BASE, TIMER_CFG_SPLIT_PAIR | TIMER_CFG_A_ONE_SHOT | TIMER_CFG_A_ACT_CLRSETTO);
		MAP_TimerLoadSet(DAC_LDAC_QUAD_TIMER_BASE, pulseWidth, TIMER_A);
	}
}

I then try and restart the timer within an EOT (end of transmission) interrupt generated by one of the SPI peripherals.  Here is the interrupt:

  /**
   * Interrupt handler for loading the DACs with the timer after updating them
   * \note Need to add the ISR to the NVIC table in the row labeled "SSIX Rx and Tx"
   **/
  void DAC_intHandlerSSItimer(void) {
	  //SSIIntClear(DAC_SSI_BASE, DAC_SSI_INT_TYPE)
	  HWREG(DAC_SSI_BASE + SSI_O_ICR) = DAC_SSI_INT_TYPE;
	  MAP_TimerLoadSet(DAC_LDAC_FORCER_TIMER_BASE, DAC_LDAC_FORCER_TIMER, 50);
	  //TimerEnable(DAC_LDAC_FORCER_TIMER_BASE, DAC_LDAC_FORCER_TIMER);
	  HWREG(DAC_LDAC_FORCER_TIMER_BASE + TIMER_O_CTL) |= DAC_LDAC_FORCER_TIMER & (TIMER_CTL_TAEN | TIMER_CTL_TBEN);
  }

Here are some of the defines used:

// ~LDAC_FORCER and ~LDAC_Quad
	#define DAC_LDAC_GPIO_PERIPH 			SYSCTL_PERIPH_GPIOM
	#define DAC_LDAC_GPIO_BASE 				GPIO_PORTM_BASE
	#define DAC_LDAC_FORCER_PIN 			GPIO_PIN_1
	#define DAC_LDAC_FORCER_PIN_CONFIG		GPIO_PM1_T2CCP1
	#define DAC_LDAC_FORCER_TIMER_PERIPH	SYSCTL_PERIPH_TIMER2
	#define DAC_LDAC_FORCER_TIMER_BASE		TIMER2_BASE
	#define DAC_LDAC_FORCER_TIMER			TIMER_B
	#define DAC_LDAC_QUAD_PIN 				GPIO_PIN_2
	#define DAC_LDAC_QUAD_PIN_CONFIG		GPIO_PM2_T3CCP0
	#define DAC_LDAC_QUAD_TIMER_PERIPH	SYSCTL_PERIPH_TIMER3
	#define DAC_LDAC_QUAD_TIMER_BASE		TIMER3_BASE
	#define DAC_LDAC_QUAD_TIMER			TIMER_A

The problem is that when I measure the pin that should be outputing a low pulse while the timer is running I don't see anything at all, the pin just remains high.  The CCP pin should be cleared when the timer starts and then set when the timer times out so that it is low while the timer is running.

I know the EOT interrupt is triggering for sure and the device supports the action modes as reported in the datasheet, so there must be some problem with the initialization that is called at the start of the main program or timer enabling code which is executed  in the SSI EOT interrupt.

My full code is attached:

3302.GTBE_mainTestDRDYpllCMSIS - Timer Problem.zip

Regards,

Curtis

  • Curtis Mayberry1 said:
    ...the pin that should be outputting a low pulse (while the timer is running) ... just remains high.

    Might this be normal/customary ARM MCU - Timer behavior?  We've noted such on ARM M0, M3, & M4 - from multiple ARM MCU vendors.  (i.e. this is no knock on this vendor)

    Past, lesser MCUs often output the timer signal to an external pin.  With many ARM MCUs - that's not the case.  With the M3s & M4s our group uses - it is usually necessary to force the timer into PWM mode - and only then does a Timer to GPIO (output) pin connection result.

    Recall that a timer function does not especially guarantee that the timer interval will be directed to the timer pin. (yes - this is contrary to many non-ARM users' past experience)  ARM apparently intended that the, "pin to timer connection" be primarily for external signals, "input to the MCU" - upon that timer pin.

    Your objection/disbelief (even protest) is expected - here then an extract from our  LX4F MCU Manual: "CCP output operates when the PLO and MRSU bits are set - and the GPTMTnMATCHR value is greater than the GPTMTnILR value."  My belief - those 2 boldened bits are set via the Timer's config into PWM mode, only.  (nothing prevents you from attempting to set those - of course you assume any/all risks in so doing...)  And kindly recall the adage - "Not to shoot {this} most humble messenger..."

    As a workaround - you may be able to have the timer, "time-out" trigger an interrupt - and w/in that interrupt's service - you may toggle a GPIO.

    I'm unclear as to the "action modes" you report and your exact device - but believe the info I've supplied is correct and the workaround points the way toward a solution...

  • Hey cb1,

    cb1_mobile said:
    I'm unclear as to the "action modes" you report and your exact device - but believe the info I've supplied is correct...

    The timer compare action modes enable a mode where the MCU should behave as I described previously.  According to the datasheet when you are in one-shot mode you should be able to set the TCACT bits of the GPTM Timer B Mode (GPTMTBMR) register to enable the mode.  The mode is described on pages 955 and 956 of the datasheet and the register bits are described on page 975.

    See the datasheet attached below.  I think these action timer compare action modes were introduced on the TM4C1294 devices.

    Right now I just skip the timer altogether and pulse the GPIO low in my SSI EOT interrupt using the code below.  However without the delay the pulse is too short (10-20ns) and with the delay the pulse is too long (300ns).  Maybe if there was a better way to make a short precise delay wiithout the timer that might work also.

      /**
       * Interrupt handler for loading the DACs after updating them
       * \note Need to add the ISR to the NVIC table in the row labeled "SSIX Rx and Tx"
       **/
      void DAC_intHandlerSSI(void) {
    	  //SSIIntClear(DAC_SSI_BASE, DAC_SSI_INT_TYPE)
    	  HWREG(DAC_SSI_BASE + SSI_O_ICR) = DAC_SSI_INT_TYPE;
    	  //MAP_GPIOPinWrite(GPIO_PORTE_BASE, GPIO_PIN_1, 0x00);
    	  HWREG(DAC_LDAC_GPIO_BASE + GPIO_O_DATA + (DAC_LDAC_FORCER_PIN <<2)) = 0x00; // Write low to GPIO PC7
    	  MAP_SysCtlDelay(1);
    	  //MAP_GPIOPinWrite(GPIO_PORTE_BASE, GPIO_PIN_1, 0x02);
    	  HWREG(DAC_LDAC_GPIO_BASE + GPIO_O_DATA + (DAC_LDAC_FORCER_PIN <<2)) = DAC_LDAC_FORCER_PIN; // Write high to GPIO PC7
      }

    Datasheet:

    5164.tm4c1294ncpdt.pdf

    - Curtis 

  • Monsieur Curtis,

    Please check Para 4 my post.  I just imported a key portion from the Timer section.  (was sure you'd protest - be in disbelief)

    Understand our tech group uses many ARM MCUs - many vendors - and I have no experience w/the device you describe.  I am alerting you - as best I'm able - to the facts as I know them - in the hope that this may save you time/effort and that the workaround may succeed if my info proves correct.  

    And please do note that nothing that you've yet provided suggests that any timer signal is output to the timer CCP pin! Might this be your hope - likely from past experience?  (I do not see that expectation delivered w/in your code listings - or any support documentation you've provided.)

    I've attempted to deal w/your expressed issue - "the lack of timer output from the CCP pin" - may we resolve that before moving to "next issue/request?" 

  • Curtis Mayberry1 said:
    Maybe if there was a better way to make a short precise delay wiithout the timer that might work also.

    My inventive (or sick) mind suggests use of some other timer!  ARM provides many.  Short, precise delays are the hallmark of the ARM timers - they are superb at such...  (the separate timer is in honor of KISS (avoids any unwanted/unexpected timer interaction) - first solve the problem - later - as/if needed - proceed by refinement...)

    And please do note that nothing that you've yet provided suggests that any timer signal is output to the timer CCP pin! Might this be your hope - likely from past experience?  

    (I do not see that expectation delivered w/in your code listings - or any support documentation you've provided.)

    I've attempted to deal w/your expressed issue - "the lack of timer output from the CCP pin" - may we resolve that before moving to "next issue/request?" 

  • Hi,

    @cb1-,

    Yes, the timer compare action is new, specific to TM4C129x - poster Curtis attempted to enable the action in this line:

    MAP_TimerConfigure(DAC_LDAC_FORCER_TIMER_BASE, TIMER_CFG_SPLIT_PAIR | TIMER_CFG_B_ONE_SHOT | TIMER_CFG_B_ACT_CLRSETTO);  // see bolded parameter

    @Curtis

    But looking into file driverlib/timer.c, seems to be conditionally compiled if the parameter CLASS_IS_TM4C129 is defined somewhere. As related in inc/hw_types.h, may be detected automatically by some other macros. So suggest to first #include inc/hw_types.h in your file header section. If not successful, define that parameter in Predefined Symbols tab of the compiler configuration.

    As for changing state, maybe the first try would be to toggle, to confirm the correct settings.

    Then try as you need - but seems the action to first preset the pin to a known state is tricky, as you can read this in user manual:

    The TCACT field can be changed while the GPTM is enabled to generate different combinations of actions. For example, during a periodic event, encodings TCACT = 0x6 or 0x7 can be used to force the initial state of the CCPn pin before the first interrupt


    Petrei

  • @Petrei-

    Thank you - as always great (needed) detail.  As stated - mine was a, "non-MCU specific" approach - which our small group has employed to "monitor" the Timer - as/if/when needed.  Suspect that it will work - if the attention to detail is proper.

    btw - I've been away from this vendor's M4s - drawn to 180MHz & other features - elsewhere.  Would you be so good as to "weigh in" re: my assessment of the establishment of a Timer to Pin Connection - under ARM - usually requiring that the Timer be forced into PWM mode?  (again - I'm targeting the plain vanilla, earlier ARM MCUs here - not the "one-off" version listed here...)  Thanks...

  • Hi

    @cb1-,

    If I understand correctly your question - under ARM, earlier (let's say ARM7TDMI if you mean that) the disorder is the same or bigger - some brands allow the output to the pin just to signal the timer event, others uses the output to the pin to generate pwm.

    LM3S - yes, as you said, timer forced to pwm is the single mode to output to the pin.

    TM4C129 - different - the compare mode does not operate when the PWM mode is active and is mutually exclusive to the PWM mode. The timer acts on corresponding CCPn pin when a timer match occurs. 

    Regards,

    Petrei

  • @Petrei,

    Good thanks - indeed we started w/ARM under ARM7TDMI. (as did so many)  Indeed - the "disorder" you report is famous.

    Thanks for your confirmation re: LM3S - however we note that, "Timer Output - only when PWM" continues under all LX4F and many (most) rebrand devices.  It is this new device which has just now changed the playing field...