-1
\$\begingroup\$

I'm studying timers for use in scheduling and embedded systems but I don't understand the detail, does the time count upwards or downwards? Is the timer like a hardware timer like the ones we learnt how to build when we took digital design?

The info about timers in book says

Basics: Timers Microcontrollers almost always include some number of peripheral devices called timers. A programmable interval timer (PIT), the most common type, simply counts down from some value to zero. The initial value is set by writing to a memory-mapped register, and when the value hits zero, the PIT raises an interrupt request. By writing to a memorymapped control register, a timer might be set up to trigger repeatedly without having to be reset by the software. Such repeated triggers will be more precisely periodic than what you would get if the ISR restarts the timer each time it gets invoked. This is because the time between when the count reaches zero in the timer hardware and the time when the counter gets restarted by the ISR is difficult to control and variable. For example, if the timer reaches zero at a time when interrupts happen to be disabled, then there will be a delay before the ISR gets invoked. It cannot be invoked before interrupts are re-enabled.

The instructions for my FPGA (Altera DE2) says

enter image description here

All device registers in the Timer have 32 bits (4 bytes) and must be read with an ldwio instruction (and written with a stwio instruction). However, no more than 16 bits (2 bytes) are connected. So the 32-bit period must be split into two 16-bit halves.

To initialize the timer, first write the 2 low bytes of the period to periodl, and then write the 2 high bytes to periodh. Finally, write once to the control register, setting the Start bit, (if appropriate) the Continuous-Mode bit, and (if appropriate) the Interrupt-on-Time-Out (ITO) bit.

Note: the timer counts down in one clock cycle, and sets the Time-Out flag in the next cycle if the counter reached zero. For example, if you want a 1000-cycle timeout, set the period value to 999.

Timer device-register summary

Status, 0x920 - read status bits, write any value to clear Time-Out bit. Control, 0x924 - write to start and/or control the timer. All bits are important, every time you write. PeriodL, 0x928 - write low bits of period here. Writing may stop the timer. PeriodH, 0x92c - write high bits of period here. Writing may stop the timer. SnapL, 0x930 - read low bits of latest snapshot, write to take a snapshot. SnapH, 0x934 - read high bits of latest snapshot. Bit by bit, explained

Time Out (TO) - bit 0 at address 0x920 - set to one by the Timer when the counter reaches zero. To reset the Time Out bit to zero, the program must write to address 0x920. Whatever value is written is ignored. The write transaction causes the Timer to reset the Time Out bit. Run - bit 1 at address 0x920 - indicates whether the Timer is running or not. This bit is set to one by the Timer when counting starts and reset to zero by the Timer when counting is finished. Continuous Mode - bit 1 at address 0x924 - this bit can be set and reset by the programmer. If this bit is set to one, the Timer will restart itself immediately after counting reaches zero. The Time Out bit will be set to one each time the counter reaches zero. The Run bit will always be 1. Start - bit 2 at address 0x924. When a value, where bit 2 is equal to "1", is written to address 0x924, the Timer starts counting. Writing values where bit 2 is equal to "0" has no effect. Stop - bit 3 at address 0x924. When a value, where bit 3 is equal to "1", is written to address 0x924, the Timer stops counting immediately. Writing values where bit 3 is equal to "0" has no effect. Snapshot - to read the current counter value, write any value to address 0x930 (SnapL). The counter value at the time of the write transaction will be copied from the counter to a Snapshot register inside the timer. The Snapshot register can then be read at addresses 0x930 (lowermost 16 bits at this address equals lower 16 bits of counter snapshot value) and 0x934 (lowermost 16 bits at this address equals upper 16 bits of counter snapshot value).

Enabling periodic timer interrupts

Setup an interrupt handler for the interrupt-requests from device number 10 (timer_1). How to do this depends on your software configuration. Initialize the periodl and periodh device-registers of the timer. Set the Start, Continuous-Mode, and Interrupt-on-TimeOut bits in the control device-register. These bits have indices 2, 1 and 0, respectively. A bit-mask with these three bits set is: 0x0007. Set (to a logic "1") the bit with index 10 in the processor's ienable register (ctl3). A mask with this bit set is: 0x0400. Set (to a logic "1") the processor's PIE bit (Processor Interrupt Enable) - bit 0 in the status register (ctl0). To acknowledge a timer interrupt, write any value to address 0x920.

I used the timer for scheduling with assembly and C code, and I got it to work so we don't need to write the program, I just need to understand the basic concept whether the timer is counting up to a spec value or counting down to zero. AFAIK the timer is used in the scheduling so if I write an RTOS or an OS I must use the timer the ae threadswitches.

Can you tell me more about it?

\$\endgroup\$
4
\$\begingroup\$

Microcontrollers have many different styles of timers. Some only count up, some only count down, some can be programmed to do either or even alternate counting up and down, some are automatically reset to zero each time they reach a programmable limit, some automatically reload a start value each time they reach zero, etc. All different sorts of behaviors.

My personal preferred type is an up counter which simply counts continuously and wraps around without regard for what anything else in the system is doing, and includes one or more "compare" interrupts which are triggered when the counter reaches a programmable value. I like that style of counter because--when sensibly implemented--it eliminates many of the uncertainties that can arise with some other styles. For example, if an interrupt has occurred at count #5,291 and one wants another interrupt to occur 300 counts after that, one can set the compare register for 5,591, and if the count hasn't passed that value yet, the second interrupt will occur precisely 300 counts after the first, even if the counter has advanced between the time the interrupt has occurred and the time one sets the compare register. If one instead uses a counter which requires one to program in the number of counts before the next interrupt, having a count pulse arrive just before programming such a counter may cause the resulting interrupt to arrive a cycle later than expected.

Note that if a system has an asynchronous interrupt input, one may design such an up-counter to operate fully asynchronously from the rest of the system without needing any double synchronizers that operate on the low clock speed except, perhaps, for one on a "master enable" or "reset" control. Unfortunately, many systems add over-complicated logic to their timer peripherals which end up making it difficult to simply keep a timebase which runs at a uniform speed independent of what anything else in the system is doing.

\$\endgroup\$
2
\$\begingroup\$

A programmable interval timer (PIT), the most common type, simply counts down from some value to zero.


Note: the timer counts down in one clock cycle, and sets the Time-Out flag in the next cycle if the counter reached zero.


If this bit is set to one, the Timer will restart itself immediately after counting reaches zero.


Sounds like they count down.

\$\endgroup\$
  • \$\begingroup\$ That's good to know since I know how to synthesis an upwardscounting timer but now a downwardscounting. \$\endgroup\$ – Niklas Rosencrantz Jul 13 '13 at 0:14
  • 1
    \$\begingroup\$ Not always, it depends on the architecture. \$\endgroup\$ – Matt Young Jul 13 '13 at 1:11

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.