Subversion Repositories HomeAutomation

Rev

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