Andrew Boyson / clock

Dependents:   oldheating gps motorhome heating

timer.c

Committer:
andrewboyson
Date:
2018-11-30
Revision:
34:aeb58975e61a
Parent:
33:b9e3c06e7dab

File content as of revision 34:aeb58975e61a:

#include <stdint.h>
#include <stdbool.h>

#include "timer.h"
#include "tick.h"

#define TCR  (*((volatile unsigned *) 0x40004004))
#define TC   (*((volatile unsigned *) 0x40004008))
#define PR   (*((volatile unsigned *) 0x4000400C))
#define MCR  (*((volatile unsigned *) 0x40004014))
#define CTCR (*((volatile unsigned *) 0x40004070))

uint32_t TimerNowCount()
{
    return TC;
}
uint32_t TimerIntervalCount(uint32_t* pLastCount)
{
    uint32_t thisCount = TC;
    uint32_t period = thisCount - *pLastCount;    
    *pLastCount = thisCount;
    return period;
}
uint32_t TimerSinceCount(uint32_t startCount)
{
    return TC - startCount; 
}
uint32_t TimerSinceMs(uint32_t startCount)
{
    uint32_t count = TC - startCount;
    return count / TIMER_COUNT_PER_MS;
}

bool TimerIntervalHasElapsed(uint32_t* pBaseCount, uint32_t intervalCount)
{
    if (TC - *pBaseCount > intervalCount) //All unsigned wrap around arithmetic
    {
        *pBaseCount += intervalCount;
        return true;
    }
    return false;
}

int32_t TimerMultiplyFractionalPart(int32_t value, uint32_t timerCountSinceStart, uint32_t interval)
{
    int64_t fraction;
    
    fraction = timerCountSinceStart;
    fraction <<= 32;
    fraction /= interval;
              
    return (value * fraction) >> 32;
}

void TimerInit()
{    
    TCR     =     2; // 21.6.2 Timer Control Register - Reset TC and PC.
    CTCR    =     0; // 21.6.3 Count Control Register - Timer mode
    PR      =     0; // 21.6.5 Prescale register      - Don't prescale 96MHz clock (divide by PR+1).
    MCR     =     0; // 21.6.8 Match Control Register - no interrupt or reset
    TCR     =     1; // 21.6.2 Timer Control Register - Enable TC and PC
}