etisserant@375: /* etisserant@375: This file is part of CanFestival, a library implementing CanOpen Stack. etisserant@375: etisserant@375: Copyright (C): Edouard TISSERANT and Francis DUPIN etisserant@375: AVR Port: Andreas GLAUSER and Peter CHRISTEN etisserant@375: etisserant@375: See COPYING file for copyrights details. etisserant@375: etisserant@375: This library is free software; you can redistribute it and/or etisserant@375: modify it under the terms of the GNU Lesser General Public etisserant@375: License as published by the Free Software Foundation; either etisserant@375: version 2.1 of the License, or (at your option) any later version. etisserant@375: etisserant@375: This library is distributed in the hope that it will be useful, etisserant@375: but WITHOUT ANY WARRANTY; without even the implied warranty of etisserant@375: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU etisserant@375: Lesser General Public License for more details. etisserant@375: etisserant@375: You should have received a copy of the GNU Lesser General Public etisserant@375: License along with this library; if not, write to the Free Software etisserant@375: Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA etisserant@375: */ etisserant@375: etisserant@375: // AVR implementation of the CANopen timer driver, uses Timer 3 (16 bit) etisserant@375: etisserant@375: // Includes for the Canfestival driver etisserant@375: #include "canfestival.h" Edouard@801: #include "timers.h" etisserant@375: etisserant@375: // Define the timer registers etisserant@375: #define TimerAlarm OCR3B etisserant@375: #define TimerCounter TCNT3 etisserant@375: etisserant@375: /************************** Modul variables **********************************/ etisserant@375: // Store the last timer value to calculate the elapsed time etisserant@375: static TIMEVAL last_time_set = TIMEVAL_MAX; etisserant@375: etisserant@375: void initTimer(void) etisserant@375: /****************************************************************************** etisserant@375: Initializes the timer, turn on the interrupt and put the interrupt time to zero etisserant@375: INPUT void etisserant@375: OUTPUT void etisserant@375: ******************************************************************************/ etisserant@375: { etisserant@375: TimerAlarm = 0; // Set it back to the zero etisserant@375: // Set timer 3 for CANopen operation tick 8us max, time is 524ms etisserant@375: TCCR3B = 1 << CS31 | 1 << CS30; // Timer 3 normal, mit CK/64 etisserant@375: TIMSK3 = 1 << OCIE3B; // Enable the interrupt etisserant@375: } etisserant@375: etisserant@375: void setTimer(TIMEVAL value) etisserant@375: /****************************************************************************** etisserant@375: Set the timer for the next alarm. etisserant@375: INPUT value TIMEVAL (unsigned long) etisserant@375: OUTPUT void etisserant@375: ******************************************************************************/ etisserant@375: { etisserant@375: TimerAlarm += (int)value; // Add the desired time to timer interrupt time etisserant@375: } etisserant@375: etisserant@375: TIMEVAL getElapsedTime(void) etisserant@375: /****************************************************************************** etisserant@375: Return the elapsed time to tell the Stack how much time is spent since last call. etisserant@375: INPUT void etisserant@375: OUTPUT value TIMEVAL (unsigned long) the elapsed time etisserant@375: ******************************************************************************/ etisserant@375: { etisserant@375: unsigned int timer = TimerCounter; // Copy the value of the running timer etisserant@375: if (timer > last_time_set) // In case the timer value is higher than the last time. etisserant@375: return (timer - last_time_set); // Calculate the time difference etisserant@375: else if (timer < last_time_set) etisserant@375: return (last_time_set - timer); // Calculate the time difference etisserant@375: else etisserant@375: return TIMEVAL_MAX; etisserant@375: } etisserant@375: etisserant@375: #ifdef __IAR_SYSTEMS_ICC__ etisserant@375: #pragma type_attribute = __interrupt etisserant@375: #pragma vector=TIMER3_COMPB_vect etisserant@375: void TIMER3_COMPB_interrupt(void) etisserant@375: #else // GCC etisserant@375: ISR(TIMER3_COMPB_vect) etisserant@375: #endif // GCC etisserant@375: /****************************************************************************** etisserant@375: Interruptserviceroutine Timer 3 Compare B for the CAN timer etisserant@375: ******************************************************************************/ etisserant@375: { etisserant@375: last_time_set = TimerCounter; etisserant@375: TimeDispatch(); // Call the time handler of the stack to adapt the elapsed time etisserant@375: } etisserant@375: etisserant@375: etisserant@375: