Subversion Repositories HomeAutomation

Rev

Blame | Last modification | View Log | SVN | RSS feed

  1. #include "protocols.h"
  2.  
  3. int8_t parseProtocol(const uint16_t *buf, uint8_t len, Ir_Protocol_Data_t *proto) {
  4.     /* Try all protocols in order. */
  5. #if (IR_PROTOCOLS_USE_SIRC)
  6.     if (parseSIRC(buf, len, proto)) return IR_OK;
  7. #endif
  8. #if (IR_PROTOCOLS_USE_RC5)
  9.     if (parseRC5(buf, len, proto)) return IR_OK;
  10. #endif
  11. #if (IR_PROTOCOLS_USE_SHARP)
  12.     if (parseSharp(buf, len, proto)) return IR_OK;
  13. #endif
  14. #if (IR_PROTOCOLS_USE_NEC)
  15.     if (parseNEC(buf, len, proto)) return IR_OK;
  16. #endif
  17. #if (IR_PROTOCOLS_USE_SAMSUNG)
  18.     if (parseSamsung(buf, len, proto)) return IR_OK;
  19. #endif
  20.     /* No protocol matched. */
  21.     return IR_NOT_CORRECT_DATA;
  22. }
  23.  
  24. int8_t parseHash(const uint16_t *buf, uint8_t len, Ir_Protocol_Data_t *proto) {
  25.     //TODO: Transform the buffer in some clever way to a 32 bit word. */
  26.     proto->protocol = IR_PROTO_HASH;
  27.     proto->timeout = 0;
  28.     proto->data = 0;
  29. }
  30.  
  31. int8_t expandProtocol(uint16_t *buf, uint8_t len, const Ir_Protocol_Data_t *proto) {
  32.     /* Call the expand function for the specified protocol. */
  33.     switch (proto->protocol) {
  34.     case IR_PROTO_SIRC:
  35.         return expandSIRC(buf, len, proto);
  36.     case IR_PROTO_RC5:
  37.         return expandRC5(buf, len, proto);
  38.     case IR_PROTO_SHARP:
  39.         return expandSharp(buf, len, proto);
  40.     case IR_PROTO_NEC:
  41.         return expandNEC(buf, len, proto);
  42.     case IR_PROTO_SAMSUNG:
  43.         return expandSamsung(buf, len, proto);
  44.     }
  45.     /* Invalid protocol specified. */
  46.     return IR_NOT_CORRECT_DATA;
  47. }
  48.  
  49. #if (IR_PROTOCOLS_USE_SIRC)
  50. /**
  51.  * Test data on SIRC protocol, 12-bit version
  52.  * http://www.sbprojects.com/knowledge/ir/sirc.htm
  53.  *
  54.  * @param address
  55.  *      Pointer to store the address of the received data
  56.  * @param command
  57.  *      Pointer to store the command of the received data
  58.  * @return
  59.  *      IR_OK if data parsed successfully, one of several errormessages if not
  60.  */
  61. int8_t parseSIRC(const uint16_t *buf, uint8_t len, Ir_Protocol_Data_t *proto) {
  62.     /* parse buf[], max is len */
  63.  
  64.     /* check if we have correct amount of data */
  65.     if (len != 25) {
  66.         return IR_NOT_CORRECT_DATA;
  67.     }
  68.    
  69.     /* check startbit */
  70.     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) {
  71.         return IR_NOT_CORRECT_DATA;
  72.     }
  73.    
  74.     uint16_t rawbits=0;
  75.    
  76.     for (uint8_t i = 1; i < len; i++) {
  77.         if ((i&1) == 1) {       /* if odd, ir-pause */
  78.             /* check length of pause between bits */
  79.             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) {
  80.                 return IR_NOT_CORRECT_DATA;
  81.             }
  82.         } else {            /* if even, ir-bit */
  83.             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) {
  84.                 /* write a one */
  85.                 rawbits |= 1<<((i-2)>>1);
  86.             } 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) {
  87.                 /* do nothing, a zero is already in rawbits */
  88.             } else {
  89.                 return IR_NOT_CORRECT_DATA;
  90.             }
  91.         }
  92.     }
  93.    
  94.     proto->protocol = IR_PROTO_SIRC;
  95.     proto->timeout = IR_SIRC_REPETITION;
  96.     proto->data = rawbits; //TODO: Should some other mapping be used?
  97.    
  98.     return IR_OK;
  99. }
  100.  
  101. int8_t expandSIRC(uint16_t *buf, uint8_t len, const Ir_Protocol_Data_t *proto) {
  102.     //TODO: Implement this function.
  103.     return IR_NOT_CORRECT_DATA;
  104. }
  105. #endif
  106.  
  107. #if (IR_PROTOCOLS_USE_RC5)
  108. /**
  109.  * Test data on RC5 protocol
  110.  * http://www.sbprojects.com/knowledge/ir/rc5.htm
  111.  *
  112.  * @param address
  113.  *      Pointer to store the address of the received data
  114.  * @param command
  115.  *      Pointer to store the command of the received data
  116.  * @return
  117.  *      IR_OK if data parsed successfully, one of several errormessages if not
  118.  */
  119. int8_t parseRC5(const uint16_t *buf, uint8_t len, Ir_Protocol_Data_t *proto) {
  120.     uint8_t halfbitscnt = 1;
  121.     uint16_t rawbits = 0;
  122.    
  123.     for (uint8_t i = 0; i<len; i++) {
  124.         //halfbitscnt&1==1 in the middle of bits
  125.         //i&1==0 positive flank
  126.  
  127.         if ((halfbitscnt&1)==1 && (i&1)==0) {       /* in the middle of bit AND a positve flank */
  128.             rawbits |= (1<<(13-(halfbitscnt>>1)));
  129.         }
  130.        
  131.         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) {
  132.             halfbitscnt += 1;
  133.         } 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) {
  134.             halfbitscnt += 2;
  135.         } else {
  136.             return IR_NOT_CORRECT_DATA;
  137.         }
  138.        
  139.     }
  140.  
  141.     //TODO: Fix this parser to use the proto struct instead.
  142.     *command = ((uint8_t)rawbits&0x3f);
  143.     *address = ((uint8_t)(rawbits>>6)&0x7f);   
  144.  
  145.     //support RC5-extended by putting the inversion of startbit 2 as the 7th commandbit
  146.     *command |= (~(*address) & 0x40);
  147.     *address &= 0x1f;       //remove togglebit and both startbits from address
  148.    
  149.     return IR_OK;
  150. }
  151.  
  152. int8_t expandRC5(uint16_t *buf, uint8_t len, const Ir_Protocol_Data_t *proto) {
  153.     //TODO: Implement this function.
  154.     return IR_NOT_CORRECT_DATA;
  155. }
  156. #endif
  157.  
  158. #if (IR_PROTOCOLS_USE_SHARP)
  159. /**
  160.  * Test data on SHARP protocol
  161.  * http://www.sbprojects.com/knowledge/ir/sharp.htm
  162.  *
  163.  * @param address
  164.  *      Pointer to store the address of the received data
  165.  * @param command
  166.  *      Pointer to store the command of the received data
  167.  * @return
  168.  *      IR_OK if data parsed successfully, one of several errormessages if not
  169.  */
  170. int8_t parseSharp(const uint16_t *buf, uint8_t len, Ir_Protocol_Data_t *proto) {
  171.     /* parse buf[], max is len */
  172.  
  173.     /* check if we have correct amount of data */
  174.     if (len != 31) {
  175.         return IR_NOT_CORRECT_DATA;
  176.     }
  177.    
  178.     uint16_t rawbits=0;
  179.    
  180.     for (uint8_t i = 1; i < len; i++) {
  181.         if ((i&1) == 1) {       /* if odd, ir-pause */
  182.             /* check length of pause between bits */
  183.             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) {
  184.                 /* write a one */
  185.                 rawbits |= 1<<((i-1)>>1);
  186.             } 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) {
  187.                 /* do nothing, a zero is already in rawbits */
  188.             } else {
  189.                 return IR_NOT_CORRECT_DATA;
  190.             }
  191.         } else {            /* if even, ir-bit */
  192.             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) {
  193.                 return IR_NOT_CORRECT_DATA;
  194.             }
  195.         }
  196.     }
  197.    
  198.     //TODO: Fix this parser to use the proto struct instead.
  199.     *command = ((uint8_t)(rawbits>>5)&0xff);
  200.     *address = ((uint8_t)rawbits&0x1f);
  201.    
  202.     return IR_OK;
  203. }
  204.  
  205. int8_t expandSharp(uint16_t *buf, uint8_t len, const Ir_Protocol_Data_t *proto) {
  206.     //TODO: Implement this function.
  207.     return IR_NOT_CORRECT_DATA;
  208. }
  209. #endif
  210.  
  211. #if (IR_PROTOCOLS_USE_NEC)
  212. /**
  213.  * Test data on NEC protocol
  214.  * http://www.sbprojects.com/knowledge/ir/nec.htm
  215.  *
  216.  * @param address
  217.  *      Pointer to store the address of the received data
  218.  * @param command
  219.  *      Pointer to store the command of the received data
  220.  * @return
  221.  *      IR_OK if data parsed successfully, one of several errormessages if not
  222.  */
  223. int8_t parseNEC(const uint16_t *buf, uint8_t len, Ir_Protocol_Data_t *proto) {
  224.     /* parse buf[], max is len */
  225.  
  226.     /* check if we have correct amount of data */
  227.     if (len != 67) {
  228.         return IR_NOT_CORRECT_DATA;
  229.     }
  230.    
  231.     /* check startbit */
  232.     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) {
  233.         return IR_NOT_CORRECT_DATA;
  234.     }
  235.  
  236.     /* check pause after startbit */
  237.     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) {
  238.         return IR_NOT_CORRECT_DATA;
  239.     }
  240.  
  241.     //TODO: Fix this parser to use the proto struct instead. Do not write to the struct unless IR_OK is returned, use temp variables.
  242.     *command = 0;
  243.     *address = 0;
  244.    
  245.     for (uint8_t i = 3; i < len; i++) {
  246.         if ((i&1) == 1) {       /* if odd, ir-pause */
  247.             /* check length of pause between bits */
  248.             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) {
  249.                 if (i>2 && i<18) {
  250.                     /* write a one */
  251.                     *address |= 1<<((i-3)>>1);
  252.                 }
  253.                 if (i>34 && i<50) {
  254.                     /* write a one */
  255.                     *command |= 1<<((i-35)>>1);
  256.                 }
  257.             } 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) {
  258.                 /* do nothing, a zero is already in rawbits */
  259.             } else {
  260.                 return IR_NOT_CORRECT_DATA;
  261.             }
  262.         } else {            /* if even, ir-bit */
  263.             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) {
  264.                 return IR_NOT_CORRECT_DATA;
  265.             }
  266.         }
  267.     }
  268.    
  269.     return IR_OK;
  270. }
  271.  
  272. int8_t expandNEC(uint16_t *buf, uint8_t len, const Ir_Protocol_Data_t *proto) {
  273.     //TODO: Implement this function.
  274.     return IR_NOT_CORRECT_DATA;
  275. }
  276. #endif
  277.  
  278. #if (IR_PROTOCOLS_USE_SAMSUNG)
  279. /**
  280.  * Test data on Samsung protocol
  281.  * Very much like NEC, different start bit/pause lengths etc.
  282.  * http://www.sbprojects.com/knowledge/ir/nec.htm
  283.  *
  284.  * @param address
  285.  *      Pointer to store the address of the received data
  286.  * @param command
  287.  *      Pointer to store the command of the received data
  288.  * @return
  289.  *      IR_OK if data parsed successfully, one of several errormessages if not
  290.  */
  291. int8_t parseSamsung(const uint16_t *buf, uint8_t len, Ir_Protocol_Data_t *proto) {
  292.     /* parse buf[], max is len */
  293.  
  294.     /* check if we have correct amount of data */
  295.     if (len != 67) {
  296.         return IR_NOT_CORRECT_DATA;
  297.     }
  298.    
  299.     /* check startbit */
  300.     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) {
  301.         return IR_NOT_CORRECT_DATA;
  302.     }
  303.  
  304.     /* check pause after startbit */
  305.     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) {
  306.         return IR_NOT_CORRECT_DATA;
  307.     }
  308.  
  309.     //TODO: Fix this parser to use the proto struct instead. Do not write to the struct unless IR_OK is returned, use temp variables.
  310.     *command = 0;
  311.     *address = 0;
  312.    
  313.     for (uint8_t i = 3; i < len; i++) {
  314.         if ((i&1) == 1) {       /* if odd, ir-pause */
  315.             /* check length of pause between bits */
  316.             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) {
  317.                 if (i>2 && i<18) {
  318.                     /* write a one */
  319.                     *address |= 1<<((i-3)>>1);
  320.                 }
  321.                 if (i>34 && i<50) {
  322.                     /* write a one */
  323.                     *command |= 1<<((i-35)>>1);
  324.                 }
  325.             } 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) {
  326.                 /* do nothing, a zero is already in rawbits */
  327.             } else {
  328.                 return IR_NOT_CORRECT_DATA;
  329.             }
  330.         } else {            /* if even, ir-bit */
  331.             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) {
  332.                 return IR_NOT_CORRECT_DATA;
  333.             }
  334.         }
  335.     }
  336.    
  337.     return IR_OK;
  338. }
  339.  
  340. int8_t expandSamsung(uint16_t *buf, uint8_t len, const Ir_Protocol_Data_t *proto) {
  341.     //TODO: Implement this function.
  342.     return IR_NOT_CORRECT_DATA;
  343. }
  344. #endif
  345.  
  346.