Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependents: oldheating gps motorhome heating
timer.c@31:f6ff7fdb9c67, 2018-11-29 (annotated)
- Committer:
- andrewboyson
- Date:
- Thu Nov 29 16:51:19 2018 +0000
- Revision:
- 31:f6ff7fdb9c67
- Parent:
- 30:212ca42b8779
- Child:
- 33:b9e3c06e7dab
Changed time.c to tm.c
Who changed what in which revision?
| User | Revision | Line number | New contents of line |
|---|---|---|---|
| andrewboyson | 24:6c9833e2a049 | 1 | #include <stdint.h> |
| andrewboyson | 26:0421132e6eaf | 2 | #include <stdbool.h> |
| andrewboyson | 24:6c9833e2a049 | 3 | |
| andrewboyson | 25:81014a201736 | 4 | #include "timer.h" |
| andrewboyson | 24:6c9833e2a049 | 5 | |
| andrewboyson | 30:212ca42b8779 | 6 | #define TCR (*((volatile unsigned *) 0x40004004)) |
| andrewboyson | 30:212ca42b8779 | 7 | #define TC (*((volatile unsigned *) 0x40004008)) |
| andrewboyson | 30:212ca42b8779 | 8 | #define PR (*((volatile unsigned *) 0x4000400C)) |
| andrewboyson | 30:212ca42b8779 | 9 | #define MCR (*((volatile unsigned *) 0x40004014)) |
| andrewboyson | 30:212ca42b8779 | 10 | #define CTCR (*((volatile unsigned *) 0x40004070)) |
| andrewboyson | 30:212ca42b8779 | 11 | |
| andrewboyson | 26:0421132e6eaf | 12 | uint32_t TimerNowCount() |
| andrewboyson | 26:0421132e6eaf | 13 | { |
| andrewboyson | 30:212ca42b8779 | 14 | return TC; |
| andrewboyson | 24:6c9833e2a049 | 15 | } |
| andrewboyson | 26:0421132e6eaf | 16 | uint32_t TimerIntervalCount(uint32_t* pLastCount) |
| andrewboyson | 24:6c9833e2a049 | 17 | { |
| andrewboyson | 30:212ca42b8779 | 18 | uint32_t thisCount = TC; |
| andrewboyson | 24:6c9833e2a049 | 19 | uint32_t period = thisCount - *pLastCount; |
| andrewboyson | 24:6c9833e2a049 | 20 | *pLastCount = thisCount; |
| andrewboyson | 24:6c9833e2a049 | 21 | return period; |
| andrewboyson | 24:6c9833e2a049 | 22 | } |
| andrewboyson | 24:6c9833e2a049 | 23 | uint32_t TimerSinceCount(uint32_t startCount) |
| andrewboyson | 24:6c9833e2a049 | 24 | { |
| andrewboyson | 30:212ca42b8779 | 25 | return TC - startCount; |
| andrewboyson | 24:6c9833e2a049 | 26 | } |
| andrewboyson | 24:6c9833e2a049 | 27 | uint32_t TimerSinceMs(uint32_t startCount) |
| andrewboyson | 24:6c9833e2a049 | 28 | { |
| andrewboyson | 30:212ca42b8779 | 29 | uint32_t count = TC - startCount; |
| andrewboyson | 25:81014a201736 | 30 | return count / TIMER_COUNT_PER_MS; |
| andrewboyson | 24:6c9833e2a049 | 31 | } |
| andrewboyson | 26:0421132e6eaf | 32 | |
| andrewboyson | 26:0421132e6eaf | 33 | static uint32_t secondsBaseCount = 0; |
| andrewboyson | 26:0421132e6eaf | 34 | |
| andrewboyson | 26:0421132e6eaf | 35 | uint32_t TimerCountSinceLastSecond() |
| andrewboyson | 26:0421132e6eaf | 36 | { |
| andrewboyson | 30:212ca42b8779 | 37 | return TC - secondsBaseCount; |
| andrewboyson | 26:0421132e6eaf | 38 | } |
| andrewboyson | 26:0421132e6eaf | 39 | int32_t TimerMultiplyFractionalPart(int32_t value, uint32_t timerCountSinceLastSecond) |
| andrewboyson | 26:0421132e6eaf | 40 | { |
| andrewboyson | 26:0421132e6eaf | 41 | int64_t fraction; |
| andrewboyson | 26:0421132e6eaf | 42 | |
| andrewboyson | 26:0421132e6eaf | 43 | fraction = timerCountSinceLastSecond; |
| andrewboyson | 26:0421132e6eaf | 44 | fraction <<= 32; |
| andrewboyson | 26:0421132e6eaf | 45 | fraction /= TIMER_COUNT_PER_SECOND; |
| andrewboyson | 26:0421132e6eaf | 46 | |
| andrewboyson | 26:0421132e6eaf | 47 | return (value * fraction) >> 32; |
| andrewboyson | 26:0421132e6eaf | 48 | } |
| andrewboyson | 26:0421132e6eaf | 49 | |
| andrewboyson | 31:f6ff7fdb9c67 | 50 | bool TimerHadSecond = false; |
| andrewboyson | 31:f6ff7fdb9c67 | 51 | |
| andrewboyson | 31:f6ff7fdb9c67 | 52 | //Counts from zero to 2^32 and wraps around after: |
| andrewboyson | 31:f6ff7fdb9c67 | 53 | // 13.7 years if 10 per second - scan time must be less than 100mS |
| andrewboyson | 31:f6ff7fdb9c67 | 54 | // 1.37 years if 100 per second - scan time must be less than 10mS |
| andrewboyson | 31:f6ff7fdb9c67 | 55 | uint32_t TimerTicks = 0; |
| andrewboyson | 26:0421132e6eaf | 56 | |
| andrewboyson | 26:0421132e6eaf | 57 | void TimerMain() |
| andrewboyson | 26:0421132e6eaf | 58 | { |
| andrewboyson | 31:f6ff7fdb9c67 | 59 | TimerHadSecond = TimerCountSinceLastSecond() > TIMER_COUNT_PER_SECOND; |
| andrewboyson | 31:f6ff7fdb9c67 | 60 | if (TimerHadSecond) secondsBaseCount += TIMER_COUNT_PER_SECOND; |
| andrewboyson | 31:f6ff7fdb9c67 | 61 | |
| andrewboyson | 31:f6ff7fdb9c67 | 62 | static uint32_t tickBaseCount = 0; |
| andrewboyson | 26:0421132e6eaf | 63 | |
| andrewboyson | 31:f6ff7fdb9c67 | 64 | if (TC - tickBaseCount > TIMER_COUNT_PER_SECOND / TIMER_TICKS_PER_SECOND) |
| andrewboyson | 31:f6ff7fdb9c67 | 65 | { |
| andrewboyson | 31:f6ff7fdb9c67 | 66 | TimerTicks++; |
| andrewboyson | 31:f6ff7fdb9c67 | 67 | tickBaseCount += TIMER_COUNT_PER_SECOND / TIMER_TICKS_PER_SECOND; |
| andrewboyson | 31:f6ff7fdb9c67 | 68 | } |
| andrewboyson | 26:0421132e6eaf | 69 | } |
| andrewboyson | 26:0421132e6eaf | 70 | void TimerInit() |
| andrewboyson | 26:0421132e6eaf | 71 | { |
| andrewboyson | 30:212ca42b8779 | 72 | TCR = 2; // 21.6.2 Timer Control Register - Reset TC and PC. |
| andrewboyson | 30:212ca42b8779 | 73 | CTCR = 0; // 21.6.3 Count Control Register - Timer mode |
| andrewboyson | 30:212ca42b8779 | 74 | PR = 0; // 21.6.5 Prescale register - Don't prescale 96MHz clock (divide by PR+1). |
| andrewboyson | 30:212ca42b8779 | 75 | MCR = 0; // 21.6.8 Match Control Register - no interrupt or reset |
| andrewboyson | 30:212ca42b8779 | 76 | TCR = 1; // 21.6.2 Timer Control Register - Enable TC and PC |
| andrewboyson | 26:0421132e6eaf | 77 | } |