drivers/AT91/timer_AT91.c
author Robert Lehmann <robert.lehmann@sitec-systems.de>
Tue, 28 Jul 2015 16:36:55 +0200
changeset 793 72e9e1064432
parent 520 cc993e72b7e6
child 801 32d146b64a35
permissions -rw-r--r--
timers_unix: Fix termination problem of WaitReceiveTaskEnd

The function pthread_kill sends the Signal thread and to the own process.
If you use this construct than the application which calls uses the
canfestival api will terminate at the call of canClose. To avoid that
use pthread_cancel instead of pthread_kill. To use the pthread_cancel call
you need to set the cancel ability in the thread function. That means
you need to call pthread_setcancelstate and pthread_setcanceltype.
For the termination of the thread at any time it is important to set the
cancel type to PTHREAD_CANCEL_ASYNCHRONOUS.
520
peter
parents:
diff changeset
     1
/*
peter
parents:
diff changeset
     2
This file is part of CanFestival, a library implementing CanOpen Stack.
peter
parents:
diff changeset
     3
peter
parents:
diff changeset
     4
Copyright (C): Edouard TISSERANT and Francis DUPIN
peter
parents:
diff changeset
     5
AT91 Port: Peter CHRISTEN
peter
parents:
diff changeset
     6
peter
parents:
diff changeset
     7
See COPYING file for copyrights details.
peter
parents:
diff changeset
     8
peter
parents:
diff changeset
     9
This library is free software; you can redistribute it and/or
peter
parents:
diff changeset
    10
modify it under the terms of the GNU Lesser General Public
peter
parents:
diff changeset
    11
License as published by the Free Software Foundation; either
peter
parents:
diff changeset
    12
version 2.1 of the License, or (at your option) any later version.
peter
parents:
diff changeset
    13
peter
parents:
diff changeset
    14
This library is distributed in the hope that it will be useful,
peter
parents:
diff changeset
    15
but WITHOUT ANY WARRANTY; without even the implied warranty of
peter
parents:
diff changeset
    16
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
peter
parents:
diff changeset
    17
Lesser General Public License for more details.
peter
parents:
diff changeset
    18
peter
parents:
diff changeset
    19
You should have received a copy of the GNU Lesser General Public
peter
parents:
diff changeset
    20
License along with this library; if not, write to the Free Software
peter
parents:
diff changeset
    21
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
peter
parents:
diff changeset
    22
*/
peter
parents:
diff changeset
    23
peter
parents:
diff changeset
    24
// Includes for the Canfestival driver
peter
parents:
diff changeset
    25
#include "canfestival.h"
peter
parents:
diff changeset
    26
#include "timer.h"
peter
parents:
diff changeset
    27
peter
parents:
diff changeset
    28
// Define the timer registers
peter
parents:
diff changeset
    29
#define AT91C_BASE_TC	AT91C_BASE_TC2
peter
parents:
diff changeset
    30
#define AT91C_ID_TC	AT91C_ID_TC2
peter
parents:
diff changeset
    31
#define TimerAlarm      AT91C_BASE_TC2->TC_RC
peter
parents:
diff changeset
    32
#define TimerCounter    AT91C_BASE_TC2->TC_CV
peter
parents:
diff changeset
    33
peter
parents:
diff changeset
    34
#define TIMER_INTERRUPT_LEVEL		1
peter
parents:
diff changeset
    35
peter
parents:
diff changeset
    36
void timer_can_irq_handler(void);
peter
parents:
diff changeset
    37
peter
parents:
diff changeset
    38
peter
parents:
diff changeset
    39
/************************** Modul variables **********************************/
peter
parents:
diff changeset
    40
// Store the last timer value to calculate the elapsed time
peter
parents:
diff changeset
    41
static TIMEVAL last_time_set = TIMEVAL_MAX;
peter
parents:
diff changeset
    42
peter
parents:
diff changeset
    43
void initTimer(void)
peter
parents:
diff changeset
    44
/******************************************************************************
peter
parents:
diff changeset
    45
Initializes the timer, turn on the interrupt and put the interrupt time to zero
peter
parents:
diff changeset
    46
INPUT	void
peter
parents:
diff changeset
    47
OUTPUT	void
peter
parents:
diff changeset
    48
******************************************************************************/
peter
parents:
diff changeset
    49
{
peter
parents:
diff changeset
    50
  unsigned int dummy;
peter
parents:
diff changeset
    51
peter
parents:
diff changeset
    52
  // First, enable the clock of the TIMER
peter
parents:
diff changeset
    53
  AT91F_PMC_EnablePeriphClock (AT91C_BASE_PMC, 1 << AT91C_ID_TC);
peter
parents:
diff changeset
    54
  // Disable the clock and the interrupts
peter
parents:
diff changeset
    55
  AT91C_BASE_TC->TC_CCR = AT91C_TC_CLKDIS ;
peter
parents:
diff changeset
    56
  AT91C_BASE_TC->TC_IDR = 0xFFFFFFFF ;
peter
parents:
diff changeset
    57
  // Clear status bit
peter
parents:
diff changeset
    58
  dummy = AT91C_BASE_TC->TC_SR;
peter
parents:
diff changeset
    59
  // Suppress warning variable "dummy" was set but never used
peter
parents:
diff changeset
    60
  dummy = dummy;
peter
parents:
diff changeset
    61
peter
parents:
diff changeset
    62
  // Set the Mode of the Timer Counter (MCK / 128)
peter
parents:
diff changeset
    63
  AT91C_BASE_TC->TC_CMR = AT91C_TC_CLKS_TIMER_DIV4_CLOCK;
peter
parents:
diff changeset
    64
peter
parents:
diff changeset
    65
  // Enable the clock
peter
parents:
diff changeset
    66
  AT91C_BASE_TC->TC_CCR = AT91C_TC_CLKEN ;
peter
parents:
diff changeset
    67
peter
parents:
diff changeset
    68
  // Open Timer interrupt
peter
parents:
diff changeset
    69
  AT91F_AIC_ConfigureIt (AT91C_BASE_AIC, AT91C_ID_TC, TIMER_INTERRUPT_LEVEL,
peter
parents:
diff changeset
    70
			 AT91C_AIC_SRCTYPE_INT_POSITIVE_EDGE, timer_can_irq_handler);
peter
parents:
diff changeset
    71
peter
parents:
diff changeset
    72
  AT91C_BASE_TC->TC_IER = AT91C_TC_CPCS;  //  IRQ enable CPC
peter
parents:
diff changeset
    73
  AT91F_AIC_EnableIt (AT91C_BASE_AIC, AT91C_ID_TC2);
peter
parents:
diff changeset
    74
peter
parents:
diff changeset
    75
  // Start Timer
peter
parents:
diff changeset
    76
  AT91C_BASE_TC->TC_CCR = AT91C_TC_SWTRG ;
peter
parents:
diff changeset
    77
}
peter
parents:
diff changeset
    78
peter
parents:
diff changeset
    79
void setTimer(TIMEVAL value)
peter
parents:
diff changeset
    80
/******************************************************************************
peter
parents:
diff changeset
    81
Set the timer for the next alarm.
peter
parents:
diff changeset
    82
INPUT	value TIMEVAL (unsigned long)
peter
parents:
diff changeset
    83
OUTPUT	void
peter
parents:
diff changeset
    84
******************************************************************************/
peter
parents:
diff changeset
    85
{
peter
parents:
diff changeset
    86
  TimerAlarm += value;	// Add the desired time to timer interrupt time
peter
parents:
diff changeset
    87
}
peter
parents:
diff changeset
    88
peter
parents:
diff changeset
    89
TIMEVAL getElapsedTime(void)
peter
parents:
diff changeset
    90
/******************************************************************************
peter
parents:
diff changeset
    91
Return the elapsed time to tell the stack how much time is spent since last call.
peter
parents:
diff changeset
    92
INPUT	void
peter
parents:
diff changeset
    93
OUTPUT	value TIMEVAL (unsigned long) the elapsed time
peter
parents:
diff changeset
    94
******************************************************************************/
peter
parents:
diff changeset
    95
{
peter
parents:
diff changeset
    96
  unsigned int timer = TimerCounter;	// Copy the value of the running timer
peter
parents:
diff changeset
    97
  // Calculate the time difference
peter
parents:
diff changeset
    98
  return timer > last_time_set ? timer - last_time_set : last_time_set - timer;
peter
parents:
diff changeset
    99
}
peter
parents:
diff changeset
   100
peter
parents:
diff changeset
   101
peter
parents:
diff changeset
   102
//*----------------------------------------------------------------------------
peter
parents:
diff changeset
   103
//* Function Name       : timer_can_irq_handler
peter
parents:
diff changeset
   104
//* Object              : C handler interrupt function by the interrupts
peter
parents:
diff changeset
   105
//*                       assembling routine
peter
parents:
diff changeset
   106
//* Output Parameters   : calls TimeDispatch
peter
parents:
diff changeset
   107
//*----------------------------------------------------------------------------
peter
parents:
diff changeset
   108
void timer_can_irq_handler(void)
peter
parents:
diff changeset
   109
{
peter
parents:
diff changeset
   110
  AT91PS_TC TC_pt = AT91C_BASE_TC;
peter
parents:
diff changeset
   111
  unsigned int dummy;
peter
parents:
diff changeset
   112
  // AcknowAT91B_LEDge interrupt status
peter
parents:
diff changeset
   113
  dummy = TC_pt->TC_SR;
peter
parents:
diff changeset
   114
  // Suppress warning variable "dummy" was set but never used
peter
parents:
diff changeset
   115
  dummy = dummy;
peter
parents:
diff changeset
   116
  last_time_set = TimerCounter;
peter
parents:
diff changeset
   117
  TimeDispatch();	// Call the time handler of the stack to adapt the elapsed time
peter
parents:
diff changeset
   118
}
peter
parents:
diff changeset
   119