Subversion Repositories HomeAutomation

Rev

Rev 2260 | 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_T3)
  66.     if (parseVikingT3(buf, len, index, proto)==IR_OK) return IR_OK;
  67. #endif
  68. #if (IR_PROTOCOLS_USE_VIKING_STEAK)
  69.     res = parseVikingSteak(buf, len, index, proto);
  70.     if (res!=IR_NOT_CORRECT_DATA) return res;
  71. #endif
  72. #if (IR_PROTOCOLS_USE_RUBICSON)
  73.     res = parseRubicson(buf, len, index, proto);
  74.     if (res!=IR_NOT_CORRECT_DATA) return res;
  75. #endif
  76. #if (IR_PROTOCOLS_USE_OREGON)
  77.    
  78.     res = parseOregon(buf, len, index, proto);
  79.     gpio_clr_pin(EXP_K);
  80.     gpio_clr_pin(EXP_L);
  81.     gpio_clr_pin(EXP_M);
  82.     gpio_clr_pin(EXP_N);
  83.     if (res!=IR_NOT_CORRECT_DATA) return res;
  84. #endif     
  85.    
  86.     /* No protocol matched. */
  87.     proto->protocol = IR_PROTO_UNKNOWN;
  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;
  94.     proto->timeout = 200;
  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) {
  103.     case CAN_MODULE_ENUM_PHYSICAL_IR_PROTOCOL_SIRC:
  104.         return expandSIRC(buf, len, proto);
  105.     case CAN_MODULE_ENUM_PHYSICAL_IR_PROTOCOL_RC5:
  106.         return expandRC5(buf, len, proto);
  107.     case CAN_MODULE_ENUM_PHYSICAL_IR_PROTOCOL_SHARP:
  108.         return expandSharp(buf, len, proto);
  109.     case CAN_MODULE_ENUM_PHYSICAL_IR_PROTOCOL_NEC:
  110.         return expandNEC(buf, len, proto);
  111.     case CAN_MODULE_ENUM_PHYSICAL_IR_PROTOCOL_SAMSUNG:
  112.         return expandSamsung(buf, len, proto);
  113.     case CAN_MODULE_ENUM_PHYSICAL_IR_PROTOCOL_MARANTZ:
  114.         return expandMarantz(buf, len, proto);
  115.     case CAN_MODULE_ENUM_PHYSICAL_IR_PROTOCOL_PANASONIC:
  116.         return expandPanasonic(buf, len, proto);
  117.     case CAN_MODULE_ENUM_PHYSICAL_IR_PROTOCOL_SKY:
  118.         return expandSky(buf, len, proto);
  119.     case CAN_MODULE_ENUM_PHYSICAL_IR_PROTOCOL_IROBOT:
  120.         return expandiRobot(buf, len, proto);
  121.     case CAN_MODULE_ENUM_PHYSICAL_IR_PROTOCOL_NEXA2:
  122.         return expandNexa2(buf, len, proto);
  123.     case CAN_MODULE_ENUM_PHYSICAL_IR_PROTOCOL_NEXA:
  124.         return expandNexa1(buf, len, proto);
  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
  134.  * http://picprojects.org.uk/projects/sirc/sonysirc.pdf
  135.  *
  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
  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.  
  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) {
  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.    
  182.     proto->protocol = CAN_MODULE_ENUM_PHYSICAL_IR_PROTOCOL_SIRC;
  183.     proto->timeout = IR_SIRC_TIMEOUT;
  184.     proto->data = rawbits;
  185.    
  186.     return IR_OK;
  187. }
  188. #endif
  189.  
  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.  */
  203. int8_t expandSIRC(uint16_t *buf, uint8_t *len, Ir_Protocol_Data_t *proto) {
  204.     buf[0] = IR_SIRC_ST_BIT;
  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;
  230. }
  231.  
  232.  
  233. #if (IR_PROTOCOLS_USE_RC5)
  234. /**
  235.  * Test data on RC5 protocol
  236.  * http://www.sbprojects.com/knowledge/ir/rc5.htm
  237.  *
  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
  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.  
  269.     proto->protocol=CAN_MODULE_ENUM_PHYSICAL_IR_PROTOCOL_RC5;
  270.     proto->timeout=IR_RC5_TIMEOUT;
  271.     //support RC5-extended keeping second startbit
  272.     //remove togglebit
  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);
  275.  
  276.    
  277.     return IR_OK;
  278. }
  279. #endif
  280.  
  281. /**
  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. /**
  287.  * Expand data from RC5 protocol
  288.  * http://www.sbprojects.com/knowledge/ir/rc5.htm
  289.  *
  290.  * One is defined as low then high
  291.  * Zero is defined as high then low
  292.  *
  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.  */
  302. int8_t expandRC5(uint16_t *buf, uint8_t *len, Ir_Protocol_Data_t *proto) {
  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.    
  308.     uint8_t previousBit;
  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
  314.    
  315.     // Bit = 1
  316.     buf[1] = IR_RC5_HALF_BIT;
  317.     buf[2] = IR_RC5_HALF_BIT;//second start bit
  318.  
  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
  324.     } else {
  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
  331.     }
  332.     //Invert the toggle for next time
  333.     rc5_toggle=!rc5_toggle & 1;
  334.    
  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;
  345.         }
  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;
  357.         }
  358.     }
  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.     }
  367.    
  368.     proto->modfreq=IR_RC5_F_MOD;
  369.     proto->timeout=IR_RC5_TIMEOUT;
  370.     proto->repeats=IR_RC5_REPS;
  371.     return IR_OK;
  372. }
  373.  
  374.  
  375. #if (IR_PROTOCOLS_USE_SHARP)
  376. /**
  377.  * Test data on SHARP protocol
  378.  * http://www.sbprojects.com/knowledge/ir/sharp.htm
  379.  *
  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
  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.    
  417.     proto->protocol=CAN_MODULE_ENUM_PHYSICAL_IR_PROTOCOL_SHARP;
  418.     proto->timeout=IR_SHARP_TIMEOUT;
  419.     proto->data=rawbits;
  420.     return IR_OK;
  421. }
  422. #endif
  423.  
  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.  */
  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.  
  442.  
  443. #if (IR_PROTOCOLS_USE_NEC)
  444. /**
  445.  * Test data on NEC protocol
  446.  * http://www.sbprojects.com/knowledge/ir/nec.htm
  447.  *
  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
  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.  
  475.     uint32_t rawbits = 0;
  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 */
  482.                 rawbits |= 1UL<<((i-3)>>1);
  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.  
  495.     proto->protocol=CAN_MODULE_ENUM_PHYSICAL_IR_PROTOCOL_NEC;
  496.     proto->timeout=IR_NEC_TIMEOUT;
  497.     proto->data=rawbits;   
  498.     return IR_OK;
  499. }
  500. #endif
  501.  
  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.  */
  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;
  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;
  532.             }
  533.         }
  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;
  540.     }
  541.     proto->modfreq=IR_NEC_F_MOD;
  542.     proto->repeats=IR_NEC_REPS;
  543.     return IR_OK;
  544. }
  545.  
  546.  
  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.  *
  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
  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.  
  580.     uint32_t rawbits = 0;
  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 */
  587.                 rawbits |= 1UL<<((i-3)>>1);
  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.    
  600.     proto->protocol=CAN_MODULE_ENUM_PHYSICAL_IR_PROTOCOL_SAMSUNG;
  601.     proto->timeout=IR_SAMS_TIMEOUT;
  602.     proto->data=rawbits;   
  603.     return IR_OK;
  604. }
  605. #endif
  606.  
  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.  */
  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.    
  640.     proto->modfreq=IR_SAMS_F_MOD;
  641.     proto->timeout=IR_SAMS_TIMEOUT;
  642.     proto->repeats=IR_SAMS_REPS;
  643.     return IR_OK;
  644. }
  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.        
  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) {
  675.             halfbitscnt += 1;
  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) {
  677.             halfbitscnt += 2;
  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) {
  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.    
  686.     proto->protocol=CAN_MODULE_ENUM_PHYSICAL_IR_PROTOCOL_MARANTZ;
  687.     proto->timeout=IR_MARANTZ_TIMEOUT;
  688.     proto->data = rawbits&0x0001ffff;
  689.    
  690.     return IR_OK;
  691. }
  692. #endif
  693.  
  694. /**
  695.  * Expand data from Marantz. Written by Martin Nordin
  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 */
  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
  714.     //TODO: Toggle bit should be better, not hard-coded
  715.     buf[3] = IR_MARANTZ_HALF_BIT;
  716.     buf[4] = IR_MARANTZ_HALF_BIT;//toggle bit
  717.     *len=5;
  718.     previousBit = 1;
  719.    
  720.     tempdata = (uint32_t)(proto->data)<<14;
  721.        
  722.     for(uint8_t i = 0; i < 17; i++) {
  723.         tempdata = (uint32_t)tempdata<<1;
  724.  
  725.         if (((uint32_t)tempdata>>31)==1){
  726.             if (previousBit == 1){//11
  727.                 buf[*len] = IR_MARANTZ_HALF_BIT;
  728.                 buf[*len+1] = IR_MARANTZ_HALF_BIT;
  729.                 *len = *len + 2;
  730.             } else {//01
  731.                 buf[*len-1] = IR_MARANTZ_BIT;
  732.                 buf[*len] = IR_MARANTZ_HALF_BIT;
  733.                 *len = *len + 1;
  734.             }
  735.             previousBit = 1;
  736.         } else {
  737.             if (previousBit == 1){//10
  738.                 buf[*len-1] = IR_MARANTZ_BIT;
  739.                 buf[*len] = IR_MARANTZ_HALF_BIT;
  740.                 *len = *len + 1;
  741.             } else {//00
  742.                 buf[*len] = IR_MARANTZ_HALF_BIT;
  743.                 if (i==4){
  744.                     buf[*len+1] = IR_MARANTZ_HALF_BIT*5;
  745.                 } else {
  746.                     buf[*len+1] = IR_MARANTZ_HALF_BIT;
  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.  
  759.     proto->modfreq=IR_MARANTZ_F_MOD;
  760.     proto->timeout=IR_MARANTZ_TIMEOUT;
  761.     proto->repeats=IR_MARANTZ_REPS;
  762.     return IR_OK;
  763. }
  764.  
  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 */
  780.  
  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.    
  817.     proto->protocol=CAN_MODULE_ENUM_PHYSICAL_IR_PROTOCOL_PANASONIC;
  818.     proto->timeout=IR_PANA_TIMEOUT;
  819.     proto->data=rawbits;   
  820.     return IR_OK;
  821. }
  822. #endif
  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.    
  870.     proto->modfreq=IR_PANA_F_MOD;
  871.     proto->timeout=IR_PANA_TIMEOUT;
  872.     proto->repeats=IR_PANA_REPS;
  873.     return IR_OK;
  874. }
  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.    
  965.     proto->protocol = CAN_MODULE_ENUM_PHYSICAL_IR_PROTOCOL_SKY;
  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.  
  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];
  1115.     proto->data = temp;
  1116.     //proto->data = temp << 8;
  1117.     //proto->data += 0x52;
  1118.     for (uint8_t i = 0; i < 16; i++) {
  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.    
  1130.     *len = 15;
  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.  
  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
  1142.  * http://pastebin.com/PJX3bRAs
  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.  */
  1153.  
  1154. int8_t parseNexa2(const uint16_t *buf, uint8_t len, uint8_t index, Ir_Protocol_Data_t *proto)
  1155. {
  1156.     /* check if we have correct amount of data */
  1157.     if (len < 132) {
  1158.         return IR_NOT_CORRECT_DATA;
  1159.     }
  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
  1169.         return IR_NOT_CORRECT_DATA;
  1170.     }
  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
  1179.         return IR_NOT_CORRECT_DATA;
  1180.     }
  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
  1189.         return IR_NOT_CORRECT_DATA;
  1190.     }
  1191.  
  1192.     /* Incoming data could actually be longer than 32bits when a dimming command is received */
  1193.     uint64_t rawbitsTemp = 0;
  1194.     uint8_t bitCounter = 0;
  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
  1204.         if ((i&1) == 0) {       /* if even, data */
  1205.             /* check length of transmit pulse */
  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)) {
  1207.                 /* write a one */
  1208.                 rawbitsTemp |= (1UL)<<(bitCounter++);
  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)) {
  1210.                 /* do nothing, a zero is already in rawbits */
  1211.                 bitCounter++;
  1212.             } else {
  1213.                 return IR_NOT_CORRECT_DATA;
  1214.             }
  1215.             i+=2;   // skip every other bit, implement check here in the future
  1216.         } else {            /* if odd, no data */
  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)) {
  1218.                 return IR_NOT_CORRECT_DATA;
  1219.             }
  1220.         }
  1221.     }
  1222.    
  1223.     proto->protocol=CAN_MODULE_ENUM_PHYSICAL_IR_PROTOCOL_NEXA2;
  1224.     proto->timeout=IR_NEXA2_TIMEOUT;
  1225.     proto->data=rawbitsTemp;
  1226.     return IR_OK;
  1227. }
  1228. #endif
  1229.  
  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) {
  1244.     buf[0] = IR_NEXA2_HIGH;
  1245.     buf[1] = IR_NEXA2_START2;
  1246.  
  1247.     uint64_t tempshift = proto->data;
  1248.  
  1249.     /* No dimming */
  1250.     *len = 131;
  1251.     uint8_t dimming = 0;
  1252.     /* If most significant bit is set, then dimming should be sent */
  1253.     if ((uint32_t)(tempshift>> 32)&0x80)
  1254.     {
  1255.         /* Dimming */
  1256.         *len = 147;
  1257.         dimming=1;
  1258.     }
  1259.    
  1260.     for (uint8_t i = 2; i < *len; i+=4)
  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.     }
  1273.    
  1274.     if (dimming)
  1275.     {
  1276.         buf[111] = IR_NEXA2_LOW_ONE;
  1277.         buf[113] = IR_NEXA2_LOW_ONE;
  1278.     }
  1279.     proto->modfreq=IR_NEXA2_F_MOD;
  1280.     proto->timeout=IR_NEXA2_START1/1000;
  1281.     proto->repeats=IR_NEXA2_REPS;
  1282.     return IR_OK;
  1283. }
  1284.  
  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.  */
  1300. int8_t parseNexa1(const uint16_t *buf, uint8_t len, uint8_t index, Ir_Protocol_Data_t *proto) {
  1301.     /* parse buf[], max is len */
  1302.  
  1303.     uint8_t i;
  1304.     /* check if we have correct amount of data */
  1305.     if (len < 50) {
  1306.         return IR_NOT_CORRECT_DATA;
  1307.     }
  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
  1316.         return IR_NOT_CORRECT_DATA;
  1317.     }
  1318.  
  1319.     uint32_t rawbitsTemp = 0;
  1320.     uint8_t bitCounter = 0;
  1321.  
  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
  1332.         /* Check if '0' bit */
  1333.         if (
  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) )
  1338.         {
  1339.             /* write a one */
  1340.             rawbitsTemp |= (1UL)<<(bitCounter++);
  1341.         }
  1342.         /* Check if 'X' bit */
  1343.         else if (
  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) )
  1348.         {
  1349.             /* do nothing, a zero is already in rawbits */
  1350.             bitCounter++;
  1351.         }
  1352.         else
  1353.         {
  1354.             return IR_NOT_CORRECT_DATA;
  1355.         }
  1356.     }
  1357.  
  1358.     if (rawbitsTemp==0)
  1359.     {
  1360.         /* Bogus RF data */
  1361.         return IR_NOT_CORRECT_DATA;
  1362.     }
  1363.    
  1364.     proto->protocol=CAN_MODULE_ENUM_PHYSICAL_IR_PROTOCOL_NEXA;
  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) {
  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;
  1412.    
  1413.     proto->modfreq = IR_NEXA1_F_MOD;
  1414.     proto->timeout = IR_NEXA1_START/1000;
  1415.     proto->repeats = IR_NEXA1_REPS;
  1416.     return IR_OK;  
  1417. }
  1418.  
  1419.  
  1420. #if (IR_PROTOCOLS_USE_VIKING)
  1421. /**
  1422.  * Test data on Viking sensor protocol
  1423.  * This is protocol type 4 (temperature with sign and one more byte)
  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. {
  1438. #if IR_RX_CONTINUOUS_MODE==1
  1439.     /* check if we have correct amount of data */
  1440.     if (len < 90) {
  1441.         return IR_NOT_CORRECT_DATA;
  1442.     }
  1443.     uint8_t i, i2;
  1444.     uint64_t rawbitsTemp = 0;//0xffffffffffffffff;
  1445.    
  1446.     for (i = 90; i > 0; i--)
  1447.     {
  1448.         i2=index-i;
  1449.         if (i2>index)
  1450.             i2+=MAX_NR_TIMES;
  1451.  
  1452.         /* Check if correct amount of data have been received */
  1453.         if ((i == 78) && (rawbitsTemp != 0b00001))
  1454.             return IR_NOT_CORRECT_DATA;
  1455.  
  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.  
  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.         }
  1470.         else
  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 */
  1476.                 rawbitsTemp = rawbitsTemp<<1;
  1477.                 rawbitsTemp |= 1;
  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 */
  1482.                 rawbitsTemp = rawbitsTemp<<1;
  1483.             }
  1484.             else
  1485.             {
  1486.                 return IR_NOT_CORRECT_DATA;
  1487.             }
  1488.         }
  1489.     }
  1490.    
  1491.     rawbitsTemp = ~rawbitsTemp;
  1492.     rawbitsTemp = rawbitsTemp&0xFFFFFFFFFF;
  1493.    
  1494.     proto->protocol=CAN_MODULE_ENUM_PHYSICAL_IR_PROTOCOL_VIKING;
  1495.     proto->timeout=0;
  1496.     proto->data=rawbitsTemp;
  1497.  
  1498.     return IR_OK;
  1499. #else
  1500.     return IR_NOT_CORRECT_DATA;
  1501. #endif
  1502. }
  1503. #endif
  1504.  
  1505.  
  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.  
  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 */
  1659.     if (len < 74) {
  1660.         return IR_NOT_CORRECT_DATA;
  1661.     }
  1662.     uint8_t i, i2;
  1663.     uint64_t rawbitsTemp = 0;//0xffffffffffffffff;
  1664.    
  1665.     /* Check start bit condition */
  1666.     i2=index-74;
  1667.     if (i2>index)
  1668.         i2+=MAX_NR_TIMES;
  1669.  
  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))
  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 */
  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))
  1690.             {
  1691.                 return IR_NOT_CORRECT_DATA;
  1692.             }
  1693.         }
  1694.         else
  1695.         {           /* if even, data */
  1696.             /* check length of transmit pulse */
  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))
  1698.             {
  1699.                 /* write a one */
  1700.                 rawbitsTemp = rawbitsTemp<<1;
  1701.                 rawbitsTemp |= 1;
  1702.             }
  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))
  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.    
  1718.     proto->protocol=CAN_MODULE_ENUM_PHYSICAL_IR_PROTOCOL_VIKINGSTEAK;
  1719.     proto->timeout=IR_VIKING_STEAK_TIMEOUT;
  1720.     proto->data=rawbitsTemp;
  1721.  
  1722.     return IR_OK;
  1723. #else
  1724.     return IR_NOT_CORRECT_DATA;
  1725. #endif
  1726. }
  1727. #endif
  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 */
  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))
  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.    
  1808.     proto->protocol=CAN_MODULE_ENUM_PHYSICAL_IR_PROTOCOL_RUBICSON;
  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.  
  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 */
  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
  2274.