-
Notifications
You must be signed in to change notification settings - Fork 3
Expand file tree
/
Copy pathIR.c
More file actions
161 lines (114 loc) · 3.01 KB
/
IR.c
File metadata and controls
161 lines (114 loc) · 3.01 KB
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
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
#include "LPC1114.h"
#include "GPIO.h"
#include "SysTick.h"
#include "UART.h"
#define GPIO1_5 5
#define IR_STATE_ON 1
#define IR_STATE_OFF 2
volatile uint32_t IR_timer;
volatile uint32_t IR_code;
volatile uint32_t IR_state;
volatile uint32_t IR_bit_count;
void IR_Timer_callback(uint32_t state) {
if (IR_state == IR_STATE_ON) {
IR_timer++;
} else {
// IR pin Logical Low (Watch for operator precedence b/n & and ==)
if ((GPIO1DATA & (1 << GPIO1_5)) == 0) {
IR_timer++;
}
}
}
void main() {
// Initialize SysTick, GPIO and UART
GPIO_init();
SysTick_init();
UART_init();
// ------------- GPIO Interrupt Configuration ------------------
// GPIO1_ISENSE defaults to Edge Sensitive trigger
// GPIO1_IEDGES defaults to GPIO1_IEVENT control
// Configure both edges trigger
GPIO1_IEDGES = (1 << GPIO1_5);
// Enable Rising Edge trigger
//GPIO1_IEVENT = (1 << GPIO1_5);
// Enable GPIO Interrupt
GPIO1_IENABLE = (1 << GPIO1_5);
// Enable GPIO1 Interrupt in NVIC
NVIC_SETENA = (1 << NVIC_GPIO1_BIT);
// ------------- GPIO Interrupt Configuration ------------------
// Initilize IR state
IR_timer = 0;
IR_bit_count = 0;
IR_code = 0;
IR_state = IR_STATE_OFF;
// Create and setup IR timer
Timer_t IR_timer = { 1, 0, 0, 0, IR_Timer_callback };
SysTick_run(&IR_timer);
// Despatch timer callbacks if available; or just wait
while(1) {
if (Callback_counter > 0) {
(Timer_callbacks[--Callback_counter])(0);
}
}
}
void GPIO1_Handler(void) {
// GPIO1_IMASKSTAT can be used to identify which pin is causing the interrupt
// Clear GPIO Edge Trigger Intrrupt Signal
GPIO1_ICLR = (1 << GPIO1_5);
if (GPIO1DATA & (1 << GPIO1_5)) {
// Rising edge trigger
if (IR_state == IR_STATE_OFF) {
// Check for the first 9ms pulse train during OFF state (Watch the difference beween bitwise & and logical &&)
if ((IR_timer >= 35) && (IR_timer <= 38)) {
// Enter ON state
IR_state = IR_STATE_ON;
}
}
} else {
// Falling edge trigger
if (IR_state == IR_STATE_ON) {
// 2.25ms pulse width = IR Bit 1
if ((IR_timer >= 8) && (IR_timer <= 10)) {
IR_code++;
IR_bit_count++;
if (IR_bit_count < 32)
IR_code = (IR_code << 1);
}
// 1.12ms pulse width = IR Bit 0
if ((IR_timer >= 3) && (IR_timer <= 6)) {
IR_bit_count++;
if (IR_bit_count < 32)
IR_code = (IR_code << 1);
}
// 32 IR bits = Complete IR command
if (IR_bit_count == 32) {
// Payload
UART_write(&IR_code, 4);
if (IR_code == 0x00FDB04F) {
GPIO1DATA ^= (1 << PIO1_9);
}
// Exit to OFF state
IR_state = IR_STATE_OFF;
IR_code = 0;
IR_bit_count = 0;
}
}
// Reset timer on all falling edge triggers
IR_timer = 0;
}
}
/* IR Buttons/Commands
ON/OFF 0x00FD00FF
PLAY/PAUSE 0x00FDA05F
>> 0x00FD609F
<< 0x00FD20DF
Vol+ 0x00FD807F
VOL- 0x00FD906F
UP 0x00FD50AF
DOWN 0x00FD10EF
EQ 0x00FDB04F
0 0x00FD30CF
1 0x00FD08F7
2 0x00FD8877
3 0x00FD48B7
*/