Subversion Repositories HomeAutomation

Rev

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