Subversion Repositories HomeAutomation

Rev

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