Subversion Repositories HomeAutomation

Rev

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

  1. /**
  2.  * IR receiver driver.
  3.  *
  4.  * @date    2006-12-10
  5.  *
  6.  * @author  Anders Runeson
  7.  *  
  8.  */
  9.  
  10. /*-----------------------------------------------------------------------------
  11.  * Includes
  12.  *---------------------------------------------------------------------------*/
  13. #include <config.h>
  14. #include <drivers/ir/transceiver/irtransceiver.h>
  15. #include <avr/io.h>
  16. #include <avr/interrupt.h>
  17.  
  18. /*-----------------------------------------------------------------------------
  19.  * Globals
  20.  *---------------------------------------------------------------------------*/
  21. static uint16_t times[MAX_NR_TIMES];            //stores
  22. static uint8_t timesCounter=0;                  //counts the items in Times, always less then MAX_NR_TIMES
  23. static uint8_t timesIndex;                      //selects the pulse width in Times to send
  24. volatile uint8_t data_received;
  25. volatile uint8_t data_transmitted;
  26. uint8_t detect_edge;
  27. uint8_t store;
  28.  
  29. /*-----------------------------------------------------------------------------
  30.  * Prerequisites
  31.  *---------------------------------------------------------------------------*/
  32. #define IR_RX_ACTIVE_LOW    1
  33. #define IR_TX_ACTIVE_LOW    0       //Only 0 is implemented
  34.  
  35.  
  36. #if defined(__AVR_ATmega8__) || defined(__AVR_ATmega16__) || defined(__AVR_ATmega32__)
  37. #define TIMSK1  TIMSK
  38. #define TIFR1   TIFR
  39. #define ICIE1   TICIE1
  40. #endif
  41.  
  42. #define IR_COMPARE_VECTOR       TIMER1_COMPB_vect
  43. #define IR_TIMEOUT_VECTOR       TIMER1_COMPA_vect
  44. #define IR_CAPTURE_VECTOR       TIMER1_CAPT_vect
  45. #define IR_TIMEOUT_REG          OCR1A
  46. #define IR_COMPARE_REG          OCR1B
  47. #define IR_CAPTURE_REG          ICR1
  48. #define IR_COUNT_REG            TCNT1
  49. #define IR_TIMER_INIT()         TCCR1A = 0; \
  50.                                 TCCR1B = (1<<ICNC1)|(2<<CS10);
  51. #define IR_MASK_COMPARE()       TIMSK1 &= ~(1<<OCIE1B);
  52. #define IR_UNMASK_COMPARE()     TIFR1 = (1<<OCF1B); TIMSK1 |= (1<<OCIE1B);
  53. #define IR_MASK_TIMEOUT()       TIMSK1 &= ~(1<<OCIE1A);
  54. #define IR_UNMASK_TIMEOUT()     TIFR1 = (1<<OCF1A); TIMSK1 |= (1<<OCIE1A);
  55. #define IR_MASK_CAPTURE()       TIMSK1 &= ~(1<<ICIE1);
  56. #define IR_UNMASK_CAPTURE()     TIFR1 = (1<<ICF1); TIMSK1 |= (1<<ICIE1);
  57. #define IR_CAPTURE_FALLING()    TCCR1B &= ~(1<<ICES1); \
  58.                                 TIFR1 = (1<<ICF1);
  59. #define IR_CAPTURE_RISING()     TCCR1B |= (1<<ICES1); \
  60.                                 TIFR1 = (1<<ICF1);
  61.  
  62. //TODO: if active low is 0 then make port 5V at LOW
  63. #if IR_TX_ACTIVE_LOW==1
  64. #define IR_OUTP_HIGH()          TCCR0A |= (1<<COM0A0);
  65. #define IR_OUTP_LOW()           TCCR0A &= ~(1<<COM0A0);
  66. #else
  67. #define IR_OUTP_HIGH()          TCCR0A |= (1<<COM0A0);
  68. #define IR_OUTP_LOW()           TCCR0A &= ~(1<<COM0A0);
  69. #endif
  70.  
  71.  
  72. /*-----------------------------------------------------------------------------
  73.  * Interrupt Handlers
  74.  *---------------------------------------------------------------------------*/
  75.  
  76. ISR(IR_COMPARE_VECTOR)
  77. {
  78.     if ((timesIndex&1) == 1) {      /* if odd, ir-pause */
  79.         IR_OUTP_LOW();
  80.     } else {
  81.         IR_OUTP_HIGH();
  82.     }
  83.    
  84.     if (timesIndex < timesCounter)
  85.     {
  86.         IR_COMPARE_REG += times[timesIndex++];     
  87.     }
  88.     else
  89.     {
  90.         IR_MASK_COMPARE();
  91.         data_transmitted = 1;
  92.     }
  93. }
  94.  
  95. ISR(IR_TIMEOUT_VECTOR)
  96. {
  97.     if (timesCounter)
  98.     {
  99.         /* Disable interrupts until the application has taken action on the
  100.          * current data and reenabled reception. */
  101.         IR_MASK_CAPTURE();
  102.         IR_MASK_TIMEOUT();
  103.         /* Notify the application that a pulse train has been received. */
  104.         data_received = 1;
  105.     }
  106.     store = 0;
  107. }
  108.  
  109. ISR(IR_CAPTURE_VECTOR)
  110. {
  111.     static uint16_t prev_time;
  112.     uint16_t pulsewidth;
  113.  
  114.     /* Read the measured transition time from the capture register. */
  115.     uint16_t time = IR_CAPTURE_REG;
  116.    
  117.     /* Toggle the edge detection. */
  118.     if (detect_edge == 0)
  119.     {
  120.         IR_CAPTURE_RISING();
  121.         detect_edge = 1;
  122.     }
  123.     else
  124.     {
  125.         IR_CAPTURE_FALLING();
  126.         detect_edge = 0;
  127.     }
  128.    
  129.     /* Subtract the current measurement from the previous to get the pulse
  130.      * width. */
  131.     pulsewidth = time - prev_time;
  132.     prev_time = time;
  133.    
  134.     /* Set the timeout. */
  135.     IR_TIMEOUT_REG = time + IR_MAX_PULSE_WIDTH;
  136.    
  137.     if (store)
  138.     {
  139.         /* Store the measurement. */
  140.         times[timesCounter++] = pulsewidth;
  141.         /* Disable future measurements if we've filled the buffer. */
  142.         //TODO: Report overflow to application
  143.         if (timesCounter == MAX_NR_TIMES)
  144.         {
  145.             IR_MASK_CAPTURE();
  146.         }
  147.     }
  148.     else
  149.     {
  150.         /* The first edge of the pulse train has been detected. Enable the
  151.          * storage of the following pulsewidths. */
  152.         store = 1;
  153.         /* Enable timeout interrupt for detection of the end of the pulse
  154.          * train. */
  155.         IR_UNMASK_TIMEOUT();
  156.     }
  157. }
  158.  
  159.  
  160.  
  161. /*-----------------------------------------------------------------------------
  162.  * Public Functions
  163.  *---------------------------------------------------------------------------*/
  164.  
  165. /**
  166.  * Prepare Samsung data
  167.  *
  168.  * @param address
  169.  *      Pointer to store the address of the received data
  170.  * @param command
  171.  *      Pointer to store the command of the received data
  172.  */
  173. void prepareSamsung(uint32_t data) {
  174.     /* Set up startbit */
  175.     times[0] = IR_SAMS_ST_BIT;
  176.     times[1] = IR_SAMS_ST_PAUSE;
  177.    
  178.     for (uint8_t i = 0; i < 65; i++) {
  179.         if ((i&1) == 1) {       /* if odd, ir-pause */
  180.             if ((data>>(i>>1))&1) {
  181.                 times[i+2] = IR_SAMS_LOW_ONE;
  182.             } else {
  183.                 times[i+2] = IR_SAMS_LOW_ZERO;
  184.             }
  185.         } else {                /* if even, ir-bit */
  186.             times[i+2] = IR_SAMS_HIGH;
  187.         }
  188.     }
  189.    
  190.     timesCounter = 67;
  191. }
  192.  
  193. /**
  194.  * Prepare NEC data
  195.  *
  196.  * @param address
  197.  *      Pointer to store the address of the received data
  198.  * @param command
  199.  *      Pointer to store the command of the received data
  200.  */
  201. void prepareNEC(uint32_t data) {
  202.     /* Set up startbit */
  203.     times[0] = IR_NEC_ST_BIT;
  204.     times[1] = IR_NEC_ST_PAUSE;
  205.  
  206.     timesCounter = 67;
  207.     for (uint8_t i = 0; i < 65; i++) {
  208.         if ((i&1) == 1) {       /* if odd, ir-pause */
  209.             if ((data>>(i>>1))&1) {
  210.                 times[i+2] = IR_NEC_LOW_ONE;
  211.             } else {
  212.                 times[i+2] = IR_NEC_LOW_ZERO;
  213.             }
  214.         } else {            /* if even, ir-bit */
  215.             times[i+2] = IR_NEC_HIGH;
  216.         }
  217.     }
  218. }
  219.  
  220. void prepareSharp(uint32_t data) {}
  221.  
  222. void IrTransceiver_Init(void)
  223. {
  224.     /* Set up receiver */
  225.     IR_TIMER_INIT();
  226.     IR_TIMEOUT_REG = IR_MAX_PULSE_WIDTH;
  227.     IR_R_DDR &= ~(1<<IR_R_BIT);
  228.     //DDRC |= (1<<PC5);
  229.    
  230.     /* Set up transmitter */
  231.     IR_T_DDR |= (1<<IR_T_BIT);
  232.     #if defined(__AVR_ATmega88__) || defined(__AVR_ATmega168__)
  233.     TCCR0A = (0<<COM0A1)|(0<<COM0A0)|(1<<WGM01)|(0<<WGM00);
  234.     TCCR0B = (0<<WGM02)|(1<<CS00)|(0<<CS01)|(0<<CS02);
  235.     #endif
  236.  
  237. }
  238.  
  239. void IrTransceiver_Start(void)
  240. {
  241.     /* Clear buffer and arm the edge detection. */
  242.     timesCounter = 0;
  243.     data_received = 0;
  244.     store = 0;
  245. #if (IR_RX_ACTIVE_LOW == 1)
  246.     IR_CAPTURE_FALLING();
  247.     detect_edge = 0;
  248. #else
  249.     IR_CAPTURE_RISING();
  250.     detect_edge = 1;
  251. #endif
  252.     IR_UNMASK_CAPTURE();
  253. }
  254.  
  255. uint8_t IrTransceiver_Poll(uint16_t **buffer, uint8_t *length)
  256. {
  257.     if (data_received)
  258.     {
  259.         *buffer = times;
  260.         *length = timesCounter;
  261.         return IR_OK;
  262.     }
  263.     else
  264.     {
  265.         return IR_NO_DATA;
  266.     }
  267. }
  268.  
  269. #if 0
  270. uint8_t IrTransceiver_Transmit(uint16_t **buffer, uint8_t *length)
  271. {
  272.     data_transmitted = 0;
  273.     if (timesCounter == 0) return IR_NO_DATA;
  274.     timesIndex = 1;
  275.     IR_COMPARE_REG = IR_COUNT_REG + times[0];
  276. #if (IR_RX_ACTIVE_LOW == 1)
  277.     PORTC &= ~(1<<PC5);
  278. #else
  279.     PORTC |= (1<<PC5);
  280. #endif
  281.     IR_UNMASK_COMPARE();
  282.    
  283.     while (!data_transmitted);
  284.    
  285.     return IR_OK;
  286. }
  287. #endif
  288.  
  289. uint8_t IrTransceiver_Transmit_Poll(void) {
  290.     if (data_transmitted == 0) {
  291.         return IR_NOT_FINISHED;
  292.     } else {
  293.         return IR_OK;
  294.     }
  295. }
  296.  
  297. uint8_t IrTransceiver_Transmit(uint8_t proto, uint32_t data, uint16_t *timeout, uint8_t *repeates)
  298. {
  299.     timesCounter = 0;
  300.     //prepare rawdata here
  301.     if (proto == IR_PROTO_SHARP) {
  302.         prepareSharp(data);
  303.         OCR0A = (((F_CPU/2000)/IR_SHARP_F_MOD) -1);     // set up modulation
  304.         *repeates = IR_SHARP_REPS;
  305.         *timeout = IR_SHARP_REPETITION;
  306.     } else if (proto == IR_PROTO_SAMS) {
  307.         prepareSamsung(data);
  308.         OCR0A = (((F_CPU/2000)/IR_SAMS_F_MOD) -1);      // set up modulation
  309.         *repeates = IR_SAMS_REPS;
  310.         *timeout = IR_SAMS_REPETITION;
  311.     } else if (proto == IR_PROTO_NEC) {
  312.         prepareNEC(data);
  313.         OCR0A = (((F_CPU/2000)/IR_NEC_F_MOD) -1);       // set up modulation
  314.         *repeates = IR_NEC_REPS;
  315.         *timeout = IR_NEC_REPETITION;
  316.     }
  317.    
  318.     data_transmitted = 0;
  319.     if (timesCounter == 0) return IR_NO_DATA;
  320.     timesIndex = 1;
  321.     IR_COMPARE_REG = IR_COUNT_REG + times[0];
  322.    
  323.     IR_OUTP_HIGH();
  324.    
  325.     IR_UNMASK_COMPARE();
  326.    
  327.     return IR_OK;
  328. }
  329.  
  330. /**
  331.  * Get an ir-time from the stored array, this can be used
  332.  * when a proper protocol is not found.
  333.  *
  334.  * @param index
  335.  *      Which time to get
  336.  * @return
  337.  *      The 16bit value at index index
  338.  */
  339. uint16_t getRawData(uint8_t index) {
  340.     return times[index];
  341. }
  342.  
  343. /**
  344.  * Get the number of stored ir-times in the array
  345.  *
  346.  * @return
  347.  *      The number of stored ir-times in the array
  348.  */
  349. uint8_t getRawDataCnt(void) {
  350.     return timesCounter;
  351. }
  352.  
  353. /**
  354.  * Test data on SIRC protocol, 12-bit version
  355.  * http://www.sbprojects.com/knowledge/ir/sirc.htm
  356.  *
  357.  * @param data
  358.  *      Pointer to store the received data
  359.  * @return
  360.  *      IR_OK if data parsed successfully, one of several errormessages if not
  361.  */
  362. uint8_t testSIRC(uint32_t *data) {
  363.     /* parse times[], max is timesCounter */
  364.  
  365.     /* check if we have correct amount of data */
  366.     if (timesCounter != 25) {
  367.         return IR_NOT_CORRECT_DATA;
  368.     }
  369.    
  370.     /* check startbit */
  371.     if (times[0] > IR_SIRC_ST_BIT + IR_SIRC_ST_BIT/IR_SIRC_TOL_DIV || times[0] < IR_SIRC_ST_BIT - IR_SIRC_ST_BIT/IR_SIRC_TOL_DIV) {
  372.         return IR_NOT_CORRECT_DATA;
  373.     }
  374.    
  375.     uint16_t rawbits=0;
  376.    
  377.     for (uint8_t i = 1; i < timesCounter; i++) {
  378.         if ((i&1) == 1) {       /* if odd, ir-pause */
  379.             /* check length of pause between bits */
  380.             if (times[i] > IR_SIRC_LOW + IR_SIRC_LOW/IR_SIRC_TOL_DIV || times[i] < IR_SIRC_LOW - IR_SIRC_LOW/IR_SIRC_TOL_DIV) {
  381.                 return IR_NOT_CORRECT_DATA;
  382.             }
  383.         } else {            /* if even, ir-bit */
  384.             if (times[i] > IR_SIRC_HIGH_ONE - IR_SIRC_HIGH_ONE/IR_SIRC_TOL_DIV && times[i] < IR_SIRC_HIGH_ONE + IR_SIRC_HIGH_ONE/IR_SIRC_TOL_DIV) {
  385.                 /* write a one */
  386.                 rawbits |= 1<<((i-2)>>1);
  387.             } else if (times[i] > IR_SIRC_HIGH_ZERO - IR_SIRC_HIGH_ZERO/IR_SIRC_TOL_DIV && times[i] < IR_SIRC_HIGH_ZERO + IR_SIRC_HIGH_ZERO/IR_SIRC_TOL_DIV) {
  388.                 /* do nothing, a zero is already in rawbits */
  389.             } else {
  390.                 return IR_NOT_CORRECT_DATA;
  391.             }
  392.         }
  393.     }
  394.    
  395.     *data = rawbits;
  396.    
  397.     return IR_OK;
  398. }
  399.  
  400. /**
  401.  * Test data on RC5 protocol
  402.  * http://www.sbprojects.com/knowledge/ir/rc5.htm
  403.  *
  404.  * @param data
  405.  *      Pointer to store the received data
  406.  * @return
  407.  *      IR_OK if data parsed successfully, one of several errormessages if not
  408.  */
  409. uint8_t testRC5(uint32_t *data) {
  410.     uint8_t halfbitscnt = 1;
  411.     uint16_t rawbits = 0;
  412.    
  413.     for (uint8_t i = 0; i<timesCounter; i++) {
  414.         //halfbitscnt&1==1 in the middle of bits
  415.         //i&1==0 positive flank
  416.  
  417.         if ((halfbitscnt&1)==1 && (i&1)==0) {       /* in the middle of bit AND a positve flank */
  418.             rawbits |= (1<<(13-(halfbitscnt>>1)));
  419.         }
  420.        
  421.         if (times[i] > IR_RC5_HALF_BIT - IR_RC5_HALF_BIT/IR_RC5_TOL_DIV && times[i] < IR_RC5_HALF_BIT + IR_RC5_HALF_BIT/IR_RC5_TOL_DIV) {
  422.             halfbitscnt += 1;
  423.         } else if (times[i] > IR_RC5_BIT - IR_RC5_BIT/IR_RC5_TOL_DIV && times[i] < IR_RC5_BIT + IR_RC5_BIT/IR_RC5_TOL_DIV) {
  424.             halfbitscnt += 2;
  425.         } else {
  426.             return IR_NOT_CORRECT_DATA;
  427.         }
  428.        
  429.     }
  430.    
  431.     //support RC5-extended keeping second startbit
  432.     //remove togglebit
  433.     *data = rawbits&0x37ff;
  434.  
  435.     return IR_OK;
  436. }
  437.  
  438. /**
  439.  * Test data on SHARP protocol
  440.  * http://www.sbprojects.com/knowledge/ir/sharp.htm
  441.  *
  442.  * @param data
  443.  *      Pointer to store the received data
  444.  * @return
  445.  *      IR_OK if data parsed successfully, one of several errormessages if not
  446.  */
  447. uint8_t testSharp(uint32_t *data) {
  448.     /* parse times[], max is timesCounter */
  449.  
  450.     /* check if we have correct amount of data */
  451.     if (timesCounter != 31) {
  452.         return IR_NOT_CORRECT_DATA;
  453.     }
  454.    
  455.     uint16_t rawbits=0;
  456.    
  457.     for (uint8_t i = 1; i < timesCounter; i++) {
  458.         if ((i&1) == 1) {       /* if odd, ir-pause */
  459.             /* check length of pause between bits */
  460.             if (times[i] > IR_SHARP_LOW_ONE - IR_SHARP_LOW_ONE/IR_SHARP_TOL_DIV && times[i] < IR_SHARP_LOW_ONE + IR_SHARP_LOW_ONE/IR_SHARP_TOL_DIV) {
  461.                 /* write a one */
  462.                 rawbits |= 1<<((i-1)>>1);
  463.             } else if (times[i] > IR_SHARP_LOW_ZERO - IR_SHARP_LOW_ZERO/IR_SHARP_TOL_DIV && times[i] < IR_SHARP_LOW_ZERO + IR_SHARP_LOW_ZERO/IR_SHARP_TOL_DIV) {
  464.                 /* do nothing, a zero is already in rawbits */
  465.             } else {
  466.                 return IR_NOT_CORRECT_DATA;
  467.             }
  468.         } else {            /* if even, ir-bit */
  469.             if (times[i] > IR_SHARP_HIGH + IR_SHARP_HIGH/IR_SHARP_TOL_DIV || times[i] < IR_SHARP_HIGH - IR_SHARP_HIGH/IR_SHARP_TOL_DIV) {
  470.                 return IR_NOT_CORRECT_DATA;
  471.             }
  472.         }
  473.     }
  474.    
  475.     *data = rawbits;
  476.    
  477.     return IR_OK;
  478. }
  479.  
  480. /**
  481.  * Test data on NEC protocol
  482.  * http://www.sbprojects.com/knowledge/ir/nec.htm
  483.  *
  484.  * @param data
  485.  *      Pointer to store the received data
  486.  * @return
  487.  *      IR_OK if data parsed successfully, one of several errormessages if not
  488.  */
  489. uint8_t testNEC(uint32_t *data) {
  490.     /* parse times[], max is timesCounter */
  491.  
  492.     /* check if we have correct amount of data */
  493.     if (timesCounter != 67) {
  494.         return IR_NOT_CORRECT_DATA;
  495.     }
  496.    
  497.     /* check startbit */
  498.     if (times[0] > IR_NEC_ST_BIT + IR_NEC_ST_BIT/IR_NEC_TOL_DIV || times[0] < IR_NEC_ST_BIT - IR_NEC_ST_BIT/IR_NEC_TOL_DIV) {
  499.         return IR_NOT_CORRECT_DATA;
  500.     }
  501.  
  502.     /* check pause after startbit */
  503.     if (times[1] > IR_NEC_ST_PAUSE + IR_NEC_ST_PAUSE/IR_NEC_TOL_DIV || times[1] < IR_NEC_ST_PAUSE - IR_NEC_ST_PAUSE/IR_NEC_TOL_DIV) {
  504.         return IR_NOT_CORRECT_DATA;
  505.     }
  506.  
  507.     *data = 0;
  508.     for (uint8_t i = 3; i < timesCounter; i++) {
  509.         if ((i&1) == 1) {       /* if odd, ir-pause */
  510.             /* check length of pause between bits */
  511.             if (times[i] > IR_NEC_LOW_ONE - IR_NEC_LOW_ONE/IR_NEC_TOL_DIV && times[i] < IR_NEC_LOW_ONE + IR_NEC_LOW_ONE/IR_NEC_TOL_DIV) {
  512.                 /* write a one */
  513.                 *data |= 1UL<<((i-3)>>1);
  514.             } else if (times[i] > IR_NEC_LOW_ZERO - IR_NEC_LOW_ZERO/IR_NEC_TOL_DIV && times[i] < IR_NEC_LOW_ZERO + IR_NEC_LOW_ZERO/IR_NEC_TOL_DIV) {
  515.                 /* do nothing, a zero is already in place */
  516.             } else {
  517.                 return IR_NOT_CORRECT_DATA;
  518.             }
  519.         } else {            /* if even, ir-bit */
  520.             if (times[i] > IR_NEC_HIGH + IR_NEC_HIGH/IR_NEC_TOL_DIV || times[i] < IR_NEC_HIGH - IR_NEC_HIGH/IR_NEC_TOL_DIV) {
  521.                 return IR_NOT_CORRECT_DATA;
  522.             }
  523.         }
  524.     }
  525.    
  526.     return IR_OK;
  527. }
  528.  
  529.  
  530. /**
  531.  * Test data on Samsung protocol
  532.  * Very much like NEC, different start bit/pause lengths etc.
  533.  * http://www.sbprojects.com/knowledge/ir/nec.htm
  534.  *
  535.  * @param data
  536.  *      Pointer to store the received data
  537.  * @return
  538.  *      IR_OK if data parsed successfully, one of several errormessages if not
  539.  */
  540. uint8_t testSamsung(uint32_t *data) {
  541.     /* parse times[], max is timesCounter */
  542.  
  543.     /* check if we have correct amount of data */
  544.     if (timesCounter != 67) {
  545.         return IR_NOT_CORRECT_DATA;
  546.     }
  547.    
  548.     /* check startbit */
  549.     if (times[0] > IR_SAMS_ST_BIT + IR_SAMS_ST_BIT/IR_SAMS_TOL_DIV || times[0] < IR_SAMS_ST_BIT - IR_SAMS_ST_BIT/IR_SAMS_TOL_DIV) {
  550.         return IR_NOT_CORRECT_DATA;
  551.     }
  552.  
  553.     /* check pause after startbit */
  554.     if (times[1] > IR_SAMS_ST_PAUSE + IR_SAMS_ST_PAUSE/IR_SAMS_TOL_DIV || times[1] < IR_SAMS_ST_PAUSE - IR_SAMS_ST_PAUSE/IR_SAMS_TOL_DIV) {
  555.         return IR_NOT_CORRECT_DATA;
  556.     }
  557.  
  558.     *data = 0;
  559.     for (uint8_t i = 3; i < timesCounter; i++) {
  560.         if ((i&1) == 1) {       /* if odd, ir-pause */
  561.             /* check length of pause between bits */
  562.             if (times[i] > IR_SAMS_LOW_ONE - IR_SAMS_LOW_ONE/IR_SAMS_TOL_DIV && times[i] < IR_SAMS_LOW_ONE + IR_SAMS_LOW_ONE/IR_SAMS_TOL_DIV) {
  563.                 /* write a one */
  564.                 *data |= 1UL<<((i-3)>>1);
  565.             } else if (times[i] > IR_SAMS_LOW_ZERO - IR_SAMS_LOW_ZERO/IR_SAMS_TOL_DIV && times[i] < IR_SAMS_LOW_ZERO + IR_SAMS_LOW_ZERO/IR_SAMS_TOL_DIV) {
  566.                 /* do nothing, a zero is already in place */
  567.             } else {
  568.                 return IR_NOT_CORRECT_DATA;
  569.             }
  570.         } else {            /* if even, ir-bit */
  571.             if (times[i] > IR_SAMS_HIGH + IR_SAMS_HIGH/IR_SAMS_TOL_DIV || times[i] < IR_SAMS_HIGH - IR_SAMS_HIGH/IR_SAMS_TOL_DIV) {
  572.                 return IR_NOT_CORRECT_DATA;
  573.             }
  574.         }
  575.     }
  576.     return IR_OK;
  577. }
  578.  
  579. //uint8_t IrReceive_CheckIR(uint8_t *proto, uint8_t *address, uint8_t *command, uint16_t *timeout) {
  580. uint8_t IrReceive_CheckIR(uint8_t *proto, uint32_t *data, uint16_t *timeout) {
  581.     IrTransceiver_Start();
  582.    
  583.     while (!data_received);
  584.    
  585.     if (testSIRC(&*data) == IR_OK) {
  586.         *proto = IR_PROTO_SIRC;
  587.         *timeout = IR_SIRC_REPETITION;
  588.         return IR_OK;
  589.     } else if (testRC5(&*data) == IR_OK) {
  590.         *proto = IR_PROTO_RC5;
  591.         *timeout = IR_RC5_REPETITION;
  592.         return IR_OK;
  593.     } else if (testSharp(&*data) == IR_OK) {
  594.         *proto = IR_PROTO_SHARP;
  595.         *timeout = IR_SHARP_REPETITION;
  596.         return IR_OK;
  597.     } else if (testNEC(&*data) == IR_OK) {
  598.         *proto = IR_PROTO_NEC;
  599.         *timeout = IR_NEC_REPETITION;
  600.         return IR_OK;
  601.     } else if (testSamsung(&*data) == IR_OK) {
  602.         *proto = IR_PROTO_SAMS;
  603.         *timeout = IR_SAMS_REPETITION;
  604.         return IR_OK;
  605.     }
  606.        
  607.     return IR_NO_PROTOCOL;
  608.    
  609. }
  610.  
  611. //TODO: skriv doxygen-header som för de andra funktionerna
  612. /**
  613.  *
  614.  *
  615.  *
  616.  *
  617.  */
  618. void IrReceive_Init(void) {
  619.     IrTransceiver_Init();
  620.     /*IR_R_DDR &= ~(1<<IR_R_BIT);*/
  621. }
  622.  
  623. //varför är denna funktion så komplex? jo den filtrerar bort korta ir-pulser
  624. //TODO: skriv doxygen-header som för de andra funktionerna
  625. uint8_t IrReceive_CheckIdle(void) {
  626.     if (IR_R_PIN & (1<<IR_R_BIT)) return IR_NO_DATA;        //om irmodulen ger en etta så återgå
  627.    
  628.     //nu lägger irmodulen ut en nolla, "startbiten" alltså
  629.    
  630.     uint16_t timerVal;
  631.    
  632.     //Läs in längden på startbiten
  633.     initTimer();
  634.     while (!(IR_R_PIN & (1<<IR_R_BIT))) {       //vänta på att irmodulen lägger ut en etta
  635.         //om timeout (om timer-ovflow-flaggan sätt)
  636.         if (isTimerOvfl() == 1) return IR_TIME_OVFL;
  637.     }
  638.     timerVal = getTimerVal();
  639.    
  640.     if ((timerVal < IR_MAX_PULSE_WIDTH) && (timerVal > IR_MIN_PULSE_WIDTH)) {
  641.         return IR_OK;
  642.     } //else if ...
  643.    
  644.    
  645.     return IR_NO_PROTOCOL;
  646. }
  647.