-
Notifications
You must be signed in to change notification settings - Fork 0
/
icu.c
129 lines (111 loc) · 3.7 KB
/
icu.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
/******************************************************************************
*
* Module: ICU
*
* File Name: icu.c
*
* Description: Source file for the AVR ICU driver
*
* Author: Mohamed Tarek
*
*******************************************************************************/
#include "icu.h"
#include "common_macros.h" /* To use the macros like SET_BIT */
#include <avr/io.h> /* To use ICU/Timer1 Registers */
#include <avr/interrupt.h> /* For ICU ISR */
/*******************************************************************************
* Global Variables *
*******************************************************************************/
/* Global variables to hold the address of the call back function in the application */
static volatile void (*g_callBackPtr)(void) = NULL_PTR;
/*******************************************************************************
* Interrupt Service Routines *
*******************************************************************************/
ISR(TIMER1_CAPT_vect)
{
if(g_callBackPtr != NULL_PTR)
{
/* Call the Call Back function in the application after the edge is detected */
(*g_callBackPtr)(); /* another method to call the function using pointer to function g_callBackPtr(); */
}
}
/*******************************************************************************
* Functions Definitions *
*******************************************************************************/
/*
* Description : Function to initialize the ICU driver
* 1. Set the required clock.
* 2. Set the required edge detection.
* 3. Enable the Input Capture Interrupt.
* 4. Initialize Timer1 Registers
*/
void ICU_init(const ICU_ConfigType * Config_Ptr)
{
/* Configure ICP1/PD6 as i/p pin */
DDRD &= ~(1<<PD6);
/* Timer1 always operates in Normal Mode */
TCCR1A = (1<<FOC1A) | (1<<FOC1B);
/*
* insert the required clock value in the first three bits (CS10, CS11 and CS12)
* of TCCR1B Register
*/
TCCR1B = (TCCR1B & 0xF8) | (Config_Ptr->clock);
/*
* insert the required edge type in ICES1 bit in TCCR1B Register
*/
TCCR1B = (TCCR1B & 0xBF) | ((Config_Ptr->edge)<<6);
/* Initial Value for Timer1 */
TCNT1 = 0;
/* Initial Value for the input capture register */
ICR1 = 0;
/* Enable the Input Capture interrupt to generate an interrupt when edge is detected on ICP1/PD6 pin */
TIMSK |= (1<<TICIE1);
}
/*
* Description: Function to set the Call Back function address.
*/
void ICU_setCallBack(void(*a_ptr)(void))
{
/* Save the address of the Call back function in a global variable */
g_callBackPtr = a_ptr;
}
/*
* Description: Function to set the required edge detection.
*/
void ICU_setEdgeDetectionType(const ICU_EdgeType a_edgeType)
{
/*
* insert the required edge type in ICES1 bit in TCCR1B Register
*/
TCCR1B = (TCCR1B & 0xBF) | (a_edgeType<<6);
}
/*
* Description: Function to get the Timer1 Value when the input is captured
* The value stored at Input Capture Register ICR1
*/
uint16 ICU_getInputCaptureValue(void)
{
return ICR1;
}
/*
* Description: Function to clear the Timer1 Value to start count from ZERO
*/
void ICU_clearTimerValue(void)
{
TCNT1 = 0;
}
/*
* Description: Function to disable the Timer1 to stop the ICU Driver
*/
void ICU_deInit(void)
{
/* Clear All Timer1/ICU Registers */
TCCR1A = 0;
TCCR1B = 0;
TCNT1 = 0;
ICR1 = 0;
/* Disable the Input Capture interrupt */
TIMSK &= ~(1<<TICIE1);
/* Reset the global pointer value */
g_callBackPtr = NULL_PTR;
}