/******************************************************************************* * * * 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 //#include //#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; ibRunning) { 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