2025-02-15 11:05:28 -05:00

301 lines
7.8 KiB
C

/*******************************************************************************
* *
* Copyright 2010 Rheinmetall Canada Inc. *
* *
* No part of this document may be reproduced, stored in *
* a retrieval system, or transmitted, in any form or by any means, *
* electronic, mechanical, photocopying, recording, or otherwise, *
* without the prior written permission of Rheinmetall Canada Inc. *
* *
*******************************************************************************/
#include "timer.h"
#include "define.h"
#include <string.h>
//#include <plib.h>
//#include "./FatFS/diskio.h"
//unsigned int MillisecCounter[TIMER_MAX_ID];
//unsigned int SecondCounter;
//int CalcPeriod;
stTimer astTimer[TIMER_MAX_ID];
//-------------------------------------------------------
void TimerInit(void)
{
#ifdef GP_TIMER_USE_TIMER_1
T1CON = 0;
T1CONbits.TCKPS = 0b01; //1:8 prescaler
TMR1 = 0;
PR1 = 10000; //77.824MHz clock with 1:8 prescaler = timer period of 102.8ns. 1ms period --> 9728 * 102.8ns = 1ms
IPC1bits.T1IP = 2; //timer interrupt priority = 2;
IPC1bits.T1IS = 3; //timer interrupt sub-priority = 2;
IFS0bits.T1IF = 0;
IEC0bits.T1IE = 1; //start timer
T1CONbits.ON = 1;
#endif
#ifdef GP_TIMER_USE_TIMER_2
T2CON = 0;
T2CONbits.TCKPS = 0b011; //1:8 prescaler
TMR2 = 0;
PR2 = 10000; //77.824MHz clock with 1:8 prescaler = timer period of 102.8ns. 1ms period --> 9728 * 102.8ns = 1ms
IPC2bits.T2IP = 2; //timer interrupt priority = 2;
IPC2bits.T2IS = 3; //timer interrupt sub-priority = 2;
IFS0bits.T2IF = 0;
IEC0bits.T2IE = 1; //start timer
T2CONbits.ON = 1;
#endif
memset(&astTimer[0], 0, sizeof(astTimer));
}
//-------------------------------------------------------
/*unsigned int GetActualTimerMilliSec(void)
{
return MillisecCounter;
}*/
//-------------------------------------------------------
/*unsigned int GetActualTimerSec(void)
{
return SecondCounter;
}*/
//-------------------------------------------------------
int IsMilliSecTimerExpired(eTimerID p_eTimerID)
{
int CalcPeriod = 0;
if ((astTimer+p_eTimerID)->bRunning)
{
CalcPeriod = (astTimer+p_eTimerID)->uiMillisecCounter - (astTimer+p_eTimerID)->uiStart;
//if(CalcPeriod > 0 && CalcPeriod >= (astTimer+p_eTimerID)->uiPeriodMillisec)
if(CalcPeriod >= (astTimer+p_eTimerID)->uiPeriodMillisec)
{
//TimerReset(p_eTimerID);
(astTimer+p_eTimerID)->uiMillisecCounter = 0;
return 1;
}
else if(CalcPeriod < 0)
{
if((1000 + CalcPeriod) >= (astTimer+p_eTimerID)->uiPeriodMillisec)
{
//TimerReset(p_eTimerID);
(astTimer+p_eTimerID)->uiMillisecCounter = 0;
return 1;
}
}
}
return 0;
}
//-------------------------------------------------------
int IsSecTimerExpired(eTimerID p_eTimerID)
{
int iCalcPeriod = 0;
if ((astTimer+p_eTimerID)->bRunning)
{
iCalcPeriod = (astTimer+p_eTimerID)->uiSecondCounter - (astTimer+p_eTimerID)->uiStart;
//if(iCalcPeriod > 0 && iCalcPeriod >= (astTimer+p_eTimerID)->uiPeriodSecond)
if(iCalcPeriod >= (astTimer+p_eTimerID)->uiPeriodSecond)
{
//TimerReset(p_eTimerID);
(astTimer+p_eTimerID)->uiSecondCounter = 0;
return 1;
}
else if(iCalcPeriod < 0)
{
if(((unsigned)0xFFFFFFFF + iCalcPeriod) >= (astTimer+p_eTimerID)->uiPeriodSecond)
{
//TimerReset(p_eTimerID);
(astTimer+p_eTimerID)->uiSecondCounter = 0;
return 1;
}
}
}
return 0;
}
//-------------------------------------------------------
int IsTimerExpired(eTimerID p_eTimerID)
{
int iCalcPeriod = 0;
if ((astTimer+p_eTimerID)->bRunning)
{
/*if (IsSecTimerExpired(p_eTimerID) && IsMilliSecTimerExpired(p_eTimerID))
return 1;*/
iCalcPeriod = (astTimer+p_eTimerID)->uiSecondCounter - (astTimer+p_eTimerID)->uiStart;
if(iCalcPeriod >= (astTimer+p_eTimerID)->uiPeriodSecond)
{
iCalcPeriod = (astTimer+p_eTimerID)->uiMillisecCounter - (astTimer+p_eTimerID)->uiStart;
if(iCalcPeriod >= (astTimer+p_eTimerID)->uiPeriodMillisec)
{
(astTimer+p_eTimerID)->uiSecondCounter = 0;
(astTimer+p_eTimerID)->uiMillisecCounter = 0;
return 1;
}
else if(iCalcPeriod < 0)
{
if((1000 + iCalcPeriod) >= (astTimer+p_eTimerID)->uiPeriodMillisec)
{
(astTimer+p_eTimerID)->uiSecondCounter = 0;
(astTimer+p_eTimerID)->uiMillisecCounter = 0;
return 1;
}
}
}
else if(iCalcPeriod < 0)
{
if(((unsigned)0xFFFFFFFF + iCalcPeriod) >= (astTimer+p_eTimerID)->uiPeriodSecond)
{
iCalcPeriod = (astTimer+p_eTimerID)->uiMillisecCounter - (astTimer+p_eTimerID)->uiStart;
if(iCalcPeriod >= (astTimer+p_eTimerID)->uiPeriodMillisec)
{
(astTimer+p_eTimerID)->uiSecondCounter = 0;
(astTimer+p_eTimerID)->uiMillisecCounter = 0;
return 1;
}
else if(iCalcPeriod < 0)
{
if((1000 + iCalcPeriod) >= (astTimer+p_eTimerID)->uiPeriodMillisec)
{
(astTimer+p_eTimerID)->uiSecondCounter = 0;
(astTimer+p_eTimerID)->uiMillisecCounter = 0;
return 1;
}
}
}
}
}
return 0;
}
//-------------------------------------------------------
void TimerStart(eTimerID p_eTimerID, unsigned int p_uiPeriod)
{
(astTimer+p_eTimerID)->bRunning = true;
if (p_uiPeriod >= 1000)
{
(astTimer+p_eTimerID)->uiPeriodSecond = p_uiPeriod / 1000;
(astTimer+p_eTimerID)->uiPeriodMillisec = p_uiPeriod % 1000;
}
else
{
(astTimer+p_eTimerID)->uiPeriodSecond = 0;
(astTimer+p_eTimerID)->uiPeriodMillisec = p_uiPeriod;
}
TimerReset(p_eTimerID);
}
void TimerStartSeconds(eTimerID p_eTimerID, unsigned int p_uiPeriod)
{
(astTimer+p_eTimerID)->bRunning = true;
(astTimer+p_eTimerID)->uiPeriodSecond = p_uiPeriod;
(astTimer+p_eTimerID)->uiPeriodMillisec = 0;
TimerReset(p_eTimerID);
}
//-------------------------------------------------------
void TimerReset(eTimerID p_eTimerID)
{
(astTimer+p_eTimerID)->uiStart = 0;
(astTimer+p_eTimerID)->uiMillisecCounter = 0;
(astTimer+p_eTimerID)->uiSecondCounter = 0;
}
//-------------------------------------------------------
bool IsTimerRunning(eTimerID p_eTimerID)
{
return (astTimer+p_eTimerID)->bRunning;
}
//-------------------------------------------------------
void TimerStop(eTimerID p_eTimerID)
{
(astTimer+p_eTimerID)->bRunning = false;
}
//-------------------------------------------------------
void Sleep(unsigned int timeout)
{
TimerStart(SLEEP_FCN_TIMER,timeout);
while(!IsTimerExpired(SLEEP_FCN_TIMER))
{
Nop();
}
TimerStop(SLEEP_FCN_TIMER);
}
#ifdef GP_TIMER_USE_TIMER_1
void __ISR(_TIMER_1_VECTOR, ipl2) Timer1MilliSecInterrupt(void)
{
unsigned int i;
stTimer* pstPtr = &astTimer[0];
// disk_timerproc();
// Update all timers
for (i=0; i<TIMER_MAX_ID; i++)
{
// update timer only if timer is running
if (pstPtr->bRunning)
{
if(pstPtr->uiMillisecCounter++ == 1000)
{
pstPtr->uiMillisecCounter = 0;
pstPtr->uiSecondCounter++;
}
}
pstPtr++;
}
IFS0bits.T1IF = 0; //Clear interrupt flag
}
#endif
#ifdef GP_TIMER_USE_TIMER_2
void __ISR(_TIMER_2_VECTOR, ipl2) Timer2MilliSecInterrupt(void) {
unsigned int i;
stTimer* pstPtr = &astTimer[0];
//disk_timerproc();
// Update all timers
for (i = 0; i < TIMER_MAX_ID; i++) {
// update timer only if timer is running
if (pstPtr->bRunning) {
if (pstPtr->uiMillisecCounter++ == 1000) {
pstPtr->uiMillisecCounter = 0;
pstPtr->uiSecondCounter++;
}
}
pstPtr++;
}
IFS0bits.T2IF = 0; //Clear interrupt flag
}
#endif
//EOF