Subversion Repositories HomeAutomation

Rev

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

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