Subversion Repositories HomeAutomation

Rev

Rev 2260 | Details | Compare with Previous | Last modification | View Log | SVN | RSS feed

Rev Author Line No. Line
610 arune 1
/**
2
 * IR receiver and transmitter protocols.
3
 *
4
 * @date    2006-12-10
5
 *
1320 arune 6
 * @author  Anders Runeson, Andreas Fritiofson, Martin Nordin
610 arune 7
 *  
8
 */
9
 
608 arune 10
#include "protocols.h"
922 zeed 11
#include <bios.h>
2259 linlun 12
#include <drivers/mcu/gpio.h>
610 arune 13
 
2244 linlun 14
#include <drivers/can/moduleid.h>
1874 arune 15
 
1875 arune 16
//#include <drivers/mcu/gpio.h>
1874 arune 17
 
18
 
19
 
2199 arune 20
int8_t parseProtocol(const uint16_t *buf, uint8_t len, uint8_t index, Ir_Protocol_Data_t *proto) {
2236 linlun 21
    uint8_t res;
610 arune 22
    proto->protocol=IR_PROTO_UNKNOWN;
23
    proto->data=0;
1875 arune 24
    proto->timeout=1;
608 arune 25
    /* Try all protocols in order. */
26
#if (IR_PROTOCOLS_USE_SIRC)
610 arune 27
    if (parseSIRC(buf, len, proto)==IR_OK) return IR_OK;
608 arune 28
#endif
29
#if (IR_PROTOCOLS_USE_RC5)
610 arune 30
    if (parseRC5(buf, len, proto)==IR_OK) return IR_OK;
608 arune 31
#endif
32
#if (IR_PROTOCOLS_USE_SHARP)
610 arune 33
    if (parseSharp(buf, len, proto)==IR_OK) return IR_OK;
608 arune 34
#endif
35
#if (IR_PROTOCOLS_USE_NEC)
610 arune 36
    if (parseNEC(buf, len, proto)==IR_OK) return IR_OK;
608 arune 37
#endif
38
#if (IR_PROTOCOLS_USE_SAMSUNG)
610 arune 39
    if (parseSamsung(buf, len, proto)==IR_OK) return IR_OK;
608 arune 40
#endif
732 noddan 41
#if (IR_PROTOCOLS_USE_MARANTZ)
42
    if (parseMarantz(buf, len, proto)==IR_OK) return IR_OK;
43
#endif
1320 arune 44
#if (IR_PROTOCOLS_USE_PANASONIC)
45
    if (parsePanasonic(buf, len, proto)==IR_OK) return IR_OK;
46
#endif
1563 arune 47
#if (IR_PROTOCOLS_USE_SKY)
48
    if (parseSky(buf, len, proto)==IR_OK) return IR_OK;
49
#endif
2244 linlun 50
#if (IR_PROTOCOLS_USE_IROBOT)
51
    if (parseiRobot(buf, len, proto)==IR_OK) return IR_OK;
52
#endif
2199 arune 53
 
54
 
55
/* RF protocols needs index parameter */
1588 linlun 56
#if (IR_PROTOCOLS_USE_NEXA2)
2199 arune 57
    if (parseNexa2(buf, len, index, proto)==IR_OK) return IR_OK;
1588 linlun 58
#endif
1906 arune 59
#if (IR_PROTOCOLS_USE_NEXA1)
2199 arune 60
    if (parseNexa1(buf, len, index, proto)==IR_OK) return IR_OK;
1906 arune 61
#endif
2200 arune 62
#if (IR_PROTOCOLS_USE_VIKING)
63
    if (parseViking(buf, len, index, proto)==IR_OK) return IR_OK;
64
#endif
2297 arune 65
#if (IR_PROTOCOLS_USE_VIKING_T3)
66
    if (parseVikingT3(buf, len, index, proto)==IR_OK) return IR_OK;
67
#endif
2233 linlun 68
#if (IR_PROTOCOLS_USE_VIKING_STEAK)
2236 linlun 69
    res = parseVikingSteak(buf, len, index, proto);
70
    if (res!=IR_NOT_CORRECT_DATA) return res;
2233 linlun 71
#endif
2239 linlun 72
#if (IR_PROTOCOLS_USE_RUBICSON)
73
    res = parseRubicson(buf, len, index, proto);
74
    if (res!=IR_NOT_CORRECT_DATA) return res;
75
#endif
2254 linlun 76
#if (IR_PROTOCOLS_USE_OREGON)
2259 linlun 77
 
2254 linlun 78
    res = parseOregon(buf, len, index, proto);
2259 linlun 79
    gpio_clr_pin(EXP_K);
80
    gpio_clr_pin(EXP_L);
81
    gpio_clr_pin(EXP_M);
82
    gpio_clr_pin(EXP_N);
2254 linlun 83
    if (res!=IR_NOT_CORRECT_DATA) return res;
84
#endif      
2239 linlun 85
 
608 arune 86
    /* No protocol matched. */
610 arune 87
    proto->protocol = IR_PROTO_UNKNOWN;
608 arune 88
    return IR_NOT_CORRECT_DATA;
89
}
90
 
91
int8_t parseHash(const uint16_t *buf, uint8_t len, Ir_Protocol_Data_t *proto) {
92
    //TODO: Transform the buffer in some clever way to a 32 bit word. */
93
    proto->protocol = IR_PROTO_HASH;
610 arune 94
    proto->timeout = 200;
608 arune 95
    proto->data = 0;
96
 
97
    return 0;
98
}
99
 
100
int8_t expandProtocol(uint16_t *buf, uint8_t *len, Ir_Protocol_Data_t *proto) {
101
    /* Call the expand function for the specified protocol. */
102
    switch (proto->protocol) {
2244 linlun 103
    case CAN_MODULE_ENUM_PHYSICAL_IR_PROTOCOL_SIRC:
608 arune 104
        return expandSIRC(buf, len, proto);
2244 linlun 105
    case CAN_MODULE_ENUM_PHYSICAL_IR_PROTOCOL_RC5:
608 arune 106
        return expandRC5(buf, len, proto);
2244 linlun 107
    case CAN_MODULE_ENUM_PHYSICAL_IR_PROTOCOL_SHARP:
608 arune 108
        return expandSharp(buf, len, proto);
2244 linlun 109
    case CAN_MODULE_ENUM_PHYSICAL_IR_PROTOCOL_NEC:
608 arune 110
        return expandNEC(buf, len, proto);
2244 linlun 111
    case CAN_MODULE_ENUM_PHYSICAL_IR_PROTOCOL_SAMSUNG:
608 arune 112
        return expandSamsung(buf, len, proto);
2244 linlun 113
    case CAN_MODULE_ENUM_PHYSICAL_IR_PROTOCOL_MARANTZ:
732 noddan 114
        return expandMarantz(buf, len, proto);
2244 linlun 115
    case CAN_MODULE_ENUM_PHYSICAL_IR_PROTOCOL_PANASONIC:
1320 arune 116
        return expandPanasonic(buf, len, proto);
2244 linlun 117
    case CAN_MODULE_ENUM_PHYSICAL_IR_PROTOCOL_SKY:
1563 arune 118
        return expandSky(buf, len, proto);
2244 linlun 119
    case CAN_MODULE_ENUM_PHYSICAL_IR_PROTOCOL_IROBOT:
120
        return expandiRobot(buf, len, proto);
121
    case CAN_MODULE_ENUM_PHYSICAL_IR_PROTOCOL_NEXA2:
1886 arune 122
        return expandNexa2(buf, len, proto);
2244 linlun 123
    case CAN_MODULE_ENUM_PHYSICAL_IR_PROTOCOL_NEXA:
1906 arune 124
        return expandNexa1(buf, len, proto);
608 arune 125
    }
126
    /* Invalid protocol specified. */
127
    return IR_NOT_CORRECT_DATA;
128
}
129
 
130
#if (IR_PROTOCOLS_USE_SIRC)
131
/**
132
 * Test data on SIRC protocol, 12-bit version
133
 * http://www.sbprojects.com/knowledge/ir/sirc.htm
1715 bjorne 134
 * http://picprojects.org.uk/projects/sirc/sonysirc.pdf
608 arune 135
 *
610 arune 136
 * @param buf
137
 *      Pointer to buffer to where to data to parse is stored
138
 * @param len
139
 *      Length of the data
140
 * @param proto
141
 *      Pointer to protocol information
608 arune 142
 * @return
143
 *      IR_OK if data parsed successfully, one of several errormessages if not
144
 */
145
int8_t parseSIRC(const uint16_t *buf, uint8_t len, Ir_Protocol_Data_t *proto) {
146
    /* parse buf[], max is len */
147
 
1715 bjorne 148
    /* check if we have correct amount of data.
149
           supporting two versions of SIRC:
150
           12 bit = 25, 15 bit = 31
151
           there is also a 20 bit protocol, but we don't support it
152
         */
153
    if (len != 25 && len != 31) {
608 arune 154
        return IR_NOT_CORRECT_DATA;
155
    }
156
 
157
    /* check startbit */
158
    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) {
159
        return IR_NOT_CORRECT_DATA;
160
    }
161
 
162
    uint16_t rawbits=0;
163
 
164
    for (uint8_t i = 1; i < len; i++) {
165
        if ((i&1) == 1) {       /* if odd, ir-pause */
166
            /* check length of pause between bits */
167
            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) {
168
                return IR_NOT_CORRECT_DATA;
169
            }
170
        } else {            /* if even, ir-bit */
171
            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) {
172
                /* write a one */
173
                rawbits |= 1<<((i-2)>>1);
174
            } 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) {
175
                /* do nothing, a zero is already in rawbits */
176
            } else {
177
                return IR_NOT_CORRECT_DATA;
178
            }
179
        }
180
    }
181
 
2244 linlun 182
    proto->protocol = CAN_MODULE_ENUM_PHYSICAL_IR_PROTOCOL_SIRC;
608 arune 183
    proto->timeout = IR_SIRC_TIMEOUT;
610 arune 184
    proto->data = rawbits;
608 arune 185
 
186
    return IR_OK;
187
}
188
#endif
189
 
610 arune 190
/**
191
 * Expand data from SIRC protocol
192
 * http://www.sbprojects.com/knowledge/ir/sirc.htm
193
 *
194
 * @param buf
195
 *      Pointer to buffer to store the expanded data
196
 * @param len
197
 *      Pointer to length of the data
198
 * @param proto
199
 *      Pointer to protocol information
200
 * @return
201
 *      IR_OK if data expanded successfully, one of several errormessages if not
202
 */
608 arune 203
int8_t expandSIRC(uint16_t *buf, uint8_t *len, Ir_Protocol_Data_t *proto) {
734 noddan 204
    buf[0] = IR_SIRC_ST_BIT;
1715 bjorne 205
    buf[1] = IR_SIRC_LOW; //start pulse finished
206
 
207
        /* Assume 12 bit protocol */
208
        *len = 25;
209
        /* If data to big, use 15 bit protocol */
210
        if (proto->data > (1<<11)) { // cannot be represented by 12 bits
211
          *len = 31;
212
        }
213
        for (uint8_t i = 0; i < *len-2; i++) {
214
          if ((i&1) == 1) {     /* if odd, ir-pause */
215
            buf[i+2] = IR_SIRC_LOW;
216
          } else {          /* if even, ir-bit */
217
            if ((proto->data>>(i>>1))&1) {
218
              buf[i+2] = IR_SIRC_HIGH_ONE;
219
            } else {
220
              buf[i+2] = IR_SIRC_HIGH_ZERO;
221
            }
222
          }
223
        }  
224
 
225
    proto->modfreq=IR_SIRC_F_MOD;
226
    proto->timeout=IR_SIRC_TIMEOUT;
227
    proto->repeats=IR_SIRC_REPS;
228
 
229
    return IR_OK;
608 arune 230
}
231
 
610 arune 232
 
608 arune 233
#if (IR_PROTOCOLS_USE_RC5)
234
/**
235
 * Test data on RC5 protocol
236
 * http://www.sbprojects.com/knowledge/ir/rc5.htm
237
 *
610 arune 238
 * @param buf
239
 *      Pointer to buffer to where to data to parse is stored
240
 * @param len
241
 *      Length of the data
242
 * @param proto
243
 *      Pointer to protocol information
608 arune 244
 * @return
245
 *      IR_OK if data parsed successfully, one of several errormessages if not
246
 */
247
int8_t parseRC5(const uint16_t *buf, uint8_t len, Ir_Protocol_Data_t *proto) {
248
    uint8_t halfbitscnt = 1;
249
    uint16_t rawbits = 0;
250
 
251
    for (uint8_t i = 0; i<len; i++) {
252
        //halfbitscnt&1==1 in the middle of bits
253
        //i&1==0 positive flank
254
 
255
        if ((halfbitscnt&1)==1 && (i&1)==0) {       /* in the middle of bit AND a positve flank */
256
            rawbits |= (1<<(13-(halfbitscnt>>1)));
257
        }
258
 
259
        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) {
260
            halfbitscnt += 1;
261
        } 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) {
262
            halfbitscnt += 2;
263
        } else {
264
            return IR_NOT_CORRECT_DATA;
265
        }
266
 
267
    }
268
 
2244 linlun 269
    proto->protocol=CAN_MODULE_ENUM_PHYSICAL_IR_PROTOCOL_RC5;
608 arune 270
    proto->timeout=IR_RC5_TIMEOUT;
271
    //support RC5-extended keeping second startbit 
272
    //remove togglebit
732 noddan 273
    proto->data = rawbits&0x37ff; //This seems to be wrong? Does not invert second start bit and keeps first start bit
274
    //proto->data = (rawbits&0x07ff) | ((~rawbits)&0x0100);
608 arune 275
 
276
 
277
    return IR_OK;
278
}
279
#endif
280
 
610 arune 281
/**
922 zeed 282
 * Used by the expandRC5 to ensure that we toggle the signal with each button press.
283
 */
284
int8_t rc5_toggle=0;
285
 
286
/**
610 arune 287
 * Expand data from RC5 protocol
288
 * http://www.sbprojects.com/knowledge/ir/rc5.htm
289
 *
922 zeed 290
 * One is defined as low then high
291
 * Zero is defined as high then low
292
 *
610 arune 293
 * @param buf
294
 *      Pointer to buffer to store the expanded data
295
 * @param len
296
 *      Pointer to length of the data
297
 * @param proto
298
 *      Pointer to protocol information
299
 * @return
300
 *      IR_OK if data expanded successfully, one of several errormessages if not
301
 */
608 arune 302
int8_t expandRC5(uint16_t *buf, uint8_t *len, Ir_Protocol_Data_t *proto) {
922 zeed 303
 
304
    //This is the raw message that we should create the IR times for
305
    //Lets copy the data locally to ensure that no interups will modify the vector.
306
    uint16_t rawMessage=proto->data & 0x3fff;
307
 
727 noddan 308
    uint8_t previousBit;
922 zeed 309
    /* Set up startbit */
310
    //Bit = 0
311
    //We start with a low signal since the diode 
312
    //isn't active before we send anything,
313
    buf[0] = IR_RC5_HALF_BIT;//first start bit
727 noddan 314
 
922 zeed 315
    // Bit = 1
727 noddan 316
    buf[1] = IR_RC5_HALF_BIT;
922 zeed 317
    buf[2] = IR_RC5_HALF_BIT;//second start bit
727 noddan 318
 
922 zeed 319
    if (rc5_toggle==0){
320
        buf[3] = IR_RC5_HALF_BIT;
321
        buf[4] = IR_RC5_HALF_BIT; //toggle bit (yes i know it should not be hardcoded)
322
        *len = 5;
323
        previousBit = 1; //Same as last startbit
727 noddan 324
    } else {
922 zeed 325
        //We are reusing the signal from the previous signal 
326
        //and extend the time into this bit.
327
        buf[2] = IR_RC5_BIT;
328
        buf[3] = IR_RC5_HALF_BIT;
329
        *len = 4;
330
        previousBit = 0; //Toggled from last startbit
727 noddan 331
    }
922 zeed 332
    //Invert the toggle for next time
333
    rc5_toggle=!rc5_toggle & 1;
727 noddan 334
 
922 zeed 335
    //Decode the message
336
    //We know that RC5 messages are 14 bits long
337
    for(uint8_t pos=11;pos>0;pos--)
338
    {      
339
        // Check the current bit
340
        if(previousBit == ((rawMessage>>(pos-1)) & 1))
341
        {
342
            buf[*len]=IR_RC5_HALF_BIT;
343
            buf[*len+1]=IR_RC5_HALF_BIT;
344
            *len=*len+2;
732 noddan 345
        }
922 zeed 346
        else
347
        {
348
            //We are having the same signal as we ended the last bit with,
349
            //Expand the time that that signal is active to cover 
350
            //half of this bit aswell
351
            buf[*len-1]=IR_RC5_BIT;
352
            buf[*len]=IR_RC5_HALF_BIT;
353
            *len=*len+1;
354
 
355
            //Invert the previous bit
356
            previousBit = (!previousBit) & 1;
727 noddan 357
        }
358
    }
922 zeed 359
    //We have to handle the last bit specially since we have to 
360
    //end with low signal on the IR diod
361
    if(previousBit == 0)
362
    {
363
        //We have to remove the last time since that would bring us to a high signal again.
364
        *len=*len-1;
365
        buf[*len]=0;
366
    }
727 noddan 367
 
1837 myhrman 368
    proto->modfreq=IR_RC5_F_MOD;
727 noddan 369
    proto->timeout=IR_RC5_TIMEOUT;
370
    proto->repeats=IR_RC5_REPS;
371
    return IR_OK;
608 arune 372
}
373
 
610 arune 374
 
608 arune 375
#if (IR_PROTOCOLS_USE_SHARP)
376
/**
377
 * Test data on SHARP protocol
378
 * http://www.sbprojects.com/knowledge/ir/sharp.htm
379
 *
610 arune 380
 * @param buf
381
 *      Pointer to buffer to where to data to parse is stored
382
 * @param len
383
 *      Length of the data
384
 * @param proto
385
 *      Pointer to protocol information
608 arune 386
 * @return
387
 *      IR_OK if data parsed successfully, one of several errormessages if not
388
 */
389
int8_t parseSharp(const uint16_t *buf, uint8_t len, Ir_Protocol_Data_t *proto) {
390
    /* parse buf[], max is len */
391
 
392
    /* check if we have correct amount of data */
393
    if (len != 31) {
394
        return IR_NOT_CORRECT_DATA;
395
    }
396
 
397
    uint16_t rawbits=0;
398
 
399
    for (uint8_t i = 1; i < len; i++) {
400
        if ((i&1) == 1) {       /* if odd, ir-pause */
401
            /* check length of pause between bits */
402
            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) {
403
                /* write a one */
404
                rawbits |= 1<<((i-1)>>1);
405
            } 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) {
406
                /* do nothing, a zero is already in rawbits */
407
            } else {
408
                return IR_NOT_CORRECT_DATA;
409
            }
410
        } else {            /* if even, ir-bit */
411
            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) {
412
                return IR_NOT_CORRECT_DATA;
413
            }
414
        }
415
    }
416
 
2244 linlun 417
    proto->protocol=CAN_MODULE_ENUM_PHYSICAL_IR_PROTOCOL_SHARP;
608 arune 418
    proto->timeout=IR_SHARP_TIMEOUT;
419
    proto->data=rawbits;
420
    return IR_OK;
421
}
422
#endif
423
 
610 arune 424
/**
425
 * Expand data from Sharp protocol
426
 * http://www.sbprojects.com/knowledge/ir/sharp.htm
427
 *
428
 * @param buf
429
 *      Pointer to buffer to store the expanded data
430
 * @param len
431
 *      Pointer to length of the data
432
 * @param proto
433
 *      Pointer to protocol information
434
 * @return
435
 *      IR_OK if data expanded successfully, one of several errormessages if not
436
 */
608 arune 437
int8_t expandSharp(uint16_t *buf, uint8_t *len, Ir_Protocol_Data_t *proto) {
438
    //TODO: Implement this function.
439
    return IR_NOT_CORRECT_DATA;
440
}
441
 
610 arune 442
 
608 arune 443
#if (IR_PROTOCOLS_USE_NEC)
444
/**
445
 * Test data on NEC protocol
446
 * http://www.sbprojects.com/knowledge/ir/nec.htm
447
 *
610 arune 448
 * @param buf
449
 *      Pointer to buffer to where to data to parse is stored
450
 * @param len
451
 *      Length of the data
452
 * @param proto
453
 *      Pointer to protocol information
608 arune 454
 * @return
455
 *      IR_OK if data parsed successfully, one of several errormessages if not
456
 */
457
int8_t parseNEC(const uint16_t *buf, uint8_t len, Ir_Protocol_Data_t *proto) {
458
    /* parse buf[], max is len */
459
 
460
    /* check if we have correct amount of data */
461
    if (len != 67) {
462
        return IR_NOT_CORRECT_DATA;
463
    }
464
 
465
    /* check startbit */
466
    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) {
467
        return IR_NOT_CORRECT_DATA;
468
    }
469
 
470
    /* check pause after startbit */
471
    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) {
472
        return IR_NOT_CORRECT_DATA;
473
    }
474
 
610 arune 475
    uint32_t rawbits = 0;
608 arune 476
 
477
    for (uint8_t i = 3; i < len; i++) {
478
        if ((i&1) == 1) {       /* if odd, ir-pause */
479
            /* check length of pause between bits */
480
            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) {
481
                /* write a one */
610 arune 482
                rawbits |= 1UL<<((i-3)>>1);
608 arune 483
            } 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) {
484
                /* do nothing, a zero is already in place */
485
            } else {
486
                return IR_NOT_CORRECT_DATA;
487
            }
488
        } else {            /* if even, ir-bit */
489
            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) {
490
                return IR_NOT_CORRECT_DATA;
491
            }
492
        }
493
    }
494
 
2244 linlun 495
    proto->protocol=CAN_MODULE_ENUM_PHYSICAL_IR_PROTOCOL_NEC;
608 arune 496
    proto->timeout=IR_NEC_TIMEOUT;
610 arune 497
    proto->data=rawbits;   
608 arune 498
    return IR_OK;
499
}
500
#endif
501
 
610 arune 502
/**
503
 * Expand data from NEC protocol
504
 * http://www.sbprojects.com/knowledge/ir/nec.htm
505
 *
506
 * @param buf
507
 *      Pointer to buffer to store the expanded data
508
 * @param len
509
 *      Pointer to length of the data
510
 * @param proto
511
 *      Pointer to protocol information
512
 * @return
513
 *      IR_OK if data expanded successfully, one of several errormessages if not
514
 */
608 arune 515
int8_t expandNEC(uint16_t *buf, uint8_t *len, Ir_Protocol_Data_t *proto) {
516
    /* Set up startbit */
517
    buf[0] = IR_NEC_ST_BIT;
617 arune 518
 
519
    if (proto->framecnt == 0) {
520
        buf[1] = IR_NEC_ST_PAUSE;
521
 
522
        *len = 67;
523
        for (uint8_t i = 0; i < 65; i++) {
524
            if ((i&1) == 1) {       /* if odd, ir-pause */
525
                if ((proto->data>>(i>>1))&1) {
526
                    buf[i+2] = IR_NEC_LOW_ONE;
527
                } else {
528
                    buf[i+2] = IR_NEC_LOW_ZERO;
529
                }
530
            } else {            /* if even, ir-bit */
531
                buf[i+2] = IR_NEC_HIGH;
608 arune 532
            }
533
        }
617 arune 534
        proto->timeout=IR_NEC_TIMEOUT;
535
    } else {
536
        buf[1] = IR_NEC_ST_PAUSE/2;
537
        buf[2] = IR_NEC_HIGH;
538
        proto->timeout=IR_NEC_ST_TIMEOUT;
539
        *len = 3;
608 arune 540
    }
1837 myhrman 541
    proto->modfreq=IR_NEC_F_MOD;
608 arune 542
    proto->repeats=IR_NEC_REPS;
543
    return IR_OK;
544
}
545
 
610 arune 546
 
608 arune 547
#if (IR_PROTOCOLS_USE_SAMSUNG)
548
/**
549
 * Test data on Samsung protocol
550
 * Very much like NEC, different start bit/pause lengths etc.
551
 * http://www.sbprojects.com/knowledge/ir/nec.htm
552
 *
610 arune 553
 * @param buf
554
 *      Pointer to buffer to where to data to parse is stored
555
 * @param len
556
 *      Length of the data
557
 * @param proto
558
 *      Pointer to protocol information
608 arune 559
 * @return
560
 *      IR_OK if data parsed successfully, one of several errormessages if not
561
 */
562
int8_t parseSamsung(const uint16_t *buf, uint8_t len, Ir_Protocol_Data_t *proto) {
563
    /* parse buf[], max is len */
564
 
565
    /* check if we have correct amount of data */
566
    if (len != 67) {
567
        return IR_NOT_CORRECT_DATA;
568
    }
569
 
570
    /* check startbit */
571
    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) {
572
        return IR_NOT_CORRECT_DATA;
573
    }
574
 
575
    /* check pause after startbit */
576
    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) {
577
        return IR_NOT_CORRECT_DATA;
578
    }
579
 
610 arune 580
    uint32_t rawbits = 0;
608 arune 581
 
582
    for (uint8_t i = 3; i < len; i++) {
583
        if ((i&1) == 1) {       /* if odd, ir-pause */
584
            /* check length of pause between bits */
585
            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) {
586
                /* write a one */
610 arune 587
                rawbits |= 1UL<<((i-3)>>1);
608 arune 588
            } 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) {
589
                /* do nothing, a zero is already in rawbits */
590
            } else {
591
                return IR_NOT_CORRECT_DATA;
592
            }
593
        } else {            /* if even, ir-bit */
594
            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) {
595
                return IR_NOT_CORRECT_DATA;
596
            }
597
        }
598
    }
599
 
2244 linlun 600
    proto->protocol=CAN_MODULE_ENUM_PHYSICAL_IR_PROTOCOL_SAMSUNG;
608 arune 601
    proto->timeout=IR_SAMS_TIMEOUT;
610 arune 602
    proto->data=rawbits;   
608 arune 603
    return IR_OK;
604
}
605
#endif
606
 
610 arune 607
/**
608
 * Expand data from Samsung protocol
609
 * Very much like NEC, different start bit/pause lengths etc.
610
 * http://www.sbprojects.com/knowledge/ir/nec.htm
611
 *
612
 * @param buf
613
 *      Pointer to buffer to store the expanded data
614
 * @param len
615
 *      Pointer to length of the data
616
 * @param proto
617
 *      Pointer to protocol information
618
 * @return
619
 *      IR_OK if data expanded successfully, one of several errormessages if not
620
 */
608 arune 621
int8_t expandSamsung(uint16_t *buf, uint8_t *len, Ir_Protocol_Data_t *proto) {
622
    /* Set up startbit */
623
    buf[0] = IR_SAMS_ST_BIT;
624
    buf[1] = IR_SAMS_ST_PAUSE;
625
 
626
    for (uint8_t i = 0; i < 65; i++) {
627
        if ((i&1) == 1) {       /* if odd, ir-pause */
628
            if ((proto->data>>(i>>1))&1) {
629
                buf[i+2] = IR_SAMS_LOW_ONE;
630
            } else {
631
                buf[i+2] = IR_SAMS_LOW_ZERO;
632
            }
633
        } else {                /* if even, ir-bit */
634
            buf[i+2] = IR_SAMS_HIGH;
635
        }
636
    }
637
 
638
    *len = 67;
639
 
1837 myhrman 640
    proto->modfreq=IR_SAMS_F_MOD;
608 arune 641
    proto->timeout=IR_SAMS_TIMEOUT;
642
    proto->repeats=IR_SAMS_REPS;
643
    return IR_OK;
644
}
732 noddan 645
 
646
#if (IR_PROTOCOLS_USE_MARANTZ)
647
/**
648
 * Test data on Marantz protocol
649
 * Reverse-Engineered by Noddan, very similar to RC-5.
650
 * Not tested with odd adresses since I have no remote that sends them.
651
 * Don't know what happens with the extra long bit in that case.
652
 *
653
 * @param buf
654
 *      Pointer to buffer to where to data to parse is stored
655
 * @param len
656
 *      Length of the data
657
 * @param proto
658
 *      Pointer to protocol information
659
 * @return
660
 *      IR_OK if data parsed successfully, one of several errormessages if not
661
 */
662
int8_t parseMarantz(const uint16_t *buf, uint8_t len, Ir_Protocol_Data_t *proto) {
663
    uint8_t halfbitscnt = 1;
664
    uint32_t rawbits = 0;
665
 
666
    for (uint8_t i = 0; i<len; i++) {
667
        //halfbitscnt&1==1 in the middle of bits
668
        //i&1==0 positive flank
669
 
670
        if ((halfbitscnt&1)==1 && (i&1)==0) {       /* in the middle of bit AND a positve flank */
671
            rawbits |= (uint32_t)1<<(19-(halfbitscnt>>1));
672
        }
673
 
734 noddan 674
        if (buf[i] > IR_MARANTZ_HALF_BIT - IR_MARANTZ_HALF_BIT/IR_MARANTZ_TOL_DIV && buf[i] < IR_MARANTZ_HALF_BIT + IR_MARANTZ_HALF_BIT/IR_MARANTZ_TOL_DIV) {
732 noddan 675
            halfbitscnt += 1;
734 noddan 676
        } else if (buf[i] > IR_MARANTZ_BIT - IR_MARANTZ_BIT/IR_MARANTZ_TOL_DIV && buf[i] < IR_MARANTZ_BIT + IR_MARANTZ_BIT/IR_MARANTZ_TOL_DIV) {
732 noddan 677
            halfbitscnt += 2;
734 noddan 678
        } else if (buf[i] > IR_MARANTZ_BIT - IR_MARANTZ_BIT/IR_MARANTZ_TOL_DIV && buf[i] < 5*IR_MARANTZ_HALF_BIT + IR_MARANTZ_BIT/IR_MARANTZ_TOL_DIV) {
732 noddan 679
            halfbitscnt += 1; //It seems to work, not entirely sure of the purpose of this long zero though.
680
        } else {
681
            return IR_NOT_CORRECT_DATA;
682
        }
683
 
684
    }
685
 
2244 linlun 686
    proto->protocol=CAN_MODULE_ENUM_PHYSICAL_IR_PROTOCOL_MARANTZ;
734 noddan 687
    proto->timeout=IR_MARANTZ_TIMEOUT;
732 noddan 688
    proto->data = rawbits&0x0001ffff;
689
 
690
    return IR_OK;
691
}
1320 arune 692
#endif
732 noddan 693
 
694
/**
1320 arune 695
 * Expand data from Marantz. Written by Martin Nordin
732 noddan 696
 *
697
 * @param buf
698
 *      Pointer to buffer to store the expanded data
699
 * @param len
700
 *      Pointer to length of the data
701
 * @param proto
702
 *      Pointer to protocol information
703
 * @return
704
 *      IR_OK if data expanded successfully, one of several errormessages if not
705
 */
706
int8_t expandMarantz(uint16_t *buf, uint8_t *len, Ir_Protocol_Data_t *proto) {
707
    uint8_t previousBit;
708
    uint32_t tempdata;
709
 
710
    /* Set up startbits */
734 noddan 711
    buf[0] = IR_MARANTZ_HALF_BIT;//first start bit
712
    buf[1] = IR_MARANTZ_HALF_BIT;
713
    buf[2] = IR_MARANTZ_HALF_BIT;//second start bit
732 noddan 714
    //TODO: Toggle bit should be better, not hard-coded
734 noddan 715
    buf[3] = IR_MARANTZ_HALF_BIT;
716
    buf[4] = IR_MARANTZ_HALF_BIT;//toggle bit
732 noddan 717
    *len=5;
718
    previousBit = 1;
719
 
733 noddan 720
    tempdata = (uint32_t)(proto->data)<<14;
721
 
722
    for(uint8_t i = 0; i < 17; i++) {
732 noddan 723
        tempdata = (uint32_t)tempdata<<1;
733 noddan 724
 
725
        if (((uint32_t)tempdata>>31)==1){
732 noddan 726
            if (previousBit == 1){//11
734 noddan 727
                buf[*len] = IR_MARANTZ_HALF_BIT;
728
                buf[*len+1] = IR_MARANTZ_HALF_BIT;
732 noddan 729
                *len = *len + 2;
730
            } else {//01
734 noddan 731
                buf[*len-1] = IR_MARANTZ_BIT;
732
                buf[*len] = IR_MARANTZ_HALF_BIT;
732 noddan 733
                *len = *len + 1;
734
            }
735
            previousBit = 1;
736
        } else {
737
            if (previousBit == 1){//10
734 noddan 738
                buf[*len-1] = IR_MARANTZ_BIT;
739
                buf[*len] = IR_MARANTZ_HALF_BIT;
732 noddan 740
                *len = *len + 1;
741
            } else {//00
734 noddan 742
                buf[*len] = IR_MARANTZ_HALF_BIT;
733 noddan 743
                if (i==4){
734 noddan 744
                    buf[*len+1] = IR_MARANTZ_HALF_BIT*5;
732 noddan 745
                } else {
734 noddan 746
                    buf[*len+1] = IR_MARANTZ_HALF_BIT;
732 noddan 747
                }
748
 
749
                *len = *len + 2;
750
            }
751
            previousBit = 0;
752
        }
753
    }
754
    //make sure that we finish high by removing the last zero if needed
755
    if (*len%2 == 0){
756
        *len = *len - 1;
757
    }
758
 
1837 myhrman 759
    proto->modfreq=IR_MARANTZ_F_MOD;
734 noddan 760
    proto->timeout=IR_MARANTZ_TIMEOUT;
761
    proto->repeats=IR_MARANTZ_REPS;
732 noddan 762
    return IR_OK;
763
}
764
 
1320 arune 765
#if (IR_PROTOCOLS_USE_PANASONIC)
766
/**
767
 * Test data on Panasonic protocol
768
 *
769
 * @param buf
770
 *      Pointer to buffer to where to data to parse is stored
771
 * @param len
772
 *      Length of the data
773
 * @param proto
774
 *      Pointer to protocol information
775
 * @return
776
 *      IR_OK if data parsed successfully, one of several errormessages if not
777
 */
778
int8_t parsePanasonic(const uint16_t *buf, uint8_t len, Ir_Protocol_Data_t *proto) {
779
    /* parse buf[], max is len */
732 noddan 780
 
1320 arune 781
    /* check if we have correct amount of data */
782
    if (len != 99) {
783
        return IR_NOT_CORRECT_DATA;
784
    }
785
 
786
    /* check startbit */
787
    if (buf[0] > IR_PANA_ST_BIT + IR_PANA_ST_BIT/IR_PANA_TOL_DIV || buf[0] < IR_PANA_ST_BIT - IR_PANA_ST_BIT/IR_PANA_TOL_DIV) {
788
        return IR_NOT_CORRECT_DATA;
789
    }
790
 
791
    /* check pause after startbit */
792
    if (buf[1] > IR_PANA_ST_PAUSE + IR_PANA_ST_PAUSE/IR_PANA_TOL_DIV || buf[1] < IR_PANA_ST_PAUSE - IR_PANA_ST_PAUSE/IR_PANA_TOL_DIV) {
793
        return IR_NOT_CORRECT_DATA;
794
    }
795
 
796
    uint32_t rawbits = 0;
797
 
798
    /* skip start bit, start bit pause and first 16 bits (32 values) */
799
    for (uint8_t i = (3+16*2); i < len; i++) {
800
        if ((i&1) == 1) {       /* if odd, ir-pause */
801
            /* check length of pause between bits */
802
            if (buf[i] > IR_PANA_LOW_ONE - IR_PANA_LOW_ONE/IR_PANA_TOL_DIV && buf[i] < IR_PANA_LOW_ONE + IR_PANA_LOW_ONE/IR_PANA_TOL_DIV) {
803
                /* write a one */
804
                rawbits |= 1UL<<((i-(3+16*2))>>1);
805
            } else if (buf[i] > IR_PANA_LOW_ZERO - IR_PANA_LOW_ZERO/IR_PANA_TOL_DIV && buf[i] < IR_PANA_LOW_ZERO + IR_PANA_LOW_ZERO/IR_PANA_TOL_DIV) {
806
                /* do nothing, a zero is already in rawbits */
807
            } else {
808
                return IR_NOT_CORRECT_DATA;
809
            }
810
        } else {            /* if even, ir-bit */
811
            if (buf[i] > IR_PANA_HIGH + IR_PANA_HIGH/IR_PANA_TOL_DIV || buf[i] < IR_PANA_HIGH - IR_PANA_HIGH/IR_PANA_TOL_DIV) {
812
                return IR_NOT_CORRECT_DATA;
813
            }
814
        }
815
    }
816
 
2244 linlun 817
    proto->protocol=CAN_MODULE_ENUM_PHYSICAL_IR_PROTOCOL_PANASONIC;
1320 arune 818
    proto->timeout=IR_PANA_TIMEOUT;
819
    proto->data=rawbits;   
820
    return IR_OK;
821
}
732 noddan 822
#endif
1320 arune 823
 
824
/**
825
 * Expand data from Panasonic protocol
826
 *
827
 * @param buf
828
 *      Pointer to buffer to store the expanded data
829
 * @param len
830
 *      Pointer to length of the data
831
 * @param proto
832
 *      Pointer to protocol information
833
 * @return
834
 *      IR_OK if data expanded successfully, one of several errormessages if not
835
 */
836
int8_t expandPanasonic(uint16_t *buf, uint8_t *len, Ir_Protocol_Data_t *proto) {
837
    /* Set up startbit */
838
    buf[0] = IR_PANA_ST_BIT;
839
    buf[1] = IR_PANA_ST_PAUSE;
840
 
841
    /* add the first 16 static bits */
842
    uint16_t staticBits = 0x2002;
843
    for (uint8_t i = 0; i < 32; i++) {
844
        if ((i&1) == 1) {       /* if odd, ir-pause */
845
            if ((staticBits>>(i>>1))&1) {
846
                buf[i+2] = IR_PANA_LOW_ONE;
847
            } else {
848
                buf[i+2] = IR_PANA_LOW_ZERO;
849
            }
850
        } else {                /* if even, ir-bit */
851
            buf[i+2] = IR_PANA_HIGH;
852
        }
853
    }
854
 
855
    /* then add the value bits */
856
    for (uint8_t i = 0; i < 65; i++) {
857
        if ((i&1) == 1) {       /* if odd, ir-pause */
858
            if ((proto->data>>(i>>1))&1) {
859
                buf[i+2+32] = IR_PANA_LOW_ONE;
860
            } else {
861
                buf[i+2+32] = IR_PANA_LOW_ZERO;
862
            }
863
        } else {                /* if even, ir-bit */
864
            buf[i+2+32] = IR_PANA_HIGH;
865
        }
866
    }
867
 
868
    *len = 99;
869
 
1837 myhrman 870
    proto->modfreq=IR_PANA_F_MOD;
1320 arune 871
    proto->timeout=IR_PANA_TIMEOUT;
872
    proto->repeats=IR_PANA_REPS;
873
    return IR_OK;
874
}
1562 arune 875
 
876
#if (IR_PROTOCOLS_USE_SKY)
877
/**
878
 * Test data on Sky protocol
879
 *
880
 *
881
 * @param buf
882
 *      Pointer to buffer to where to data to parse is stored
883
 * @param len
884
 *      Length of the data
885
 * @param proto
886
 *      Pointer to protocol information
887
 * @return
888
 *      IR_OK if data parsed successfully, one of several errormessages if not
889
 */
890
int8_t parseSky(const uint16_t *buf, uint8_t len, Ir_Protocol_Data_t *proto) {
891
    /* parse buf[], max is len */
892
 
893
    /* check startbit */
894
    if (buf[0] > IR_SKY_ST_BIT + IR_SKY_ST_BIT/IR_SKY_TOL_DIV || buf[0] < IR_SKY_ST_BIT - IR_SKY_ST_BIT/IR_SKY_TOL_DIV) {
895
        return IR_NOT_CORRECT_DATA;
896
    }
897
 
898
    uint32_t rawbits=0;
899
    uint8_t current=0;
900
    uint8_t previous=0;
901
    uint8_t cnt=0;
902
#define SKYLONG 0
903
#define SKYSHORT 1
904
    for (uint8_t i = 1; i < len; i++)
905
    {
906
        if (buf[i] > IR_SKY_SHORT - IR_SKY_SHORT/IR_SKY_TOL_DIV && buf[i] < IR_SKY_SHORT + IR_SKY_SHORT/IR_SKY_TOL_DIV) {
907
            current = SKYSHORT;
908
        }
909
        else if (buf[i] > IR_SKY_LONG - IR_SKY_LONG/IR_SKY_TOL_DIV && buf[i] < IR_SKY_LONG + IR_SKY_LONG/IR_SKY_TOL_DIV) {
910
            current = SKYLONG;
911
        }
912
        else {
913
            return IR_NOT_CORRECT_DATA;
914
        }
915
 
916
        /* if level is low */
917
        if ((rawbits&1)==0) {
918
            /* and there is a long pulse */
919
            if (current == SKYLONG) {
920
                /* push a one */
921
                rawbits = rawbits<<1;
922
                rawbits |= 1;
923
                cnt = 0;
924
            }
925
            else if (cnt == 0) {
926
                cnt=1;
927
                /* push a zero */
928
                rawbits = rawbits<<1;
929
 
930
            }
931
            else {
932
                cnt = 0;
933
            }
934
        }
935
 
936
        /* if level is high */
937
        if ((rawbits&1)==1) {
938
            /* and there is a long pulse */
939
            if (current == SKYLONG) {
940
                /* push a zero */
941
                rawbits = rawbits<<1;
942
 
943
                if (previous == SKYLONG) {
944
                    cnt = 1;
945
                }
946
                else {
947
                    cnt = 0;
948
                }
949
            }
950
            else if (cnt == 0) {
951
                cnt=1;
952
                /* push a one */
953
                rawbits = rawbits<<1;
954
                rawbits |= 1;
955
            }
956
            else {
957
                cnt = 0;
958
            }
959
        }
960
 
961
        previous=current;
962
 
963
    }
964
 
2244 linlun 965
    proto->protocol = CAN_MODULE_ENUM_PHYSICAL_IR_PROTOCOL_SKY;
1562 arune 966
    proto->timeout = IR_SKY_TIMEOUT;
967
    proto->data = rawbits;
968
 
969
    return IR_OK;
970
}
971
#endif
972
 
973
/**
974
 * Expand data from Sky protocol
975
 *
976
 *
977
 * @param buf
978
 *      Pointer to buffer to store the expanded data
979
 * @param len
980
 *      Pointer to length of the data
981
 * @param proto
982
 *      Pointer to protocol information
983
 * @return
984
 *      IR_OK if data expanded successfully, one of several errormessages if not
985
 */
986
int8_t expandSky(uint16_t *buf, uint8_t *len, Ir_Protocol_Data_t *proto) {
987
    //TODO: Implement this function.
988
    buf[0] = IR_SKY_ST_BIT;
989
    buf[1] = IR_SKY_LONG;   //
990
 
991
 
992
    return IR_NOT_CORRECT_DATA;
993
}
994
 
2244 linlun 995
#if (IR_PROTOCOLS_USE_IROBOT)
996
/**
997
 * Test data on iRobot protocol
998
 *
999
 *
1000
 * @param buf
1001
 *      Pointer to buffer to where to data to parse is stored
1002
 * @param len
1003
 *      Length of the data
1004
 * @param proto
1005
 *      Pointer to protocol information
1006
 * @return
1007
 *      IR_OK if data parsed successfully, one of several errormessages if not
1008
 */
1009
int8_t parseiRobot(const uint16_t *buf, uint8_t len, Ir_Protocol_Data_t *proto) {
1010
    /* parse buf[], max is len */  
1011
    uint32_t rawbits=0;
1012
    uint8_t current=0;
1013
    uint8_t previous=0;
1014
    uint8_t cnt=0;
1015
#define IROBOTLONG 0
1016
#define IROBOTSHORT 1
1017
 
1018
    /* check if we have correct amount of data */
1019
    if (len != 16) {
1020
        return IR_NOT_CORRECT_DATA;
1021
    }
1022
 
1023
 
1024
    for (uint8_t i = 0; i < len; i++)
1025
    {
1026
        if (buf[i] > IR_IROBOT_SHORT - IR_IROBOT_SHORT/IR_IROBOT_TOL_DIV && buf[i] < IR_IROBOT_SHORT + IR_IROBOT_SHORT/IR_IROBOT_TOL_DIV) {
1027
            current = IROBOTSHORT;
1028
        }
1029
        else if (buf[i] > IR_IROBOT_LONG - IR_IROBOT_LONG/IR_IROBOT_TOL_DIV && buf[i] < IR_IROBOT_LONG + IR_IROBOT_LONG/IR_IROBOT_TOL_DIV) {
1030
            current = IROBOTLONG;
1031
        }
1032
        else {
1033
            return IR_NOT_CORRECT_DATA;
1034
        }
1035
 
1036
        /* if level is low */
1037
        if ((rawbits&1)==0) {
1038
            /* and there is a long pulse */
1039
            if (current == IROBOTLONG) {
1040
                /* push a one */
1041
                rawbits = rawbits<<1;
1042
                rawbits |= 1;
1043
                cnt = 0;
1044
            }
1045
            else if (cnt == 0) {
1046
                cnt=1;
1047
                /* push a zero */
1048
                rawbits = rawbits<<1;
1049
 
1050
            }
1051
            else {
1052
                cnt = 0;
1053
            }
1054
        }
1055
 
1056
        /* if level is high */
1057
        if ((rawbits&1)==1) {
1058
            /* and there is a long pulse */
1059
            if (current == IROBOTLONG) {
1060
                /* push a zero */
1061
                rawbits = rawbits<<1;
1062
 
1063
                if (previous == IROBOTLONG) {
1064
                    cnt = 1;
1065
                }
1066
                else {
1067
                    cnt = 0;
1068
                }
1069
            }
1070
            else if (cnt == 0) {
1071
                cnt=1;
1072
                /* push a one */
1073
                rawbits = rawbits<<1;
1074
                rawbits |= 1;
1075
            }
1076
            else {
1077
                cnt = 0;
1078
            }
1079
        }
1080
 
1081
        previous=current;
1082
 
1083
    }
1084
 
1085
    proto->protocol = CAN_MODULE_ENUM_PHYSICAL_IR_PROTOCOL_IROBOT;
1086
    proto->timeout = IR_IROBOT_TIMEOUT;
1087
    proto->data = rawbits;
1088
 
1089
    return IR_OK;
1090
}
1091
#endif
1092
 
1093
/**
1094
 * Expand data from iRobot protocol
1095
 *
1096
 *
1097
 * @param buf
1098
 *      Pointer to buffer to store the expanded data
1099
 * @param len
1100
 *      Pointer to length of the data
1101
 * @param proto
1102
 *      Pointer to protocol information
1103
 * @return
1104
 *      IR_OK if data expanded successfully, one of several errormessages if not
1105
 */
1106
int8_t expandiRobot(uint16_t *buf, uint8_t *len, Ir_Protocol_Data_t *proto) {
1107
    uint8_t temp;
1108
    uint8_t lookup[16] = {
1109
                   0x0, 0x8, 0x4, 0xC,
1110
                   0x2, 0xA, 0x6, 0xE,
1111
                   0x1, 0x9, 0x5, 0xD,
1112
                   0x3, 0xB, 0x7, 0xF };
1113
    temp = (uint8_t)proto->data;
1114
    temp = (lookup[temp &0x0F] << 4) | lookup[temp >>4];
2246 linlun 1115
    proto->data = temp;
1116
    //proto->data = temp << 8;
1117
    //proto->data += 0x52;
1118
    for (uint8_t i = 0; i < 16; i++) {
2244 linlun 1119
        if ((proto->data>>(i>>1))&1) {
1120
            buf[i] = IR_IROBOT_LONG;
1121
            i++;
1122
            buf[i] = IR_IROBOT_SHORT;  
1123
        } else {
1124
            buf[i] = IR_IROBOT_SHORT;
1125
            i++;
1126
            buf[i] = IR_IROBOT_LONG;
1127
        }
1128
    }
1129
 
2246 linlun 1130
    *len = 15;
2244 linlun 1131
    proto->modfreq=IR_IROBOT_F_MOD;
1132
    proto->timeout=IR_IROBOT_TIMEOUT;
1133
    proto->repeats=IR_IROBOT_REPS;
1134
    return IR_OK;
1135
}
1136
 
1137
 
1588 linlun 1138
#if (IR_PROTOCOLS_USE_NEXA2)
1139
/**
1140
 * Test data on NEXA protocol
1141
 * http://elektronikforumet.com/wiki/index.php?title=RF_Protokoll_-_Nexa_sj%C3%A4lvl%C3%A4rande
2065 arune 1142
 * http://pastebin.com/PJX3bRAs
1588 linlun 1143
 *
1144
 * @param buf
1145
 *      Pointer to buffer to where to data to parse is stored
1146
 * @param len
1147
 *      Length of the data
1148
 * @param proto
1149
 *      Pointer to protocol information
1150
 * @return
1151
 *      IR_OK if data parsed successfully, one of several errormessages if not
1152
 */
2198 arune 1153
 
2199 arune 1154
int8_t parseNexa2(const uint16_t *buf, uint8_t len, uint8_t index, Ir_Protocol_Data_t *proto)
1155
{
1588 linlun 1156
    /* check if we have correct amount of data */
2198 arune 1157
    if (len < 132) {
1588 linlun 1158
        return IR_NOT_CORRECT_DATA;
1159
    }
2199 arune 1160
    uint8_t i;
1161
#if IR_RX_CONTINUOUS_MODE==0
1162
    i = 0;
1163
#else
1164
    i=index-132;
1165
    if (i>index)
1166
        i+=MAX_NR_TIMES;
1167
#endif
1168
    if ((buf[i] < IR_NEXA2_START1 - IR_NEXA2_START1/IR_NEXA2_TOL_DIV) || (buf[i] > IR_NEXA2_START1 + IR_NEXA2_START1/IR_NEXA2_TOL_DIV)) { //check start bit
1588 linlun 1169
        return IR_NOT_CORRECT_DATA;
1170
    }
2199 arune 1171
#if IR_RX_CONTINUOUS_MODE==0
1172
    i = 1;
1173
#else
1174
    i=index-131;
1175
    if (i>index)
1176
        i+=MAX_NR_TIMES;
1177
#endif
1178
    if ((buf[i] < IR_NEXA2_HIGH - IR_NEXA2_HIGH/IR_NEXA2_TOL_DIV) || (buf[i] > IR_NEXA2_HIGH + IR_NEXA2_HIGH/IR_NEXA2_TOL_DIV)) { //check start bit
1874 arune 1179
        return IR_NOT_CORRECT_DATA;
1180
    }
2199 arune 1181
#if IR_RX_CONTINUOUS_MODE==0
1182
    i = 2;
1183
#else
1184
    i=index-130;
1185
    if (i>index)
1186
        i+=MAX_NR_TIMES;
1187
#endif
1188
    if ((buf[i] < IR_NEXA2_START2 - IR_NEXA2_START2/IR_NEXA2_TOL_DIV) || (buf[i] > IR_NEXA2_START2 + IR_NEXA2_START2/IR_NEXA2_TOL_DIV)) { //check start bit
1874 arune 1189
        return IR_NOT_CORRECT_DATA;
1190
    }
1191
 
1875 arune 1192
    /* Incoming data could actually be longer than 32bits when a dimming command is received */
1929 arune 1193
    uint64_t rawbitsTemp = 0;
1874 arune 1194
    uint8_t bitCounter = 0;
2199 arune 1195
    uint8_t i2;
1196
    for (i = 3; i < 132; i++) {
1197
#if IR_RX_CONTINUOUS_MODE==0
1198
        i2 = i;
1199
#else
1200
        i2=index-(132-i);
1201
        if (i2>index)
1202
            i2+=MAX_NR_TIMES;
1203
#endif
1875 arune 1204
        if ((i&1) == 0) {       /* if even, data */
1874 arune 1205
            /* check length of transmit pulse */
2199 arune 1206
            if ((buf[i2] > IR_NEXA2_LOW_ONE - IR_NEXA2_LOW_ONE/IR_NEXA2_TOL_DIV) && (buf[i2] < IR_NEXA2_LOW_ONE + IR_NEXA2_LOW_ONE/IR_NEXA2_TOL_DIV)) {
1588 linlun 1207
                /* write a one */
1875 arune 1208
                rawbitsTemp |= (1UL)<<(bitCounter++);
2199 arune 1209
            } else if ((buf[i2] > IR_NEXA2_LOW_ZERO - IR_NEXA2_LOW_ZERO/IR_NEXA2_TOL_DIV) && (buf[i2] < IR_NEXA2_LOW_ZERO + IR_NEXA2_LOW_ZERO/IR_NEXA2_TOL_DIV)) {
1588 linlun 1210
                /* do nothing, a zero is already in rawbits */
1211
                bitCounter++;
1212
            } else {
1213
                return IR_NOT_CORRECT_DATA;
1214
            }
1874 arune 1215
            i+=2;   // skip every other bit, implement check here in the future
1875 arune 1216
        } else {            /* if odd, no data */
2200 arune 1217
            if ((buf[i2] < IR_NEXA2_HIGH - IR_NEXA2_HIGH/IR_NEXA2_TOL_DIV) || (buf[i2] > IR_NEXA2_HIGH + IR_NEXA2_HIGH/IR_NEXA2_TOL_DIV)) {
1588 linlun 1218
                return IR_NOT_CORRECT_DATA;
1219
            }
1220
        }
1221
    }
1222
 
2244 linlun 1223
    proto->protocol=CAN_MODULE_ENUM_PHYSICAL_IR_PROTOCOL_NEXA2;
1588 linlun 1224
    proto->timeout=IR_NEXA2_TIMEOUT;
1875 arune 1225
    proto->data=rawbitsTemp;
1588 linlun 1226
    return IR_OK;
1227
}
1228
#endif
1229
 
1886 arune 1230
/**
1231
 * Expand data from Nexa2 protocol
1232
 *
1233
 *
1234
 * @param buf
1235
 *      Pointer to buffer to store the expanded data
1236
 * @param len
1237
 *      Pointer to length of the data
1238
 * @param proto
1239
 *      Pointer to protocol information
1240
 * @return
1241
 *      IR_OK if data expanded successfully, one of several errormessages if not
1242
 */
1243
int8_t expandNexa2(uint16_t *buf, uint8_t *len, Ir_Protocol_Data_t *proto) {
1922 arune 1244
    buf[0] = IR_NEXA2_HIGH;
1245
    buf[1] = IR_NEXA2_START2;
1246
 
1930 arune 1247
    uint64_t tempshift = proto->data;
1248
 
1249
    /* No dimming */
1922 arune 1250
    *len = 131;
1930 arune 1251
    uint8_t dimming = 0;
2013 arune 1252
    /* If most significant bit is set, then dimming should be sent */
2119 linlun 1253
    if ((uint32_t)(tempshift>> 32)&0x80)
2065 arune 1254
    {
1930 arune 1255
        /* Dimming */
2065 arune 1256
        *len = 147;
1257
        dimming=1;
1258
    }
1922 arune 1259
 
2065 arune 1260
    for (uint8_t i = 2; i < *len; i+=4)
1929 arune 1261
    {
1262
        buf[i] = IR_NEXA2_HIGH;
1263
        buf[i+2] = IR_NEXA2_HIGH;
1264
        if (tempshift&1) {
1265
            buf[i+1] = IR_NEXA2_LOW_ONE;
1266
            buf[i+3] = IR_NEXA2_LOW_ZERO;
1267
        } else {
1268
            buf[i+1] = IR_NEXA2_LOW_ZERO;
1269
            buf[i+3] = IR_NEXA2_LOW_ONE;
1270
        }
1271
        tempshift = tempshift>>1;
1272
    }
1922 arune 1273
 
1930 arune 1274
    if (dimming)
1275
    {
2065 arune 1276
        buf[111] = IR_NEXA2_LOW_ONE;
1277
        buf[113] = IR_NEXA2_LOW_ONE;
1930 arune 1278
    }
1929 arune 1279
    proto->modfreq=IR_NEXA2_F_MOD;
1280
    proto->timeout=IR_NEXA2_START1/1000;
1281
    proto->repeats=IR_NEXA2_REPS;
1282
    return IR_OK;
1886 arune 1283
}
1284
 
1904 arune 1285
 
1286
#if (IR_PROTOCOLS_USE_NEXA1)
1287
/**
1288
 * Test data on NEXA protocol
1289
 * http://www.elektronikforumet.com/wiki/index.php/RF_Protokoll_-_Nexa/Proove_(%C3%A4ldre,_ej_sj%C3%A4lvl%C3%A4rande)
1290
 *
1291
 * @param buf
1292
 *      Pointer to buffer to where to data to parse is stored
1293
 * @param len
1294
 *      Length of the data
1295
 * @param proto
1296
 *      Pointer to protocol information
1297
 * @return
1298
 *      IR_OK if data parsed successfully, one of several errormessages if not
1299
 */
2199 arune 1300
int8_t parseNexa1(const uint16_t *buf, uint8_t len, uint8_t index, Ir_Protocol_Data_t *proto) {
1904 arune 1301
    /* parse buf[], max is len */
1302
 
2223 arune 1303
    uint8_t i;
1904 arune 1304
    /* check if we have correct amount of data */
2223 arune 1305
    if (len < 50) {
1904 arune 1306
        return IR_NOT_CORRECT_DATA;
1307
    }
2223 arune 1308
#if IR_RX_CONTINUOUS_MODE==0
1309
    i = 0;
1310
#else
1311
    i=index-50;
1312
    if (i>index)
1313
        i+=MAX_NR_TIMES;
1314
#endif
1315
    if (buf[i] < IR_NEXA1_START - IR_NEXA1_START/IR_NEXA1_TOL_DIV || buf[i] > IR_NEXA1_START + IR_NEXA1_START/IR_NEXA1_TOL_DIV) { //check start bit
1906 arune 1316
        return IR_NOT_CORRECT_DATA;
1317
    }
1318
 
1904 arune 1319
    uint32_t rawbitsTemp = 0;
1906 arune 1320
    uint8_t bitCounter = 0;
1904 arune 1321
 
2223 arune 1322
    for (i = 1; i < 48; i+=4)
1323
    {
1324
        uint8_t i2;
1325
#if IR_RX_CONTINUOUS_MODE==0
1326
        i2 = i;
1327
#else
1328
        i2=index-(50-i);
1329
        if (i2>index)
1330
            i2+=MAX_NR_TIMES;
1331
#endif
1906 arune 1332
        /* Check if '0' bit */
1333
        if (
2223 arune 1334
            (buf[i2+0] > IR_NEXA1_SHORT - IR_NEXA1_SHORT/IR_NEXA1_TOL_DIV) && (buf[i2+0] < IR_NEXA1_SHORT + IR_NEXA1_SHORT/IR_NEXA1_TOL_DIV) &&
1335
            (buf[i2+1] > IR_NEXA1_LONG  - IR_NEXA1_LONG /IR_NEXA1_TOL_DIV) && (buf[i2+1] < IR_NEXA1_LONG  + IR_NEXA1_LONG /IR_NEXA1_TOL_DIV) &&
1336
            (buf[i2+2] > IR_NEXA1_SHORT - IR_NEXA1_SHORT/IR_NEXA1_TOL_DIV) && (buf[i2+2] < IR_NEXA1_SHORT + IR_NEXA1_SHORT/IR_NEXA1_TOL_DIV) &&
1337
            (buf[i2+3] > IR_NEXA1_LONG  - IR_NEXA1_LONG /IR_NEXA1_TOL_DIV) && (buf[i2+3] < IR_NEXA1_LONG  + IR_NEXA1_LONG /IR_NEXA1_TOL_DIV) )
1906 arune 1338
        {
1339
            /* write a one */
1340
            rawbitsTemp |= (1UL)<<(bitCounter++);
1341
        }
1342
        /* Check if 'X' bit */
1343
        else if (
2223 arune 1344
            (buf[i2+0] > IR_NEXA1_SHORT - IR_NEXA1_SHORT/IR_NEXA1_TOL_DIV) && (buf[i2+0] < IR_NEXA1_SHORT + IR_NEXA1_SHORT/IR_NEXA1_TOL_DIV) &&
1345
            (buf[i2+1] > IR_NEXA1_LONG  - IR_NEXA1_LONG /IR_NEXA1_TOL_DIV) && (buf[i2+1] < IR_NEXA1_LONG  + IR_NEXA1_LONG /IR_NEXA1_TOL_DIV) &&
1346
            (buf[i2+2] > IR_NEXA1_LONG  - IR_NEXA1_LONG /IR_NEXA1_TOL_DIV) && (buf[i2+2] < IR_NEXA1_LONG  + IR_NEXA1_LONG /IR_NEXA1_TOL_DIV) &&
1347
            (buf[i2+3] > IR_NEXA1_SHORT - IR_NEXA1_SHORT/IR_NEXA1_TOL_DIV) && (buf[i2+3] < IR_NEXA1_SHORT + IR_NEXA1_SHORT/IR_NEXA1_TOL_DIV) )
1906 arune 1348
        {
1349
            /* do nothing, a zero is already in rawbits */
1350
            bitCounter++;
1351
        }
2223 arune 1352
        else
1353
        {
1354
            return IR_NOT_CORRECT_DATA;
1355
        }
1906 arune 1356
    }
2013 arune 1357
 
1358
    if (rawbitsTemp==0)
1359
    {
1360
        /* Bogus RF data */
1361
        return IR_NOT_CORRECT_DATA;
1362
    }
1906 arune 1363
 
2244 linlun 1364
    proto->protocol=CAN_MODULE_ENUM_PHYSICAL_IR_PROTOCOL_NEXA;
1904 arune 1365
    proto->timeout=IR_NEXA1_TIMEOUT;
1366
    proto->data=rawbitsTemp;
1367
    return IR_OK;
1368
}
1369
 
1370
#endif
1371
 
1372
/**
1373
 * Expand data from Nexa1 protocol
1374
 *
1375
 *
1376
 * @param buf
1377
 *      Pointer to buffer to store the expanded data
1378
 * @param len
1379
 *      Pointer to length of the data
1380
 * @param proto
1381
 *      Pointer to protocol information
1382
 * @return
1383
 *      IR_OK if data expanded successfully, one of several errormessages if not
1384
 */
1385
int8_t expandNexa1(uint16_t *buf, uint8_t *len, Ir_Protocol_Data_t *proto) {
2143 bjorne 1386
    uint64_t tempshift = proto->data;
1387
 
1388
    /* 12 data bits + 1 stop bit */
1389
    *len = 49;
1390
 
1391
    /* encode data bits */
1392
    for (uint8_t i = 0; i < 45; i += 4)
1393
    {
1394
        if (tempshift & 1) {
1395
            /* encode 0 bit */
1396
            buf[i+0] = IR_NEXA1_SHORT;
1397
            buf[i+1] = IR_NEXA1_LONG;
1398
            buf[i+2] = IR_NEXA1_SHORT;
1399
            buf[i+3] = IR_NEXA1_LONG;
1400
        } else {
1401
            /* encode X bit */
1402
            buf[i+0] = IR_NEXA1_SHORT;
1403
            buf[i+1] = IR_NEXA1_LONG;
1404
            buf[i+2] = IR_NEXA1_LONG;
1405
            buf[i+3] = IR_NEXA1_SHORT;
1406
        }
1407
        tempshift = tempshift>>1;
1408
    }
1409
 
1410
    /* encode stop/sync bit */
1411
    buf[48] = IR_NEXA1_SHORT;
1904 arune 1412
 
2143 bjorne 1413
    proto->modfreq = IR_NEXA1_F_MOD;
1414
    proto->timeout = IR_NEXA1_START/1000;
1415
    proto->repeats = IR_NEXA1_REPS;
1416
    return IR_OK;  
1904 arune 1417
}
1418
 
2200 arune 1419
 
1420
#if (IR_PROTOCOLS_USE_VIKING)
1421
/**
2297 arune 1422
 * Test data on Viking sensor protocol
1423
 * This is protocol type 4 (temperature with sign and one more byte)
2200 arune 1424
 *
1425
 *
1426
 * @param buf
1427
 *      Pointer to buffer to where to data to parse is stored
1428
 * @param len
1429
 *      Length of the data
1430
 * @param proto
1431
 *      Pointer to protocol information
1432
 * @return
1433
 *      IR_OK if data parsed successfully, one of several errormessages if not
1434
 */
1435
 
1436
int8_t parseViking(const uint16_t *buf, uint8_t len, uint8_t index, Ir_Protocol_Data_t *proto)
1437
{
2203 arune 1438
#if IR_RX_CONTINUOUS_MODE==1
2200 arune 1439
    /* check if we have correct amount of data */
2202 arune 1440
    if (len < 90) {
2200 arune 1441
        return IR_NOT_CORRECT_DATA;
1442
    }
1443
    uint8_t i, i2;
2204 arune 1444
    uint64_t rawbitsTemp = 0;//0xffffffffffffffff;
2202 arune 1445
 
1446
    for (i = 90; i > 0; i--)
1447
    {
1448
        i2=index-i;
2200 arune 1449
        if (i2>index)
1450
            i2+=MAX_NR_TIMES;
2202 arune 1451
 
1452
        /* Check if correct amount of data have been received */
2204 arune 1453
        if ((i == 78) && (rawbitsTemp != 0b00001))
2202 arune 1454
            return IR_NOT_CORRECT_DATA;
1455
 
2297 arune 1456
/* Only check type if we have separate support for type 3 */
1457
#if (IR_PROTOCOLS_USE_VIKING_T3)
1458
        /* Check type, only allow type=4 (3 inverted) */
1459
        if ((i == 72) && (rawbitsTemp != 0b00001011))
1460
            return IR_NOT_CORRECT_DATA;
1461
#endif
1462
 
2200 arune 1463
        if ((i&1) == 0)
1464
        {       /* if even, no data */
1465
            if ((buf[i2] < IR_VIKING_LOW - IR_VIKING_LOW/IR_VIKING_TOL_DIV) || (buf[i2] > IR_VIKING_LOW + IR_VIKING_LOW/IR_VIKING_TOL_DIV))
1466
            {
1467
                return IR_NOT_CORRECT_DATA;
1468
            }
1469
        }
2204 arune 1470
        else
2200 arune 1471
        {           /* if odd, data */
1472
            /* check length of transmit pulse */
1473
            if ((buf[i2] > IR_VIKING_HIGH_ONE - IR_VIKING_HIGH_ONE/IR_VIKING_TOL_DIV) && (buf[i2] < IR_VIKING_HIGH_ONE + IR_VIKING_HIGH_ONE/IR_VIKING_TOL_DIV))
1474
            {
1475
                /* write a one */
2202 arune 1476
                rawbitsTemp = rawbitsTemp<<1;
1477
                rawbitsTemp |= 1;
2200 arune 1478
            }
1479
            else if ((buf[i2] > IR_VIKING_HIGH_ZERO - IR_VIKING_HIGH_ZERO/IR_VIKING_TOL_DIV) && (buf[i2] < IR_VIKING_HIGH_ZERO + IR_VIKING_HIGH_ZERO/IR_VIKING_TOL_DIV))
1480
            {
1481
                /* do nothing, a zero is already in rawbits */
2202 arune 1482
                rawbitsTemp = rawbitsTemp<<1;
2200 arune 1483
            }
1484
            else
1485
            {
1486
                return IR_NOT_CORRECT_DATA;
1487
            }
1488
        }
1489
    }
1490
 
2204 arune 1491
    rawbitsTemp = ~rawbitsTemp;
1492
    rawbitsTemp = rawbitsTemp&0xFFFFFFFFFF;
2202 arune 1493
 
2244 linlun 1494
    proto->protocol=CAN_MODULE_ENUM_PHYSICAL_IR_PROTOCOL_VIKING;
2200 arune 1495
    proto->timeout=0;
1496
    proto->data=rawbitsTemp;
1497
 
1498
    return IR_OK;
2203 arune 1499
#else
1500
    return IR_NOT_CORRECT_DATA;
1501
#endif
2200 arune 1502
}
1503
#endif
2233 linlun 1504
 
1505
 
2297 arune 1506
#if (IR_PROTOCOLS_USE_VIKING_T3)
1507
/**
1508
 * Test data on Viking sensor protocol
1509
 * This is protocol type 3 (offseted temperature with three bytes)
1510
 *
1511
 *
1512
 * @param buf
1513
 *      Pointer to buffer to where to data to parse is stored
1514
 * @param len
1515
 *      Length of the data
1516
 * @param proto
1517
 *      Pointer to protocol information
1518
 * @return
1519
 *      IR_OK if data parsed successfully, one of several errormessages if not
1520
 */
1521
 
1522
int8_t parseVikingT3(const uint16_t *buf, uint8_t len, uint8_t index, Ir_Protocol_Data_t *proto)
1523
{
1524
#if IR_RX_CONTINUOUS_MODE==1
1525
    /* check if we have correct amount of data */
1526
    if (len < 106) {
1527
        return IR_NOT_CORRECT_DATA;
1528
    }
1529
    uint8_t i, i2;
1530
    uint64_t rawbitsTemp = 0;//0xffffffffffffffff;
1531
    //uint8_t rawbitsTempArr[6] = {0,0,0,0,0,0};
1532
 
1533
    for (i = 106; i > 16; i--)
1534
    {
1535
        i2=index-i;
1536
        if (i2>index)
1537
            i2+=MAX_NR_TIMES;
1538
 
1539
        /* Check if correct amount of data have been received */
1540
        if ((i == 94) && (rawbitsTemp != 0b00001))
1541
            return IR_NOT_CORRECT_DATA;
1542
 
1543
        /* Check type, only allow type=3 (4 inverted) */
1544
        if ((i == 88) && (rawbitsTemp != 0b00001100))
1545
            return IR_NOT_CORRECT_DATA;
1546
 
1547
        if ((i&1) == 0)
1548
        {       /* if even, no data */
1549
            if ((buf[i2] < IR_VIKING_LOW - IR_VIKING_LOW/IR_VIKING_TOL_DIV) || (buf[i2] > IR_VIKING_LOW + IR_VIKING_LOW/IR_VIKING_TOL_DIV))
1550
            {
1551
                return IR_NOT_CORRECT_DATA;
1552
            }
1553
        }
1554
        else
1555
        {           /* if odd, data */
1556
            /* check length of transmit pulse */
1557
            if ((buf[i2] > IR_VIKING_HIGH_ONE - IR_VIKING_HIGH_ONE/IR_VIKING_TOL_DIV) && (buf[i2] < IR_VIKING_HIGH_ONE + IR_VIKING_HIGH_ONE/IR_VIKING_TOL_DIV))
1558
            {
1559
                /* write a one */
1560
                rawbitsTemp = rawbitsTemp<<1;
1561
                rawbitsTemp |= 1;
1562
            }
1563
            else if ((buf[i2] > IR_VIKING_HIGH_ZERO - IR_VIKING_HIGH_ZERO/IR_VIKING_TOL_DIV) && (buf[i2] < IR_VIKING_HIGH_ZERO + IR_VIKING_HIGH_ZERO/IR_VIKING_TOL_DIV))
1564
            {
1565
                /* do nothing, a zero is already in rawbits */
1566
                rawbitsTemp = rawbitsTemp<<1;
1567
            }
1568
            else
1569
            {
1570
                return IR_NOT_CORRECT_DATA;
1571
            }
1572
        }
1573
    }
1574
 
1575
    uint16_t rest = 0;
1576
    for (i = 16; i > 0; i--)
1577
    {
1578
        i2=index-i;
1579
        if (i2>index)
1580
            i2+=MAX_NR_TIMES;
1581
 
1582
        if ((i&1) == 0)
1583
        {       /* if even, no data */
1584
            if ((buf[i2] < IR_VIKING_LOW - IR_VIKING_LOW/IR_VIKING_TOL_DIV) || (buf[i2] > IR_VIKING_LOW + IR_VIKING_LOW/IR_VIKING_TOL_DIV))
1585
            {
1586
                return IR_NOT_CORRECT_DATA;
1587
            }
1588
        }
1589
        else
1590
        {           /* if odd, data */
1591
            /* check length of transmit pulse */
1592
            if ((buf[i2] > IR_VIKING_HIGH_ONE - IR_VIKING_HIGH_ONE/IR_VIKING_TOL_DIV) && (buf[i2] < IR_VIKING_HIGH_ONE + IR_VIKING_HIGH_ONE/IR_VIKING_TOL_DIV))
1593
            {
1594
                /* write a one */
1595
                rest = rest<<1;
1596
                rest |= 1;
1597
            }
1598
            else if ((buf[i2] > IR_VIKING_HIGH_ZERO - IR_VIKING_HIGH_ZERO/IR_VIKING_TOL_DIV) && (buf[i2] < IR_VIKING_HIGH_ZERO + IR_VIKING_HIGH_ZERO/IR_VIKING_TOL_DIV))
1599
            {
1600
                /* do nothing, a zero is already in rawbits */
1601
                rest = rest<<1;
1602
            }
1603
            else
1604
            {
1605
                return IR_NOT_CORRECT_DATA;
1606
            }
1607
        }
1608
    }
1609
    rest = ~rest;
1610
    //rest = rest&0xFF;
1611
 
1612
    rawbitsTemp = ~rawbitsTemp;
1613
    rawbitsTemp = rawbitsTemp&0xFFFFFFFFFF;
1614
 
1615
    uint8_t crc = 0;
1616
    crc = _crc_ibutton_update(crc, 0xFF);
1617
    crc = _crc_ibutton_update(crc, rawbitsTemp&0xFF);
1618
    crc = _crc_ibutton_update(crc, (rawbitsTemp>>8)&0xFF);
1619
    crc = _crc_ibutton_update(crc, (rawbitsTemp>>16)&0xFF);
1620
    crc = _crc_ibutton_update(crc, (rawbitsTemp>>24)&0xFF);
1621
    crc = _crc_ibutton_update(crc, (rawbitsTemp>>32)&0xFF);
1622
    //crc = _crc_ibutton_update(crc, (rawbitsTemp>>40)&0xFF);
1623
 
1624
    rawbitsTemp = rawbitsTemp&0xFFFFFF0000;
1625
    rawbitsTemp |= (crc<<8)|((rest>>8)&0xFF);
1626
 
1627
    proto->protocol=CAN_MODULE_ENUM_PHYSICAL_IR_PROTOCOL_VIKING;
1628
    proto->timeout=0;
1629
    proto->data=rawbitsTemp;
1630
 
1631
    return IR_OK;
1632
#else
1633
    return IR_NOT_CORRECT_DATA;
1634
#endif
1635
}
1636
#endif
1637
 
1638
 
2233 linlun 1639
#if (IR_PROTOCOLS_USE_VIKING_STEAK)
1640
/**
1641
 * Test data on Viking steak temperature sensor protocol
1642
 *
1643
 *
1644
 *
1645
 * @param buf
1646
 *      Pointer to buffer to where to data to parse is stored
1647
 * @param len
1648
 *      Length of the data
1649
 * @param proto
1650
 *      Pointer to protocol information
1651
 * @return
1652
 *      IR_OK if data parsed successfully, one of several errormessages if not
1653
 */
1654
 
1655
int8_t parseVikingSteak(const uint16_t *buf, uint8_t len, uint8_t index, Ir_Protocol_Data_t *proto)
1656
{
1657
#if IR_RX_CONTINUOUS_MODE==1
1658
    /* check if we have correct amount of data */
2236 linlun 1659
    if (len < 74) {
2233 linlun 1660
        return IR_NOT_CORRECT_DATA;
1661
    }
1662
    uint8_t i, i2;
1663
    uint64_t rawbitsTemp = 0;//0xffffffffffffffff;
1664
 
1665
    /* Check start bit condition */
2236 linlun 1666
    i2=index-74;
2233 linlun 1667
    if (i2>index)
1668
        i2+=MAX_NR_TIMES;
1669
 
2236 linlun 1670
    proto->data=i2;     /*Store startindex for debug output */
1671
 
1672
    if ((buf[i2] < IR_VIKING_STEAK_LOW_START - IR_VIKING_STEAK_LOW_START/IR_VIKING_STEAK_TOL_DIV) || (buf[i2] > IR_VIKING_STEAK_LOW_START + IR_VIKING_STEAK_LOW_START/IR_VIKING_STEAK_TOL_DIV))
2233 linlun 1673
    {
1674
        return IR_NOT_CORRECT_DATA;
1675
    }
1676
 
1677
    for (i = 73; i > 0; i--)
1678
    {
1679
        i2=index-i;
1680
        if (i2>index)
1681
            i2+=MAX_NR_TIMES;
1682
 
1683
        /* Check if correct amount of data have been received */
1684
        //if ((i == 78) && (rawbitsTemp != 0b00001))
1685
        //  return IR_NOT_CORRECT_DATA;
1686
 
1687
        if ((i&1) != 0)
1688
        {       /* if odd, no data */
2236 linlun 1689
            if ((buf[i2] < IR_VIKING_STEAK_HIGH - IR_VIKING_STEAK_HIGH/IR_VIKING_STEAK_TOL_DIV) || (buf[i2] > IR_VIKING_STEAK_HIGH + IR_VIKING_STEAK_HIGH/IR_VIKING_STEAK_TOL_DIV))
2233 linlun 1690
            {
1691
                return IR_NOT_CORRECT_DATA;
1692
            }
1693
        }
1694
        else
1695
        {           /* if even, data */
1696
            /* check length of transmit pulse */
2236 linlun 1697
            if ((buf[i2] > IR_VIKING_STEAK_LOW_ONE - IR_VIKING_STEAK_LOW_ONE/IR_VIKING_STEAK_TOL_DIV) && (buf[i2] < IR_VIKING_STEAK_LOW_ONE + IR_VIKING_STEAK_LOW_ONE/IR_VIKING_STEAK_TOL_DIV))
2233 linlun 1698
            {
1699
                /* write a one */
1700
                rawbitsTemp = rawbitsTemp<<1;
1701
                rawbitsTemp |= 1;
1702
            }
2236 linlun 1703
            else if ((buf[i2] > IR_VIKING_STEAK_LOW_ZERO - IR_VIKING_STEAK_LOW_ZERO/IR_VIKING_STEAK_TOL_DIV) && (buf[i2] < IR_VIKING_STEAK_LOW_ZERO + IR_VIKING_STEAK_LOW_ZERO/IR_VIKING_STEAK_TOL_DIV))
2233 linlun 1704
            {
1705
                /* do nothing, a zero is already in rawbits */
1706
                rawbitsTemp = rawbitsTemp<<1;
1707
            }
1708
            else
1709
            {
1710
                return IR_NOT_CORRECT_DATA;
1711
            }
1712
        }
1713
    }
1714
 
1715
    //rawbitsTemp = ~rawbitsTemp;
1716
    //rawbitsTemp = rawbitsTemp&0xFFFFFFFFFF;
1717
 
2245 linlun 1718
    proto->protocol=CAN_MODULE_ENUM_PHYSICAL_IR_PROTOCOL_VIKINGSTEAK;
2237 linlun 1719
    proto->timeout=IR_VIKING_STEAK_TIMEOUT;
2233 linlun 1720
    proto->data=rawbitsTemp;
1721
 
1722
    return IR_OK;
1723
#else
1724
    return IR_NOT_CORRECT_DATA;
1725
#endif
1726
}
1727
#endif
2239 linlun 1728
 
1729
#if (IR_PROTOCOLS_USE_RUBICSON)
1730
/**
1731
 * Test data on Rubicson temperature sensor protocol
1732
 *
1733
 *
1734
 *
1735
 * @param buf
1736
 *      Pointer to buffer to where to data to parse is stored
1737
 * @param len
1738
 *      Length of the data
1739
 * @param proto
1740
 *      Pointer to protocol information
1741
 * @return
1742
 *      IR_OK if data parsed successfully, one of several errormessages if not
1743
 */
1744
 
1745
int8_t parseRubicson(const uint16_t *buf, uint8_t len, uint8_t index, Ir_Protocol_Data_t *proto)
1746
{
1747
#if IR_RX_CONTINUOUS_MODE==1
1748
    /* check if we have correct amount of data */
1749
    if (len < 74) {
1750
        return IR_NOT_CORRECT_DATA;
1751
    }
1752
    uint8_t i, i2;
1753
    uint64_t rawbitsTemp = 0;//0xffffffffffffffff;
1754
 
1755
    /* Check start bit condition */
1756
    i2=index-74;
1757
    if (i2>index)
1758
        i2+=MAX_NR_TIMES;
1759
 
1760
    proto->data=i2;     /*Store startindex for debug output */
1761
 
1762
    if ((buf[i2] < IR_RUBICSON_LOW_START - IR_RUBICSON_LOW_START/IR_RUBICSON_TOL_DIV) || (buf[i2] > IR_RUBICSON_LOW_START + IR_RUBICSON_LOW_START/IR_RUBICSON_TOL_DIV))
1763
    {
1764
        return IR_NOT_CORRECT_DATA;
1765
    }
1766
 
1767
    for (i = 73; i > 0; i--)
1768
    {
1769
        i2=index-i;
1770
        if (i2>index)
1771
            i2+=MAX_NR_TIMES;
1772
 
1773
        /* Check if correct amount of data have been received */
1774
        //if ((i == 78) && (rawbitsTemp != 0b00001))
1775
        //  return IR_NOT_CORRECT_DATA;
1776
 
1777
        if ((i&1) != 0)
1778
        {       /* if odd, no data */
2241 linlun 1779
            if ((buf[i2] < IR_RUBICSON_HIGH - IR_RUBICSON_HIGH/IR_RUBICSON_TOL_DIV) || (buf[i2] > IR_RUBICSON_HIGH + IR_RUBICSON_HIGH/IR_RUBICSON_TOL_DIV))
2239 linlun 1780
            {
1781
                return IR_NOT_CORRECT_DATA;
1782
            }
1783
        }
1784
        else
1785
        {           /* if even, data */
1786
            /* check length of transmit pulse */
1787
            if ((buf[i2] > IR_RUBICSON_LOW_ONE - IR_RUBICSON_LOW_ONE/IR_RUBICSON_TOL_DIV) && (buf[i2] < IR_RUBICSON_LOW_ONE + IR_RUBICSON_LOW_ONE/IR_RUBICSON_TOL_DIV))
1788
            {
1789
                /* write a one */
1790
                rawbitsTemp = rawbitsTemp<<1;
1791
                rawbitsTemp |= 1;
1792
            }
1793
            else if ((buf[i2] > IR_RUBICSON_LOW_ZERO - IR_RUBICSON_LOW_ZERO/IR_RUBICSON_TOL_DIV) && (buf[i2] < IR_RUBICSON_LOW_ZERO + IR_RUBICSON_LOW_ZERO/IR_RUBICSON_TOL_DIV))
1794
            {
1795
                /* do nothing, a zero is already in rawbits */
1796
                rawbitsTemp = rawbitsTemp<<1;
1797
            }
1798
            else
1799
            {
1800
                return IR_NOT_CORRECT_DATA;
1801
            }
1802
        }
1803
    }
1804
 
1805
    //rawbitsTemp = ~rawbitsTemp;
1806
    //rawbitsTemp = rawbitsTemp&0xFFFFFFFFFF;
1807
 
2244 linlun 1808
    proto->protocol=CAN_MODULE_ENUM_PHYSICAL_IR_PROTOCOL_RUBICSON;
2239 linlun 1809
    proto->timeout=IR_RUBICSON_TIMEOUT;
1810
    proto->data=rawbitsTemp;
1811
 
1812
    return IR_OK;
1813
#else
1814
    return IR_NOT_CORRECT_DATA;
1815
#endif
1816
}
1817
#endif
1818
 
2254 linlun 1819
 
1820
 
1821
#if (IR_PROTOCOLS_USE_OREGON)
1822
/**
1823
 * Test data on OREGON weather sensor protocol
1824
 *
1825
 *
1826
 *
1827
 * @param buf
1828
 *      Pointer to buffer to where to data to parse is stored
1829
 * @param len
1830
 *      Length of the data
1831
 * @param proto
1832
 *      Pointer to protocol information
1833
 * @return
1834
 *      IR_OK if data parsed successfully, one of several errormessages if not
1835
 */
1836
 
1837
int8_t parseOregon(const uint16_t *buf, uint8_t len, uint8_t index, Ir_Protocol_Data_t *proto)
1838
{
1839
#if IR_RX_CONTINUOUS_MODE==1
1840
    /* check if we have correct amount of data */
2259 linlun 1841
    if (len < 160) {    //Ändra till vettigt värde
1842
        return IR_NOT_CORRECT_DATA;
1843
    }
1844
    uint8_t data[IR_OREGON_DATASIZE]; //Verifiera minsta möjliga storlek
1845
    uint8_t i2 = 0;
1846
    uint8_t b_i;
1847
    uint8_t currentBit = 1;
1848
    uint8_t done = 0;
1849
    uint8_t bits = 0;
1850
    uint8_t shift = 0;
1851
    uint16_t temperature=0;
1852
    uint8_t i = index;
1853
    uint16_t temp =0;
1854
    uint64_t rawbitsTemp = 0;//0xffffffffffffffff;
1855
    const uint8_t nibbleSwap[16] = {0x0u,0x8u,0x4u,0xCu,0x2u,0xAu,0x6u,0xEu,0x1u,0x9u,0x5u,0xDu,0x3u,0xBu,0x7u,0xFu};
1856
 
1857
    gpio_set_pin(EXP_K);
1858
    /* Check stop condition */
1859
    /*if (buf[i] < IR_OREGON_END)
1860
    {
1861
      //printf("data: %d of %d\n", buf[i], IR_OREGON_END);
1862
        return IR_NOT_CORRECT_DATA;
1863
    }
1864
    */
1865
    //gpio_set_pin(EXP_L);
1866
 
1867
    if (160 > index) {
1868
      i = MAX_NR_TIMES-160+index;
1869
    } else {
1870
      i = index - 160;
1871
    }
1872
    len= 160; //Store remaining length
1873
 
1874
 
1875
    while (len>117) {
1876
      if ((buf[i] > IR_OREGON_SHORT_L) || (buf[i] < IR_OREGON_SHORT_S)){
1877
        gpio_set_pin(EXP_L);
1878
        return IR_NOT_CORRECT_DATA;
1879
      }
1880
      i++;
1881
      if (i>= MAX_NR_TIMES){
1882
        i=0;
1883
      }
1884
      len--;
1885
    }
1886
    gpio_set_pin(EXP_M);
1887
    if ((buf[i] < IR_OREGON_LONG_L) && (buf[i] > IR_OREGON_LONG_S)){
1888
      gpio_set_pin(EXP_N);    
1889
    } else  {
1890
      return IR_NOT_CORRECT_DATA;
1891
    }
1892
    i++;
1893
    len--;
1894
    if (i>= MAX_NR_TIMES){
1895
      i=0;
1896
    }
1897
    if ((buf[i] < IR_OREGON_LONG_L) && (buf[i] > IR_OREGON_LONG_S)){
1898
      gpio_toggle_pin(EXP_N);    
1899
    } else  {
1900
      return IR_NOT_CORRECT_DATA;
1901
    }
1902
    i++;
1903
    len--;
1904
    if (i>= MAX_NR_TIMES){
1905
      i=0;
1906
    }
1907
    if ((buf[i] < IR_OREGON_LONG_L) && (buf[i] > IR_OREGON_LONG_S)){
1908
      gpio_toggle_pin(EXP_N);    
1909
    } else  {
1910
      return IR_NOT_CORRECT_DATA;
1911
    }
1912
    i++;
1913
    len--;
1914
    if (i>= MAX_NR_TIMES){
1915
      i=0;
1916
    }
1917
    if ((buf[i] < IR_OREGON_LONG_L) && (buf[i] > IR_OREGON_LONG_S)){
1918
      gpio_toggle_pin(EXP_N);    
1919
    } else  {
1920
      return IR_NOT_CORRECT_DATA;
1921
    }
1922
    i++;
1923
    len--;
1924
    if (i>= MAX_NR_TIMES){
1925
      i=0;
1926
    }
1927
    gpio_set_pin(EXP_L);
1928
    i2=i;
1929
    i2++;
1930
    if (i2>= MAX_NR_TIMES){
1931
      i2=0;
1932
    }
1933
    bits = 0;
1934
    while ( bits < 16) {
1935
        if ((buf[i] < IR_OREGON_SHORT_L) && (buf[i] > IR_OREGON_SHORT_S)){
1936
          if ((buf[i2] < IR_OREGON_SHORT_L) && (buf[i2] > IR_OREGON_SHORT_S)){
1937
          i++;
1938
          i2++;
1939
          } else {
1940
        printf("d1: %d %d %d\n", (int)(buf[i]*CYCLES_PER_US/TIMER_PRESC),(int)(buf[i2]*CYCLES_PER_US/TIMER_PRESC), len);
1941
        return IR_NOT_CORRECT_DATA;
1942
          }
1943
        } else if ((buf[i] < IR_OREGON_LONG_L) && (buf[i] > IR_OREGON_LONG_S)){
1944
          currentBit = !currentBit;
1945
        } else {
1946
          printf("d2: %d %d\n", (int)(buf[i]*CYCLES_PER_US/TIMER_PRESC), len);
1947
          return IR_NOT_CORRECT_DATA;
1948
        }
1949
        gpio_toggle_pin(EXP_M);
1950
        bits++;
1951
        if (currentBit) {
1952
          rawbitsTemp = rawbitsTemp<<1;
1953
          rawbitsTemp |= 1;
1954
        } else {
1955
          rawbitsTemp = rawbitsTemp<<1;
1956
        }
1957
        i++;
1958
        len--;
1959
        if (i>= MAX_NR_TIMES){
1960
          i=0;
1961
        }
1962
        i2++;
1963
        if (i2>= MAX_NR_TIMES){
1964
          i2=0;
1965
        }
1966
    }
1967
    bits = 0;
1968
    //inverse bitorder
1969
    while (bits < 16) {
1970
      bits++;
1971
      if (rawbitsTemp & 0x1u) {
1972
          temp |= 1u;
1973
      }
1974
      if (bits == 16) {
1975
        break;
1976
      }
1977
      temp = temp << 1;
1978
      rawbitsTemp = rawbitsTemp >> 1;
1979
    }
1980
    //restore nibbleorder
1981
    rawbitsTemp = ((temp & 0xFu) << 12)+((temp>>4 & 0xFu) << 8)+((temp>>8 & 0xFu) << 4)+((temp>>12 & 0xFu));
1982
/*
1983
    if ((rawbitsTemp != 0xf824) && (rawbitsTemp != 0x1d20) && (rawbitsTemp != 0xf8b4) ) {
1984
      printf("Found sens: %x\n", (uint16_t)rawbitsTemp);
1985
      return IR_NOT_CORRECT_DATA;
1986
    }
1987
    */
1988
    //----------------------
1989
    uint8_t bitlenght = 0;
1990
    uint16_t sensorType = (uint16_t)rawbitsTemp;
1991
    switch (sensorType)
1992
    {
1993
      case 0xf824:
1994
      case 0x1d20:
1995
      case 0xf8b4:
1996
        // Temperature and humidity
1997
        //printf("Found temp\n");
1998
        bitlenght = 40;
1999
        break;
2000
      case 0x2914:
2001
        // Rain gage inches
2002
        printf("Found rain\n");
2003
        bitlenght = 56;
2004
        break;
2005
      case 0x1984:
2006
      case 0x1994:    
2007
        // Wind speed and direction
2008
        printf("Found wind\n");
2009
        bitlenght = 52;
2010
        break;
2011
      default:
2012
        printf("Found sens: %x\n", (uint16_t)rawbitsTemp);
2013
        return IR_NOT_CORRECT_DATA;
2014
    }
2015
 
2016
 
2017
    bits = 0;
2018
    rawbitsTemp = 0;
2019
    while ( bits < bitlenght) {
2020
        if ((buf[i] < IR_OREGON_SHORT_L) && (buf[i] > IR_OREGON_SHORT_S)){
2021
          if ((buf[i2] < IR_OREGON_SHORT_L) && (buf[i2] > IR_OREGON_SHORT_S)){
2022
          i++;
2023
          i2++;
2024
          } else {
2025
        printf("x1: %d %d %d\n", (int)(buf[i]*CYCLES_PER_US/TIMER_PRESC),(int)(buf[i2]*CYCLES_PER_US/TIMER_PRESC), len);
2026
        return IR_NOT_CORRECT_DATA;
2027
          }
2028
        } else if ((buf[i] < IR_OREGON_LONG_L) && (buf[i] > IR_OREGON_LONG_S)){
2029
          currentBit = !currentBit;
2030
        } else {
2031
          printf("x2: %d %d\n", (int)(buf[i]*CYCLES_PER_US/TIMER_PRESC), len);
2032
          return IR_NOT_CORRECT_DATA;
2033
        }
2034
        gpio_toggle_pin(EXP_M);
2035
        bits++;
2036
        if (currentBit) {
2037
          rawbitsTemp = rawbitsTemp<<1;
2038
          rawbitsTemp |= 1;
2039
        } else {
2040
          rawbitsTemp = rawbitsTemp<<1;
2041
        }
2042
        i++;
2043
        len--;
2044
        if (i>= MAX_NR_TIMES){
2045
          i=0;
2046
        }
2047
        i2++;
2048
        if (i2>= MAX_NR_TIMES){
2049
          i2=0;
2050
        }
2051
    }
2052
 
2053
    proto->data = 0;
2054
    bits = 0;
2055
 
2056
    switch (sensorType)
2057
    {
2058
      case 0xf824:
2059
      case 0x1d20:
2060
      case 0xf8b4:
2061
       /* ----------- Data order rawbitsTemp ------
2062
        * aa bc cc de ef
2063
        * fe ed cc cb aa
2064
        * aa  = Humidity in BCD %
2065
        * b   = Sign for temperature (1 => -, 0 => +)
2066
        * ccc = Temperature in BCD celcius
2067
        * d   = 0x01 bat low, 0x00 bat OK
2068
        * ee  = Rolling code, random value each time batteries is inserted
2069
        * f   =  Channel
2070
        * -----------------------------*/
2071
        //printf("begi: %x %x %x %x\n", (uint16_t)(rawbitsTemp>>48), (uint16_t)(rawbitsTemp>>32), (uint16_t)(rawbitsTemp>>16), (uint16_t)rawbitsTemp);
2072
 
2073
        //Convert hunmidity to decimal from BCD
2074
        i = (uint8_t)( (rawbitsTemp & 0xFF ));
2075
        //printf("humi: %x\n", i);
2076
        i = ((uint8_t)nibbleSwap[i & 0xF]<<4) + ((uint8_t)(nibbleSwap[(i>>4) & 0xF])&0x0f);
2077
        //printf("humi: %x\n", i);
2078
        index = (i>>4)*10 + (i & 0x0Fu);
2079
        proto->data = index; // humidity
2080
 
2081
        //Convert temperature to decimal from BCD
2082
        temperature = (uint16_t)( ((rawbitsTemp >> 8) & 0x7FFF ));
2083
        //printf("temp: %x\n", temperature);
2084
        temperature = ((nibbleSwap[(temperature>>0) & 0xF]<<12)&0xf000) + ((nibbleSwap[(temperature>>4) & 0xF]<<8)&0x0f00) + ((nibbleSwap[(temperature>>8) & 0xF]<<4)&0x00f0) + ((nibbleSwap[(temperature>>12) & 0xF]<<0)&0x000f);
2085
        //printf("temp: %x\n", temperature);
2086
 
2087
        temperature = ((temperature>>12) & 0x0Fu)*1000 +((temperature>>8) & 0x0Fu)*100 +((temperature>>4) & 0x0Fu)*10 + (temperature & 0x0Fu);
2088
        //printf("temd: %d\n", temperature);
2089
 
2090
        if (rawbitsTemp & 0x0080000000 ) {
2091
          temperature = -temperature;
2092
        }
2093
        proto->data += ((temperature & 0xFFFF) << 8);
2094
 
2095
 
2096
        //Add channel information
2097
        proto->data += ((uint64_t)nibbleSwap[(uint8_t)( ((rawbitsTemp >> 36 ) & 0xF))]) << 46;
2098
        //printf("chan: %d\n", nibbleSwap[(uint8_t)( ((rawbitsTemp >> 36 ) & 0xF))]);
2099
 
2100
        //Add battery information
2101
        proto->data += ((uint64_t)(nibbleSwap[(uint8_t)( ((rawbitsTemp >> 24 ) & 0xF))])&0x1) << 45;
2102
        //printf("bat : %d\n", ((nibbleSwap[(uint8_t)( ((rawbitsTemp >> 24 ) & 0xF))])&0x1));
2103
 
2104
        //Add rolling code information
2105
        i = (uint8_t)((rawbitsTemp >> 28 ) & 0xFF);
2106
        i = (uint8_t)nibbleSwap[i & 0xF] + ((uint8_t)(nibbleSwap[(i>>4) & 0xF]<<4)&0xf0);
2107
        i = i & 0x1F;
2108
        proto->data += ((uint64_t)(i)) << 40;
2109
        //printf("roll : %d\n", i);
2110
 
2111
 
2112
        /* ----------- Data order proto-data ------
2113
        * cc 00 00 bb bb aa
2114
        * aa   = Humidity in %
2115
        * bbbb = Temperature*10 in celcius
2116
        * cc   = 0xddefffff
2117
        *   dd = Channel
2118
        *   e  = Battery low flag
2119
        *   fffff = Lower part of rolling code
2120
        * -----------------------------*/
2121
 
2122
        //printf("done: %x %x %x %x\n", (uint16_t)(proto->data>>48), (uint16_t)(proto->data>>32), (uint16_t)(proto->data>>16), (uint16_t)proto->data);
2123
        proto->protocol=CAN_MODULE_ENUM_PHYSICAL_IR_PROTOCOL_OREGONTEMPHUM;
2124
        proto->timeout=IR_OREGON_TIMEOUT;
2125
        return IR_OK;
2126
        break;
2127
      case 0x2914:
2128
        // Rain gage inches
2129
        /* ----------- Data order rawbitsTemp ------
2130
        * aa aa bb bb bb de ef
2131
        * fe ed bb bb bb aa aa
2132
        * a   = Rain in 0.01 inches per hour
2133
        * b   = Total Rain in 0.001 inches
2134
        * d   = 0x01 bat low, 0x00 bat OK
2135
        * ee  = Rolling code, random value each time batteries is inserted
2136
        * f   =  Channel
2137
        * -----------------------------*/
2138
        printf("begi: %x %x %x %x\n", (uint16_t)(rawbitsTemp>>48), (uint16_t)(rawbitsTemp>>32), (uint16_t)(rawbitsTemp>>16), (uint16_t)rawbitsTemp);
2139
 
2140
        //Convert rain per hour
2141
        temp = (uint16_t)( (rawbitsTemp & 0xFFFF ));
2142
        printf("i/h : %x\n", temp);
2143
        temp = ((nibbleSwap[(temp>>0) & 0xF]<<12)&0xf000) + ((nibbleSwap[(temp>>4) & 0xF]<<8)&0x0f00) + ((nibbleSwap[(temp>>8) & 0xF]<<4)&0x00f0) + ((nibbleSwap[(temp>>12) & 0xF]<<0)&0x000f);
2144
        printf("i/h : %x\n", temp);
2145
        printf("i/h : %d\n", temp);
2146
        temp = ((temp>>12) & 0x0Fu)*1000 +((temp>>8) & 0x0Fu)*100 +((temp>>4) & 0x0Fu)*10 + (temp & 0x0Fu);
2147
        proto->data = temp; // inches per hour
2148
 
2149
        uint32_t temp32 = 0;
2150
 
2151
        //Convert temperature to decimal from BCD
2152
        temp32 = (uint32_t)( ((rawbitsTemp >> 16) & 0xFFFFFF ));
2153
        printf("temp: %x\n", temp32);
2154
        temp32 = (((uint32_t)nibbleSwap[(temp32>>0) & 0xF]<<20)&0xf00000) + (((uint32_t)nibbleSwap[(temp32>>4) & 0xF]<<16)&0x0f0000) + (((uint32_t)nibbleSwap[(temp32>>8) & 0xF]<<12)&0x00f000) + (((uint32_t)nibbleSwap[(temp32>>12) & 0xF]<<8)&0x000f00) + (((uint32_t)nibbleSwap[(temp32>>16) & 0xF]<<4)&0x0000f0) + (((uint32_t)nibbleSwap[(temp32>>20) & 0xF]<<0)&0x00000f);
2155
        //printf("temp: %x\n", temperature);
2156
 
2157
        //temperature = ((temperature>>12) & 0x0Fu)*1000 +((temperature>>8) & 0x0Fu)*100 +((temperature>>4) & 0x0Fu)*10 + (temperature & 0x0Fu);
2158
        //printf("temd: %d\n", temperature);
2159
        printf("tota: %x\n", temp32);
2160
        printf("tota: %d\n", temp32);
2161
 
2162
        proto->data += (temp32 << 16);
2163
 
2164
 
2165
        //Add channel information
2166
        proto->data += ((uint64_t)nibbleSwap[(uint8_t)( ((rawbitsTemp >> 52 ) & 0xF))]) << 46;
2167
        printf("chan: %d\n", nibbleSwap[(uint8_t)( ((rawbitsTemp >> 52 ) & 0xF))]);
2168
 
2169
        //Add battery information
2170
        proto->data += ((uint64_t)(nibbleSwap[(uint8_t)( ((rawbitsTemp >> 40 ) & 0xF))])&0x1) << 45;
2171
        printf("bat : %d\n", ((nibbleSwap[(uint8_t)( ((rawbitsTemp >> 40 ) & 0xF))])&0x1));
2172
 
2173
        //Add rolling code information
2174
        i = (uint8_t)((rawbitsTemp >> 44 ) & 0xFF);
2175
        i = (uint8_t)nibbleSwap[i & 0xF] + ((uint8_t)(nibbleSwap[(i>>4) & 0xF]<<4)&0xf0);
2176
        i = i & 0x1F;
2177
        proto->data += ((uint64_t)(i)) << 40;
2178
        printf("roll : %d\n", i);
2179
 
2180
 
2181
        /* ----------- Data order proto-data ------
2182
        * cc bb bb bb aa aa
2183
        * a   = Rain in 0.01 inches per hour
2184
        * b   = Total Rain in 0.001 inches
2185
        * cc   = 0xddefffff
2186
        *   dd = Channel
2187
        *   e  = Battery low flag
2188
        *   fffff = Lower part of rolling code
2189
        * -----------------------------*/
2190
 
2191
        printf("done: %x %x %x %x\n", (uint16_t)(proto->data>>48), (uint16_t)(proto->data>>32), (uint16_t)(proto->data>>16), (uint16_t)proto->data);
2192
        proto->protocol=CAN_MODULE_ENUM_PHYSICAL_IR_PROTOCOL_OREGONRAIN;
2193
        proto->timeout=IR_OREGON_TIMEOUT;
2194
        return IR_OK;
2195
        break;
2196
 
2197
      case 0x1994:
2198
      case 0x1984:
2199
       /* ----------- Data order rawbitsTemp ------
2200
        * a? ?b bb cc cd ee f
2201
        * fe ed x? ?c cc aa a
2202
        * x   = Direction (0-F) steps of 22.5 degrees
2203
        * ccc = Temperature in BCD celcius
2204
        * ccc = Temperature in BCD celcius
2205
        * d   = 0x01 bat low, 0x00 bat OK
2206
        * ee  = Rolling code, random value each time batteries is inserted
2207
        * f   =  Channel
2208
        * -----------------------------*/
2209
        printf("begi: %x %x %x %x\n", (uint16_t)(rawbitsTemp>>48), (uint16_t)(rawbitsTemp>>32), (uint16_t)(rawbitsTemp>>16), (uint16_t)rawbitsTemp);
2210
 
2211
        //Convert average wind to decimal from BCD
2212
        temp = (uint16_t)( (rawbitsTemp & 0xFFF ));
2213
        //printf("w_av: %x\n", temp);
2214
        temp = (uint16_t)nibbleSwap[temp & 0xF] + ((uint16_t)(nibbleSwap[(temp>>4) & 0xF]<<4)&0xf0) + ((uint16_t)(nibbleSwap[(temp>>8) & 0xF]<<8)&0xf0);
2215
        //printf("humi: %x\n", temp);
2216
        temp = ((temp>>8) & 0x0Fu)*100 +((temp>>4) & 0x0Fu)*10 + (temp & 0x0Fu);
2217
        proto->data = temp; // wind average
2218
 
2219
        //Convert current wind to decimal from BCD
2220
        temp = (uint16_t)( ((rawbitsTemp >> 12) & 0xFFF ));
2221
        //printf("w_av: %x\n", temp);
2222
        temp = (uint16_t)nibbleSwap[temp & 0xF] + ((uint16_t)(nibbleSwap[(temp>>4) & 0xF]<<4)&0xf0) + ((uint16_t)(nibbleSwap[(temp>>8) & 0xF]<<8)&0xf0);
2223
        //printf("humi: %x\n", temp);
2224
        temp = ((temp>>8) & 0x0Fu)*100 +((temp>>4) & 0x0Fu)*10 + (temp & 0x0Fu);
2225
        proto->data += (temp << 12) & 0xFFF000; // wind average
2226
 
2227
        //store direction
2228
        i = (uint8_t)( ((rawbitsTemp >> 32) & 0xF ));
2229
        proto->data += (uint32_t)i << 24;
2230
 
2231
        //Add channel information
2232
        proto->data += ((uint64_t)nibbleSwap[(uint8_t)( ((rawbitsTemp >> 48 ) & 0xF))]) << 46;
2233
        //printf("chan: %d\n", nibbleSwap[(uint8_t)( ((rawbitsTemp >> 36 ) & 0xF))]);
2234
 
2235
        //Add battery information
2236
        proto->data += ((uint64_t)(nibbleSwap[(uint8_t)( ((rawbitsTemp >> 36 ) & 0xF))])&0x1) << 45;
2237
        //printf("bat : %d\n", ((nibbleSwap[(uint8_t)( ((rawbitsTemp >> 24 ) & 0xF))])&0x1));
2238
 
2239
        //Add rolling code information
2240
        i = (uint8_t)((rawbitsTemp >> 36 ) & 0xFF);
2241
        i = (uint8_t)nibbleSwap[i & 0xF] + ((uint8_t)(nibbleSwap[(i>>4) & 0xF]<<4)&0xf0);
2242
        i = i & 0x1F;
2243
        proto->data += ((uint64_t)(i)) << 40;
2244
        //printf("roll : %d\n", i);
2245
 
2246
 
2247
        /* ----------- Data order proto-data ------
2248
        * cc 00 0d bb ba aa
2249
        * aaa  = wind speed average (in 0.1m/s)
2250
        * bbb  = wind speed current (in 0.1m/s)
2251
        * d    = Direction in 22.5 degrees
2252
        * cc   = 0xddefffff
2253
        *   dd = Channel
2254
        *   e  = Battery low flag
2255
        *   fffff = Lower part of rolling code
2256
        * -----------------------------*/
2257
 
2258
        //printf("done: %x %x %x %x\n", (uint16_t)(proto->data>>48), (uint16_t)(proto->data>>32), (uint16_t)(proto->data>>16), (uint16_t)proto->data);
2259
        proto->protocol=CAN_MODULE_ENUM_PHYSICAL_IR_PROTOCOL_OREGONWIND;
2260
        proto->timeout=IR_OREGON_TIMEOUT;
2261
        return IR_OK;
2262
        break;
2263
 
2264
      default:
2265
        return IR_NOT_CORRECT_DATA;
2266
    }
2267
 
2268
 
2269
#else
2270
    return IR_NOT_CORRECT_DATA;
2271
#endif
2272
}
2273
#endif