Subversion Repositories HomeAutomation

Rev

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