Subversion Repositories HomeAutomation

Rev

Details | Last modification | View Log | SVN | RSS feed

Rev Author Line No. Line
600 nattgris 1
#include "protocols.h"
2
 
3
int8_t parseProtocol(const uint16_t *buf, uint8_t len, Ir_Protocol_Data_t *proto) {
4
    /* Try all protocols in order. */
5
#if (IR_PROTOCOLS_USE_SIRC)
6
    if (parseSIRC(buf, len, proto)) return IR_OK;
7
#endif
8
#if (IR_PROTOCOLS_USE_RC5)
9
    if (parseRC5(buf, len, proto)) return IR_OK;
10
#endif
11
#if (IR_PROTOCOLS_USE_SHARP)
12
    if (parseSharp(buf, len, proto)) return IR_OK;
13
#endif
14
#if (IR_PROTOCOLS_USE_NEC)
15
    if (parseNEC(buf, len, proto)) return IR_OK;
16
#endif
17
#if (IR_PROTOCOLS_USE_SAMSUNG)
18
    if (parseSamsung(buf, len, proto)) return IR_OK;
19
#endif
20
    /* No protocol matched. */
21
    return IR_NOT_CORRECT_DATA;
22
}
23
 
24
int8_t parseHash(const uint16_t *buf, uint8_t len, Ir_Protocol_Data_t *proto) {
25
    //TODO: Transform the buffer in some clever way to a 32 bit word. */
26
    proto->protocol = IR_PROTO_HASH;
27
    proto->timeout = 0;
28
    proto->data = 0;
29
}
30
 
31
int8_t expandProtocol(uint16_t *buf, uint8_t len, const Ir_Protocol_Data_t *proto) {
32
    /* Call the expand function for the specified protocol. */
33
    switch (proto->protocol) {
34
    case IR_PROTO_SIRC:
35
        return expandSIRC(buf, len, proto);
36
    case IR_PROTO_RC5:
37
        return expandRC5(buf, len, proto);
38
    case IR_PROTO_SHARP:
39
        return expandSharp(buf, len, proto);
40
    case IR_PROTO_NEC:
41
        return expandNEC(buf, len, proto);
42
    case IR_PROTO_SAMSUNG:
43
        return expandSamsung(buf, len, proto);
44
    }
45
    /* Invalid protocol specified. */
46
    return IR_NOT_CORRECT_DATA;
47
}
48
 
49
#if (IR_PROTOCOLS_USE_SIRC)
50
/**
51
 * Test data on SIRC protocol, 12-bit version
52
 * http://www.sbprojects.com/knowledge/ir/sirc.htm
53
 *
54
 * @param address
55
 *      Pointer to store the address of the received data
56
 * @param command
57
 *      Pointer to store the command of the received data
58
 * @return
59
 *      IR_OK if data parsed successfully, one of several errormessages if not
60
 */
61
int8_t parseSIRC(const uint16_t *buf, uint8_t len, Ir_Protocol_Data_t *proto) {
62
    /* parse buf[], max is len */
63
 
64
    /* check if we have correct amount of data */
65
    if (len != 25) {
66
        return IR_NOT_CORRECT_DATA;
67
    }
68
 
69
    /* check startbit */
70
    if (buf[0] > IR_SIRC_ST_BIT + IR_SIRC_ST_BIT/IR_SIRC_TOL_DIV || buf[0] < IR_SIRC_ST_BIT - IR_SIRC_ST_BIT/IR_SIRC_TOL_DIV) {
71
        return IR_NOT_CORRECT_DATA;
72
    }
73
 
74
    uint16_t rawbits=0;
75
 
76
    for (uint8_t i = 1; i < len; i++) {
77
        if ((i&1) == 1) {       /* if odd, ir-pause */
78
            /* check length of pause between bits */
79
            if (buf[i] > IR_SIRC_LOW + IR_SIRC_LOW/IR_SIRC_TOL_DIV || buf[i] < IR_SIRC_LOW - IR_SIRC_LOW/IR_SIRC_TOL_DIV) {
80
                return IR_NOT_CORRECT_DATA;
81
            }
82
        } else {            /* if even, ir-bit */
83
            if (buf[i] > IR_SIRC_HIGH_ONE - IR_SIRC_HIGH_ONE/IR_SIRC_TOL_DIV && buf[i] < IR_SIRC_HIGH_ONE + IR_SIRC_HIGH_ONE/IR_SIRC_TOL_DIV) {
84
                /* write a one */
85
                rawbits |= 1<<((i-2)>>1);
86
            } else if (buf[i] > IR_SIRC_HIGH_ZERO - IR_SIRC_HIGH_ZERO/IR_SIRC_TOL_DIV && buf[i] < IR_SIRC_HIGH_ZERO + IR_SIRC_HIGH_ZERO/IR_SIRC_TOL_DIV) {
87
                /* do nothing, a zero is already in rawbits */
88
            } else {
89
                return IR_NOT_CORRECT_DATA;
90
            }
91
        }
92
    }
93
 
94
    proto->protocol = IR_PROTO_SIRC;
95
    proto->timeout = IR_SIRC_REPETITION;
96
    proto->data = rawbits; //TODO: Should some other mapping be used?
97
 
98
    return IR_OK;
99
}
100
 
101
int8_t expandSIRC(uint16_t *buf, uint8_t len, const Ir_Protocol_Data_t *proto) {
102
    //TODO: Implement this function.
103
    return IR_NOT_CORRECT_DATA;
104
}
105
#endif
106
 
107
#if (IR_PROTOCOLS_USE_RC5)
108
/**
109
 * Test data on RC5 protocol
110
 * http://www.sbprojects.com/knowledge/ir/rc5.htm
111
 *
112
 * @param address
113
 *      Pointer to store the address of the received data
114
 * @param command
115
 *      Pointer to store the command of the received data
116
 * @return
117
 *      IR_OK if data parsed successfully, one of several errormessages if not
118
 */
119
int8_t parseRC5(const uint16_t *buf, uint8_t len, Ir_Protocol_Data_t *proto) {
120
    uint8_t halfbitscnt = 1;
121
    uint16_t rawbits = 0;
122
 
123
    for (uint8_t i = 0; i<len; i++) {
124
        //halfbitscnt&1==1 in the middle of bits
125
        //i&1==0 positive flank
126
 
127
        if ((halfbitscnt&1)==1 && (i&1)==0) {       /* in the middle of bit AND a positve flank */
128
            rawbits |= (1<<(13-(halfbitscnt>>1)));
129
        }
130
 
131
        if (buf[i] > IR_RC5_HALF_BIT - IR_RC5_HALF_BIT/IR_RC5_TOL_DIV && buf[i] < IR_RC5_HALF_BIT + IR_RC5_HALF_BIT/IR_RC5_TOL_DIV) {
132
            halfbitscnt += 1;
133
        } else if (buf[i] > IR_RC5_BIT - IR_RC5_BIT/IR_RC5_TOL_DIV && buf[i] < IR_RC5_BIT + IR_RC5_BIT/IR_RC5_TOL_DIV) {
134
            halfbitscnt += 2;
135
        } else {
136
            return IR_NOT_CORRECT_DATA;
137
        }
138
 
139
    }
140
 
141
    //TODO: Fix this parser to use the proto struct instead.
142
    *command = ((uint8_t)rawbits&0x3f);
143
    *address = ((uint8_t)(rawbits>>6)&0x7f);   
144
 
145
    //support RC5-extended by putting the inversion of startbit 2 as the 7th commandbit
146
    *command |= (~(*address) & 0x40);
147
    *address &= 0x1f;       //remove togglebit and both startbits from address
148
 
149
    return IR_OK;
150
}
151
 
152
int8_t expandRC5(uint16_t *buf, uint8_t len, const Ir_Protocol_Data_t *proto) {
153
    //TODO: Implement this function.
154
    return IR_NOT_CORRECT_DATA;
155
}
156
#endif
157
 
158
#if (IR_PROTOCOLS_USE_SHARP)
159
/**
160
 * Test data on SHARP protocol
161
 * http://www.sbprojects.com/knowledge/ir/sharp.htm
162
 *
163
 * @param address
164
 *      Pointer to store the address of the received data
165
 * @param command
166
 *      Pointer to store the command of the received data
167
 * @return
168
 *      IR_OK if data parsed successfully, one of several errormessages if not
169
 */
170
int8_t parseSharp(const uint16_t *buf, uint8_t len, Ir_Protocol_Data_t *proto) {
171
    /* parse buf[], max is len */
172
 
173
    /* check if we have correct amount of data */
174
    if (len != 31) {
175
        return IR_NOT_CORRECT_DATA;
176
    }
177
 
178
    uint16_t rawbits=0;
179
 
180
    for (uint8_t i = 1; i < len; i++) {
181
        if ((i&1) == 1) {       /* if odd, ir-pause */
182
            /* check length of pause between bits */
183
            if (buf[i] > IR_SHARP_LOW_ONE - IR_SHARP_LOW_ONE/IR_SHARP_TOL_DIV && buf[i] < IR_SHARP_LOW_ONE + IR_SHARP_LOW_ONE/IR_SHARP_TOL_DIV) {
184
                /* write a one */
185
                rawbits |= 1<<((i-1)>>1);
186
            } else if (buf[i] > IR_SHARP_LOW_ZERO - IR_SHARP_LOW_ZERO/IR_SHARP_TOL_DIV && buf[i] < IR_SHARP_LOW_ZERO + IR_SHARP_LOW_ZERO/IR_SHARP_TOL_DIV) {
187
                /* do nothing, a zero is already in rawbits */
188
            } else {
189
                return IR_NOT_CORRECT_DATA;
190
            }
191
        } else {            /* if even, ir-bit */
192
            if (buf[i] > IR_SHARP_HIGH + IR_SHARP_HIGH/IR_SHARP_TOL_DIV || buf[i] < IR_SHARP_HIGH - IR_SHARP_HIGH/IR_SHARP_TOL_DIV) {
193
                return IR_NOT_CORRECT_DATA;
194
            }
195
        }
196
    }
197
 
198
    //TODO: Fix this parser to use the proto struct instead.
199
    *command = ((uint8_t)(rawbits>>5)&0xff);
200
    *address = ((uint8_t)rawbits&0x1f);
201
 
202
    return IR_OK;
203
}
204
 
205
int8_t expandSharp(uint16_t *buf, uint8_t len, const Ir_Protocol_Data_t *proto) {
206
    //TODO: Implement this function.
207
    return IR_NOT_CORRECT_DATA;
208
}
209
#endif
210
 
211
#if (IR_PROTOCOLS_USE_NEC)
212
/**
213
 * Test data on NEC protocol
214
 * http://www.sbprojects.com/knowledge/ir/nec.htm
215
 *
216
 * @param address
217
 *      Pointer to store the address of the received data
218
 * @param command
219
 *      Pointer to store the command of the received data
220
 * @return
221
 *      IR_OK if data parsed successfully, one of several errormessages if not
222
 */
223
int8_t parseNEC(const uint16_t *buf, uint8_t len, Ir_Protocol_Data_t *proto) {
224
    /* parse buf[], max is len */
225
 
226
    /* check if we have correct amount of data */
227
    if (len != 67) {
228
        return IR_NOT_CORRECT_DATA;
229
    }
230
 
231
    /* check startbit */
232
    if (buf[0] > IR_NEC_ST_BIT + IR_NEC_ST_BIT/IR_NEC_TOL_DIV || buf[0] < IR_NEC_ST_BIT - IR_NEC_ST_BIT/IR_NEC_TOL_DIV) {
233
        return IR_NOT_CORRECT_DATA;
234
    }
235
 
236
    /* check pause after startbit */
237
    if (buf[1] > IR_NEC_ST_PAUSE + IR_NEC_ST_PAUSE/IR_NEC_TOL_DIV || buf[1] < IR_NEC_ST_PAUSE - IR_NEC_ST_PAUSE/IR_NEC_TOL_DIV) {
238
        return IR_NOT_CORRECT_DATA;
239
    }
240
 
241
    //TODO: Fix this parser to use the proto struct instead. Do not write to the struct unless IR_OK is returned, use temp variables.
242
    *command = 0;
243
    *address = 0;
244
 
245
    for (uint8_t i = 3; i < len; i++) {
246
        if ((i&1) == 1) {       /* if odd, ir-pause */
247
            /* check length of pause between bits */
248
            if (buf[i] > IR_NEC_LOW_ONE - IR_NEC_LOW_ONE/IR_NEC_TOL_DIV && buf[i] < IR_NEC_LOW_ONE + IR_NEC_LOW_ONE/IR_NEC_TOL_DIV) {
249
                if (i>2 && i<18) {
250
                    /* write a one */
251
                    *address |= 1<<((i-3)>>1);
252
                }
253
                if (i>34 && i<50) {
254
                    /* write a one */
255
                    *command |= 1<<((i-35)>>1);
256
                }
257
            } else if (buf[i] > IR_NEC_LOW_ZERO - IR_NEC_LOW_ZERO/IR_NEC_TOL_DIV && buf[i] < IR_NEC_LOW_ZERO + IR_NEC_LOW_ZERO/IR_NEC_TOL_DIV) {
258
                /* do nothing, a zero is already in rawbits */
259
            } else {
260
                return IR_NOT_CORRECT_DATA;
261
            }
262
        } else {            /* if even, ir-bit */
263
            if (buf[i] > IR_NEC_HIGH + IR_NEC_HIGH/IR_NEC_TOL_DIV || buf[i] < IR_NEC_HIGH - IR_NEC_HIGH/IR_NEC_TOL_DIV) {
264
                return IR_NOT_CORRECT_DATA;
265
            }
266
        }
267
    }
268
 
269
    return IR_OK;
270
}
271
 
272
int8_t expandNEC(uint16_t *buf, uint8_t len, const Ir_Protocol_Data_t *proto) {
273
    //TODO: Implement this function.
274
    return IR_NOT_CORRECT_DATA;
275
}
276
#endif
277
 
278
#if (IR_PROTOCOLS_USE_SAMSUNG)
279
/**
280
 * Test data on Samsung protocol
281
 * Very much like NEC, different start bit/pause lengths etc.
282
 * http://www.sbprojects.com/knowledge/ir/nec.htm
283
 *
284
 * @param address
285
 *      Pointer to store the address of the received data
286
 * @param command
287
 *      Pointer to store the command of the received data
288
 * @return
289
 *      IR_OK if data parsed successfully, one of several errormessages if not
290
 */
291
int8_t parseSamsung(const uint16_t *buf, uint8_t len, Ir_Protocol_Data_t *proto) {
292
    /* parse buf[], max is len */
293
 
294
    /* check if we have correct amount of data */
295
    if (len != 67) {
296
        return IR_NOT_CORRECT_DATA;
297
    }
298
 
299
    /* check startbit */
300
    if (buf[0] > IR_SAMS_ST_BIT + IR_SAMS_ST_BIT/IR_SAMS_TOL_DIV || buf[0] < IR_SAMS_ST_BIT - IR_SAMS_ST_BIT/IR_SAMS_TOL_DIV) {
301
        return IR_NOT_CORRECT_DATA;
302
    }
303
 
304
    /* check pause after startbit */
305
    if (buf[1] > IR_SAMS_ST_PAUSE + IR_SAMS_ST_PAUSE/IR_SAMS_TOL_DIV || buf[1] < IR_SAMS_ST_PAUSE - IR_SAMS_ST_PAUSE/IR_SAMS_TOL_DIV) {
306
        return IR_NOT_CORRECT_DATA;
307
    }
308
 
309
    //TODO: Fix this parser to use the proto struct instead. Do not write to the struct unless IR_OK is returned, use temp variables.
310
    *command = 0;
311
    *address = 0;
312
 
313
    for (uint8_t i = 3; i < len; i++) {
314
        if ((i&1) == 1) {       /* if odd, ir-pause */
315
            /* check length of pause between bits */
316
            if (buf[i] > IR_SAMS_LOW_ONE - IR_SAMS_LOW_ONE/IR_SAMS_TOL_DIV && buf[i] < IR_SAMS_LOW_ONE + IR_SAMS_LOW_ONE/IR_SAMS_TOL_DIV) {
317
                if (i>2 && i<18) {
318
                    /* write a one */
319
                    *address |= 1<<((i-3)>>1);
320
                }
321
                if (i>34 && i<50) {
322
                    /* write a one */
323
                    *command |= 1<<((i-35)>>1);
324
                }
325
            } else if (buf[i] > IR_SAMS_LOW_ZERO - IR_SAMS_LOW_ZERO/IR_SAMS_TOL_DIV && buf[i] < IR_SAMS_LOW_ZERO + IR_SAMS_LOW_ZERO/IR_SAMS_TOL_DIV) {
326
                /* do nothing, a zero is already in rawbits */
327
            } else {
328
                return IR_NOT_CORRECT_DATA;
329
            }
330
        } else {            /* if even, ir-bit */
331
            if (buf[i] > IR_SAMS_HIGH + IR_SAMS_HIGH/IR_SAMS_TOL_DIV || buf[i] < IR_SAMS_HIGH - IR_SAMS_HIGH/IR_SAMS_TOL_DIV) {
332
                return IR_NOT_CORRECT_DATA;
333
            }
334
        }
335
    }
336
 
337
    return IR_OK;
338
}
339
 
340
int8_t expandSamsung(uint16_t *buf, uint8_t len, const Ir_Protocol_Data_t *proto) {
341
    //TODO: Implement this function.
342
    return IR_NOT_CORRECT_DATA;
343
}
344
#endif
345