Subversion Repositories HomeAutomation

Rev

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