Subversion Repositories HomeAutomation

Rev

Rev 617 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | SVN | RSS feed

  1. #include "protocols.h"
  2. #include <avr/io.h>
  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.     return 0;
  31. }
  32.  
  33. int8_t expandProtocol(uint16_t *buf, uint8_t *len, Ir_Protocol_Data_t *proto) {
  34.     /* Call the expand function for the specified protocol. */
  35.     switch (proto->protocol) {
  36.     case IR_PROTO_SIRC:
  37.         return expandSIRC(buf, len, proto);
  38.     case IR_PROTO_RC5:
  39.         return expandRC5(buf, len, proto);
  40.     case IR_PROTO_SHARP:
  41.         return expandSharp(buf, len, proto);
  42.     case IR_PROTO_NEC:
  43.         return expandNEC(buf, len, proto);
  44.     case IR_PROTO_SAMS:
  45.         return expandSamsung(buf, len, proto);
  46.     }
  47.     /* Invalid protocol specified. */
  48.     return IR_NOT_CORRECT_DATA;
  49. }
  50.  
  51. #if (IR_PROTOCOLS_USE_SIRC)
  52. /**
  53.  * Test data on SIRC protocol, 12-bit version
  54.  * http://www.sbprojects.com/knowledge/ir/sirc.htm
  55.  *
  56.  * @param address
  57.  *      Pointer to store the address of the received data
  58.  * @param command
  59.  *      Pointer to store the command of the received data
  60.  * @return
  61.  *      IR_OK if data parsed successfully, one of several errormessages if not
  62.  */
  63. int8_t parseSIRC(const uint16_t *buf, uint8_t len, Ir_Protocol_Data_t *proto) {
  64.     /* parse buf[], max is len */
  65.  
  66.     /* check if we have correct amount of data */
  67.     if (len != 25) {
  68.         return IR_NOT_CORRECT_DATA;
  69.     }
  70.    
  71.     /* check startbit */
  72.     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) {
  73.         return IR_NOT_CORRECT_DATA;
  74.     }
  75.    
  76.     uint16_t rawbits=0;
  77.    
  78.     for (uint8_t i = 1; i < len; i++) {
  79.         if ((i&1) == 1) {       /* if odd, ir-pause */
  80.             /* check length of pause between bits */
  81.             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) {
  82.                 return IR_NOT_CORRECT_DATA;
  83.             }
  84.         } else {            /* if even, ir-bit */
  85.             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) {
  86.                 /* write a one */
  87.                 rawbits |= 1<<((i-2)>>1);
  88.             } 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) {
  89.                 /* do nothing, a zero is already in rawbits */
  90.             } else {
  91.                 return IR_NOT_CORRECT_DATA;
  92.             }
  93.         }
  94.     }
  95.    
  96.     proto->protocol = IR_PROTO_SIRC;
  97.     proto->timeout = IR_SIRC_TIMEOUT;
  98.     proto->data = rawbits; //TODO: Should some other mapping be used?
  99.    
  100.     return IR_OK;
  101. }
  102. #endif
  103.  
  104. int8_t expandSIRC(uint16_t *buf, uint8_t *len, Ir_Protocol_Data_t *proto) {
  105.     //TODO: Implement this function.
  106.     return IR_NOT_CORRECT_DATA;
  107. }
  108.  
  109. #if (IR_PROTOCOLS_USE_RC5)
  110. /**
  111.  * Test data on RC5 protocol
  112.  * http://www.sbprojects.com/knowledge/ir/rc5.htm
  113.  *
  114.  * @param address
  115.  *      Pointer to store the address of the received data
  116.  * @param command
  117.  *      Pointer to store the command of the received data
  118.  * @return
  119.  *      IR_OK if data parsed successfully, one of several errormessages if not
  120.  */
  121. int8_t parseRC5(const uint16_t *buf, uint8_t len, Ir_Protocol_Data_t *proto) {
  122.     uint8_t halfbitscnt = 1;
  123.     uint16_t rawbits = 0;
  124.    
  125.     for (uint8_t i = 0; i<len; i++) {
  126.         //halfbitscnt&1==1 in the middle of bits
  127.         //i&1==0 positive flank
  128.  
  129.         if ((halfbitscnt&1)==1 && (i&1)==0) {       /* in the middle of bit AND a positve flank */
  130.             rawbits |= (1<<(13-(halfbitscnt>>1)));
  131.         }
  132.        
  133.         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) {
  134.             halfbitscnt += 1;
  135.         } 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) {
  136.             halfbitscnt += 2;
  137.         } else {
  138.             return IR_NOT_CORRECT_DATA;
  139.         }
  140.        
  141.     }
  142.  
  143.     proto->protocol=IR_PROTO_RC5;
  144.     proto->timeout=IR_RC5_TIMEOUT;
  145.     //support RC5-extended keeping second startbit
  146.     //remove togglebit
  147.     proto->data = rawbits&0x37ff;
  148.  
  149.    
  150.     return IR_OK;
  151. }
  152. #endif
  153.  
  154. int8_t expandRC5(uint16_t *buf, uint8_t *len, Ir_Protocol_Data_t *proto) {
  155.     //TODO: Implement this function.
  156.     return IR_NOT_CORRECT_DATA;
  157. }
  158.  
  159. #if (IR_PROTOCOLS_USE_SHARP)
  160. /**
  161.  * Test data on SHARP protocol
  162.  * http://www.sbprojects.com/knowledge/ir/sharp.htm
  163.  *
  164.  * @param address
  165.  *      Pointer to store the address of the received data
  166.  * @param command
  167.  *      Pointer to store the command of the received data
  168.  * @return
  169.  *      IR_OK if data parsed successfully, one of several errormessages if not
  170.  */
  171. int8_t parseSharp(const uint16_t *buf, uint8_t len, Ir_Protocol_Data_t *proto) {
  172.     /* parse buf[], max is len */
  173.  
  174.     /* check if we have correct amount of data */
  175.     if (len != 31) {
  176.         return IR_NOT_CORRECT_DATA;
  177.     }
  178.    
  179.     uint16_t rawbits=0;
  180.    
  181.     for (uint8_t i = 1; i < len; i++) {
  182.         if ((i&1) == 1) {       /* if odd, ir-pause */
  183.             /* check length of pause between bits */
  184.             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) {
  185.                 /* write a one */
  186.                 rawbits |= 1<<((i-1)>>1);
  187.             } 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) {
  188.                 /* do nothing, a zero is already in rawbits */
  189.             } else {
  190.                 return IR_NOT_CORRECT_DATA;
  191.             }
  192.         } else {            /* if even, ir-bit */
  193.             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) {
  194.                 return IR_NOT_CORRECT_DATA;
  195.             }
  196.         }
  197.     }
  198.    
  199.     proto->protocol=IR_PROTO_SHARP;
  200.     proto->timeout=IR_SHARP_TIMEOUT;
  201.     proto->data=rawbits;
  202.     return IR_OK;
  203. }
  204. #endif
  205.  
  206. int8_t expandSharp(uint16_t *buf, uint8_t *len, Ir_Protocol_Data_t *proto) {
  207.     //TODO: Implement this function.
  208.     return IR_NOT_CORRECT_DATA;
  209. }
  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.     uint32_t tmpdata = 0;
  242.  
  243.     for (uint8_t i = 3; i < len; i++) {
  244.         if ((i&1) == 1) {       /* if odd, ir-pause */
  245.             /* check length of pause between bits */
  246.             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) {
  247.                 /* write a one */
  248.                 tmpdata |= 1UL<<((i-3)>>1);
  249.             } 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) {
  250.                 /* do nothing, a zero is already in place */
  251.             } else {
  252.                 return IR_NOT_CORRECT_DATA;
  253.             }
  254.         } else {            /* if even, ir-bit */
  255.             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) {
  256.                 return IR_NOT_CORRECT_DATA;
  257.             }
  258.         }
  259.     }
  260.  
  261.     proto->protocol=IR_PROTO_NEC;
  262.     proto->timeout=IR_NEC_TIMEOUT;
  263.     proto->data=tmpdata;   
  264.     return IR_OK;
  265. }
  266. #endif
  267.  
  268. int8_t expandNEC(uint16_t *buf, uint8_t *len, Ir_Protocol_Data_t *proto) {
  269.     /* Set up startbit */
  270.     buf[0] = IR_NEC_ST_BIT;
  271.     buf[1] = IR_NEC_ST_PAUSE;
  272.  
  273.     *len = 67;
  274.     for (uint8_t i = 0; i < 65; i++) {
  275.         if ((i&1) == 1) {       /* if odd, ir-pause */
  276.             if ((proto->data>>(i>>1))&1) {
  277.                 buf[i+2] = IR_NEC_LOW_ONE;
  278.             } else {
  279.                 buf[i+2] = IR_NEC_LOW_ZERO;
  280.             }
  281.         } else {            /* if even, ir-bit */
  282.             buf[i+2] = IR_NEC_HIGH;
  283.         }
  284.     }
  285.    
  286.     proto->modfreq=(((F_CPU/2000)/IR_NEC_F_MOD) -1);
  287.     proto->timeout=IR_NEC_TIMEOUT;
  288.     proto->repeats=IR_NEC_REPS;
  289.     return IR_OK;
  290. }
  291.  
  292. #if (IR_PROTOCOLS_USE_SAMSUNG)
  293. /**
  294.  * Test data on Samsung protocol
  295.  * Very much like NEC, different start bit/pause lengths etc.
  296.  * http://www.sbprojects.com/knowledge/ir/nec.htm
  297.  *
  298.  * @param address
  299.  *      Pointer to store the address of the received data
  300.  * @param command
  301.  *      Pointer to store the command of the received data
  302.  * @return
  303.  *      IR_OK if data parsed successfully, one of several errormessages if not
  304.  */
  305. int8_t parseSamsung(const uint16_t *buf, uint8_t len, Ir_Protocol_Data_t *proto) {
  306.     /* parse buf[], max is len */
  307.  
  308.     /* check if we have correct amount of data */
  309.     if (len != 67) {
  310.         return IR_NOT_CORRECT_DATA;
  311.     }
  312.    
  313.     /* check startbit */
  314.     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) {
  315.         return IR_NOT_CORRECT_DATA;
  316.     }
  317.  
  318.     /* check pause after startbit */
  319.     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) {
  320.         return IR_NOT_CORRECT_DATA;
  321.     }
  322.  
  323.     uint32_t tmpdata = 0;
  324.    
  325.     for (uint8_t i = 3; i < len; i++) {
  326.         if ((i&1) == 1) {       /* if odd, ir-pause */
  327.             /* check length of pause between bits */
  328.             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) {
  329.                 /* write a one */
  330.                 tmpdata |= 1UL<<((i-3)>>1);
  331.             } 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) {
  332.                 /* do nothing, a zero is already in rawbits */
  333.             } else {
  334.                 return IR_NOT_CORRECT_DATA;
  335.             }
  336.         } else {            /* if even, ir-bit */
  337.             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) {
  338.                 return IR_NOT_CORRECT_DATA;
  339.             }
  340.         }
  341.     }
  342.    
  343.     proto->protocol=IR_PROTO_SAMS;
  344.     proto->timeout=IR_SAMS_TIMEOUT;
  345.     proto->data=tmpdata;   
  346.     return IR_OK;
  347. }
  348. #endif
  349.  
  350. int8_t expandSamsung(uint16_t *buf, uint8_t *len, Ir_Protocol_Data_t *proto) {
  351.     /* Set up startbit */
  352.     buf[0] = IR_SAMS_ST_BIT;
  353.     buf[1] = IR_SAMS_ST_PAUSE;
  354.    
  355.     for (uint8_t i = 0; i < 65; i++) {
  356.         if ((i&1) == 1) {       /* if odd, ir-pause */
  357.             if ((proto->data>>(i>>1))&1) {
  358.                 buf[i+2] = IR_SAMS_LOW_ONE;
  359.             } else {
  360.                 buf[i+2] = IR_SAMS_LOW_ZERO;
  361.             }
  362.         } else {                /* if even, ir-bit */
  363.             buf[i+2] = IR_SAMS_HIGH;
  364.         }
  365.     }
  366.    
  367.     *len = 67;
  368.    
  369.     proto->modfreq=(((F_CPU/2000)/IR_SAMS_F_MOD) -1);
  370.     proto->timeout=IR_SAMS_TIMEOUT;
  371.     proto->repeats=IR_SAMS_REPS;
  372.     return IR_OK;
  373. }
  374.