Subversion Repositories HomeAutomation

Rev

Rev 2259 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | SVN | RSS feed

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