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.

RM48L952ZWT: Setting up a timer

Other Parts Discussed in Thread: HALCOGEN

How do I set up a timer? Is there an example code somewhere? Also, is there a limit to the number of timers? I need 3 for this project, but I am curious too.

For instance, in Winforms .Net, all I would have to do is drag and drop a timer control to the form, set the interval in milliseconds, set up the timer event handler, basically double click on the event, and either programmatically, or more conveniently, set start, and off it goes. In the event, I would stop the timer and at the end of the handler event I would start the timer again.

The previous version of my project used a different CPU, an Intel 80386EX, which made you jump through hoops to get something simple. It would seem that possibly the High End Timer (N2HET) might be what I need, but reviewing the manual for N2HET seemed that that module did something else.

Anyways, how would I programmatically set up my 3 timers? The inputs I presume for all timers would be the interval and where the ISR.

Do I need to do any EOI notification or re-setup?

  • Sarah,
    I will suggest you use the RTI (Real time Interrupt) module for your timer function. Example can be found if you go to HalCoGen->Help->Help Topics->Examples->example_rtiBlinky.c. In this example it sets up a timer that will interrupt every 1000ms and toggle a LED light. The RTI module can support up to 4 compare units. You can use each compare to setup your timer period. Please also refer to the TRM for details.
  • Charles, The example is a bit confusing for setting up a timer, 2 in my case, that does NOT start using RTI1 Compare | Compare 0 Period. I believe that I am fine with the GUI part of the configuration, but am a bit unsure about the sys_main part of the coding.

    Before going on, I have a question regarding the example. Here is a screenshot of the example:

    Notice the example says "Map VIM Channel 2 to IRQ," however the screenshot shows VIM Channel 2 mapped to FIQ, not IRQ. Which one is it? (Please have the document team correct the bug.) Does this bug affect the settings that I made, see screenshot below?

    Here is my VIM Channel 0-31 configuration:

    Here is my RTI1 Compare configuration:

    Do I need to do anything else in the sys_main module (or anywhere else)?

    	// Initailize: VIM Table
    	vimInit();
    	vimChannelMap(9, 2, &gioHighLevelInterrupt);
    	vimChannelMap(2, 3, &rtiCompare0Interrupt);
    	vimChannelMap(64, 4, &sciHighLevelInterrupt); // COM1 RX: SCI Level 0, which makes it Interrupt Request 64
    	vimChannelMap(13, 5, &linHighLevelInterrupt); // COM2 RX: LIN/SCI Level 0, which makes it Interrupt Request 13
    	vimChannelMap(74, 6, &sciLowLevelInterrupt); // COM1 TX: SCI Level 1, which makes it Interrupt Request 74
    	vimChannelMap(27, 7, &linLowLevelInterrupt); //COM2 TX: LIN/SCI Level 1, which makes it Interrupt Request 27
    
    	// Initialize: RTI
    	//
    	// Initialize RTI driver.
    	rtiInit();
    
    	// Enable RTI Compare 0 interrupt notification.
    	rtiEnableNotification(rtiNOTIFICATION_COMPARE0);
    
    	// Enable interrupts
        //   - Clear I flag in CPS register
    	//   - Note: This is usually done by the OS or in an svc dispatcher
    	_enable_IRQ();
    
    	// Start RTI Counter Block 0.
    	rtiStartCounter(rtiCOUNTER_BLOCK0);

    My goal is to set up a 10ms timer on Counter Period 1 and a 100ms timer on Counter Period 2, as shown in the above screenshot.

    Am I correct that "Compare 0-3 Periods" are all part of Counter Block 0?

    Is the notification code correct?

    /* USER CODE BEGIN (8) */
    /* USER CODE END */
    #pragma WEAK(rtiNotification)
    void rtiNotification(uint32 notification)
    {
    /*  enter user code between the USER CODE BEGIN and USER CODE END. */
    /* USER CODE BEGIN (9) */
    	// Fire CCM 10ms timer event: System, Algorithm, and Application Stuff.
    	if (rtiNOTIFICATION_COMPARE1 == notification)
    		TimerIsrCombined();
    	else if (rtiNOTIFICATION_COMPARE2 == notification)
    		TimerIsrWatchdog();
    /* USER CODE END */
    }
    

  • HI Sarah,

    First of all the HalCoGen has a typo. In the HalCoGen setting it is choosing the FiQ level but the description says to map VIM Channel 2 to IRQ. So this is a mistake. I will feedback to the HalCoGen team.

    As far as your HalCoGen configuration, you are configuring three different timers with the first timer for 100ms, 2nd timer for 10ms and 3rd timer for 100ms. Is this the duration you want? If this is what you want for your application then it is fine. The question is why you want the same timer value for the first and the third timer at 100ms?

    Since you use three timers then you will have three different interrupts? I see that you map VIM request 2 to channel 3 as in vimChannelMap(2, 3, &rtiCompare0Interrupt); What about rtiCompare1Interrupt and rtiCompare2Interrupt? Where are you mapping these two to? You need to map them to somewhere else since you have already mapped COM1 RX and COM2 RX to channel 4 and 5.

    You have only enable interrupt for compare0. You need to do so for the other two timers as well like below.

    rtiEnableNotification(rtiNOTIFICATION_COMPARE0);
    rtiEnableNotification(rtiNOTIFICATION_COMPARE1);
    rtiEnableNotification(rtiNOTIFICATION_COMPARE2);
  • Hi Charles,

    Great catch! I set up the first RTI interrupt, merely because the interface specification called for it:

    1.7. Real Time Interrupt- Setup a real time interrupt every 100msec.

    1.7.2. Set the time period of the RTI interrupt by writing 500000 to RTICOMP0 at 0xFFFFC050. This will cause 500000 (decimal) prescale clocks (which is VCLK/2, set in the next section) to generate the RTI, when enabled.

    1.7.3. Set the count value to be added to the RTICOMP0 register when it hits the compare value in RTICOMP0 by writing 500000 to RTIUDCP0 at 0xFFFFC054.

    1.7.4. Set the prescale count by writing 1 to RTICPUC0 at 0xFFFFC018, which will cause the Upcount 0 prescale counter to divide VCLK by 2, to increment the RTIFRC0 counter. Thus VCLK is divided by 1000000. And VCLK is the 20MHz oscillator divided by 2, which means you get a RTI every 100 msec.

    1.7.5. Select RTICOMP0 as the register that RTIFRC0 (the free running counter) is compared to by writing 0 to RTICOMPCTRL at 0xFFFFC00C.

    1.7.6. Write 0 to RTITBCTRL at 0xFFFFC004, to select RTIUC0 to clock RTIFRC0 instead of the Network Timing Interface.

    1.7.7. Write 1 to RTIGCTRL at 0xFFFFC000, to start the RTI counter chain.

    1.7.8. Write 0x00010000 to RTISETINTENA at 0xFFFFC080, to enable the RTI interrupt.

    What the specification failed to do was answer the question why! To my knowledge, there are two timers: one for the watchdog (100ms) and the second to periodically read values from the ADC. There are GPIO line signals for the ACOK and BUSOK signals, but that is something else entirely. I deleted the 2nd timer, as and re-purposed the zeroth timer to be the watchdog timer. That changes the VIM table to:

    // Initailize: VIM Table
    vimInit();
    vimChannelMap(9, 2, &gioHighLevelInterrupt); // GPIOA Interrupts (BUSOK), see 1.3.2 (GIOA[0] BUSOK), 1.8.4.1 in interface specification, and GIO tab bit 0
    vimChannelMap(23, 3, &gioLowLevelInterrupt);  // GPIOA Interrupts (ACOK), see 1.3.3 (GIOA[1] ACOK), 1.8.4.2 in interface specification, and GIO tab bit 1
    vimChannelMap(2, 4, &rtiCompare0Interrupt); // Timer: Watchdog
    vimChannelMap(64, 5, &sciHighLevelInterrupt); // COM1 RX: SCI Level 0, which makes it Interrupt Request 64
    vimChannelMap(13, 6, &linHighLevelInterrupt); // COM2 RX: LIN/SCI Level 0, which makes it Interrupt Request 13
    vimChannelMap(74, 7, &sciLowLevelInterrupt); // COM1 TX: SCI Level 1, which makes it Interrupt Request 74
    vimChannelMap(27, 8, &linLowLevelInterrupt); // COM2 TX: LIN/SCI Level 1, which makes it Interrupt Request 27
    vimChannelMap(3, 9, &rtiCompare1Interrupt); // Timer: Combined

    Thanks again for the catch. I will have to ask the EE if he wanted the RTI to do something other than what I know to do. If so, I can add that logic to the watchdog timer, same interval.

    asdf