-
Notifications
You must be signed in to change notification settings - Fork 9
/
ir.c
137 lines (118 loc) · 3.79 KB
/
ir.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
130
131
132
133
134
135
136
137
#include "ir.h"
u16 pin;
GPIO_TypeDef *gpio;
ir_nec_state ir_nec_current_state;
u8 cnt = 0;
unsigned int data, prev_data;
u16 ir_nec_pulse_lengths[6];
bool ir_nec_repeat_last_command = false;
u8 global_device;
u8 global_command;
void ir_nec_init(u16 p, GPIO_TypeDef *g) {
pin = p;
gpio = g;
ir_nec_current_state = IR_NEC_NONE;
ir_nec_pulse_lengths[IR_NEC_NONE] = 0;
ir_nec_pulse_lengths[IR_NEC_FIRST_BURST] = 9000;
ir_nec_pulse_lengths[IR_NEC_SECOND_BURST] = 4500;
ir_nec_pulse_lengths[IR_NEC_1] = 560;
ir_nec_pulse_lengths[IR_NEC_NDEF] = 1;
ir_nec_pulse_lengths[IR_NEC_SECOND_BURST_REPEAT] = 2250;
}
void ir_print_data(unsigned int p_data) {
// static u8 dev_id;
// static u8 dev_id2;
static u8 cmd_id;
static u8 cmd_id2;
// dev_id = (p_data & 0xFF000000) >> 24;
// dev_id2 = (p_data & 0x00FF0000) >> 16;
cmd_id = (p_data & 0x0000FF00) >> 8;
cmd_id2 = (p_data & 0x000000FF);
if (cmd_id + cmd_id2 == 0xFF) {
// printf("%u %u\r\n", dev_id, cmd_id);
global_command = cmd_id;
EXTI_GenerateSWInterrupt(EXTI_Line1);
}
}
void ir_nec_reset_transmission() {
if (ir_nec_current_state != IR_NEC_NONE) {
ir_nec_current_state = IR_NEC_NONE;
if (ir_nec_repeat_last_command) {
ir_print_data(prev_data);
} else {
ir_print_data(data);
prev_data = data;
}
data = 0;
cnt = 0;
ir_nec_repeat_last_command = false;
}
}
bool ir_nec_check_tolerance(unsigned int received, ir_nec_state current_state) {
unsigned int expected = ir_nec_pulse_lengths[current_state];
if (current_state == IR_NEC_NONE ||
current_state == IR_NEC_NDEF) {
return true;
} else if (current_state == IR_NEC_SECOND_BURST) {
// We can receive long (4.5 ms) or short (2.25 ms) burst.
if (received < 3000) {
ir_nec_current_state = IR_NEC_SECOND_BURST_REPEAT;
// ^ nasty hack, but we are can determine type of burst after receiving
expected = ir_nec_pulse_lengths[IR_NEC_SECOND_BURST_REPEAT];
} else {
expected = ir_nec_pulse_lengths[IR_NEC_SECOND_BURST];
}
}
u32 min = expected - (TOLERANCE / 100.0) * expected;
u32 max = expected + (TOLERANCE / 100.0) * expected;
if ((received >= min) && (received <= max)) {
return true;
}
return false;
}
void ir_nec_state_machine(unsigned int time) {
// BitAction bit = 1 - GPIO_ReadInputDataBit(gpio, pin); // Invert received value
// GPIO_WriteBit(GPIOC, GPIO_Pin_8, bit);
if (!ir_nec_check_tolerance(time, ir_nec_current_state)) {
ir_nec_reset_transmission();
return;
}
switch (ir_nec_current_state) {
case IR_NEC_NONE:
ir_nec_current_state = IR_NEC_FIRST_BURST;
break;
case IR_NEC_FIRST_BURST:
ir_nec_current_state = IR_NEC_SECOND_BURST;
break;
case IR_NEC_SECOND_BURST:
ir_nec_current_state = IR_NEC_1;
break;
case IR_NEC_1:
ir_nec_current_state = IR_NEC_NDEF; // we can receive either 0 or 1
break;
case IR_NEC_NDEF:
ir_nec_current_state = IR_NEC_1;
if (time < 1000) {
data = data << 1 | 1;
} else {
data = data << 1 | 0;
}
// if (cnt++ == 32) { //all data received
//
// }
break;
case IR_NEC_SECOND_BURST_REPEAT:
// repeat last message
// ir_nec_repeat_last_command = true;
ir_nec_current_state = IR_NEC_1;
break;
default:
ir_nec_reset_transmission();
break;
}
}
u8 ir_nec_get_last_command() {
u8 command = global_command;
global_command = 0;
return command;
}