Subversion Repositories HomeAutomation

Rev

Rev 547 | Rev 608 | 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. #if defined(__AVR_ATmega8__) || defined(__AVR_ATmega16__) || defined(__AVR_ATmega32__)
  33. #define TIMSK1  TIMSK
  34. #define TIFR1   TIFR
  35. #define ICIE1   TICIE1
  36. #endif
  37.  
  38. #define IR_COMPARE_VECTOR       TIMER1_COMPB_vect
  39. #define IR_TIMEOUT_VECTOR       TIMER1_COMPA_vect
  40. #define IR_CAPTURE_VECTOR       TIMER1_CAPT_vect
  41. #define IR_TIMEOUT_REG          OCR1A
  42. #define IR_COMPARE_REG          OCR1B
  43. #define IR_CAPTURE_REG          ICR1
  44. #define IR_COUNT_REG            TCNT1
  45. #define IR_TIMER_INIT()         TCCR1A = 0; \
  46.                                 TCCR1B = (1<<ICNC1)|(2<<CS10);
  47. #define IR_MASK_COMPARE()       TIMSK1 &= ~(1<<OCIE1B);
  48. #define IR_UNMASK_COMPARE()     TIFR1 = (1<<OCF1B); TIMSK1 |= (1<<OCIE1B);
  49. #define IR_MASK_TIMEOUT()       TIMSK1 &= ~(1<<OCIE1A);
  50. #define IR_UNMASK_TIMEOUT()     TIFR1 = (1<<OCF1A); TIMSK1 |= (1<<OCIE1A);
  51. #define IR_MASK_CAPTURE()       TIMSK1 &= ~(1<<ICIE1);
  52. #define IR_UNMASK_CAPTURE()     TIFR1 = (1<<ICF1); TIMSK1 |= (1<<ICIE1);
  53. #define IR_CAPTURE_FALLING()    TCCR1B &= ~(1<<ICES1); \
  54.                                 TIFR1 = (1<<ICF1);
  55. #define IR_CAPTURE_RISING()     TCCR1B |= (1<<ICES1); \
  56.                                 TIFR1 = (1<<ICF1);
  57.  
  58. #define IR_RX_ACTIVE_LOW    1
  59. #define IR_TX_ACTIVE_LOW    1
  60.  
  61. /*-----------------------------------------------------------------------------
  62.  * Interrupt Handlers
  63.  *---------------------------------------------------------------------------*/
  64.  
  65. ISR(IR_COMPARE_VECTOR)
  66. {
  67.     PORTC ^= (1<<PC5);
  68.     if (timesIndex < timesCounter)
  69.     {
  70.         IR_COMPARE_REG += times[timesIndex++];     
  71.     }
  72.     else
  73.     {
  74.         IR_MASK_COMPARE();
  75.         data_transmitted = 1;
  76.     }
  77. }
  78.  
  79. ISR(IR_TIMEOUT_VECTOR)
  80. {
  81.     if (timesCounter)
  82.     {
  83.         /* Disable interrupts until the application has taken action on the
  84.          * current data and reenabled reception. */
  85.         IR_MASK_CAPTURE();
  86.         IR_MASK_TIMEOUT();
  87.         /* Notify the application that a pulse train has been received. */
  88.         data_received = 1;
  89.     }
  90.     store = 0;
  91. }
  92.  
  93. ISR(IR_CAPTURE_VECTOR)
  94. {
  95.     static uint16_t prev_time;
  96.     uint16_t pulsewidth;
  97.  
  98.     /* Read the measured transition time from the capture register. */
  99.     uint16_t time = IR_CAPTURE_REG;
  100.    
  101.     /* Toggle the edge detection. */
  102.     if (detect_edge == 0)
  103.     {
  104.         IR_CAPTURE_RISING();
  105.         detect_edge = 1;
  106.     }
  107.     else
  108.     {
  109.         IR_CAPTURE_FALLING();
  110.         detect_edge = 0;
  111.     }
  112.    
  113.     /* Subtract the current measurement from the previous to get the pulse
  114.      * width. */
  115.     pulsewidth = time - prev_time;
  116.     prev_time = time;
  117.    
  118.     /* Set the timeout. */
  119.     IR_TIMEOUT_REG = time + IR_MAX_PULSE_WIDTH;
  120.    
  121.     if (store)
  122.     {
  123.         /* Store the measurement. */
  124.         times[timesCounter++] = pulsewidth;
  125.         /* Disable future measurements if we've filled the buffer. */
  126.         //TODO: Report overflow to application
  127.         if (timesCounter == MAX_NR_TIMES)
  128.         {
  129.             IR_MASK_CAPTURE();
  130.         }
  131.     }
  132.     else
  133.     {
  134.         /* The first edge of the pulse train has been detected. Enable the
  135.          * storage of the following pulsewidths. */
  136.         store = 1;
  137.         /* Enable timeout interrupt for detection of the end of the pulse
  138.          * train. */
  139.         IR_UNMASK_TIMEOUT();
  140.     }
  141. }
  142.  
  143.  
  144. /*-----------------------------------------------------------------------------
  145.  * Public Functions
  146.  *---------------------------------------------------------------------------*/
  147.  
  148. void IrTransceiver_Init(void)
  149. {
  150.     IR_TIMER_INIT();
  151.     IR_TIMEOUT_REG = IR_MAX_PULSE_WIDTH;
  152.     IRDDR &= ~(1<<IRBIT);
  153.     DDRC |= (1<<PC5);
  154. }
  155.  
  156. void IrTransceiver_Start(void)
  157. {
  158.     /* Clear buffer and arm the edge detection. */
  159.     timesCounter = 0;
  160.     data_received = 0;
  161.     store = 0;
  162. #if (IR_RX_ACTIVE_LOW == 1)
  163.     IR_CAPTURE_FALLING();
  164.     detect_edge = 0;
  165. #else
  166.     IR_CAPTURE_RISING();
  167.     detect_edge = 1;
  168. #endif
  169.     IR_UNMASK_CAPTURE();
  170. }
  171.  
  172. uint8_t IrTransceiver_Poll(uint16_t **buffer, uint8_t *length)
  173. {
  174.     if (data_received)
  175.     {
  176.         *buffer = times;
  177.         *length = timesCounter;
  178.         return IR_OK;
  179.     }
  180.     else
  181.     {
  182.         return IR_NO_DATA;
  183.     }
  184. }
  185.  
  186. uint8_t IrTransceiver_Transmit(uint16_t **buffer, uint8_t *length)
  187. {
  188.     data_transmitted = 0;
  189.     if (timesCounter == 0) return IR_NO_DATA;
  190.     timesIndex = 1;
  191.     IR_COMPARE_REG = IR_COUNT_REG + times[0];
  192. #if (IR_RX_ACTIVE_LOW == 1)
  193.     PORTC &= ~(1<<PC5);
  194. #else
  195.     PORTC |= (1<<PC5);
  196. #endif
  197.     IR_UNMASK_COMPARE();
  198.    
  199.     while (!data_transmitted);
  200.    
  201.     return IR_OK;
  202. }
  203.  
  204. /**
  205.  * Get an ir-time from the stored array, this can be used
  206.  * when a proper protocol is not found.
  207.  *
  208.  * @param index
  209.  *      Which time to get
  210.  * @return
  211.  *      The 16bit value at index index
  212.  */
  213. uint16_t getRawData(uint8_t index) {
  214.     return times[index];
  215. }
  216.  
  217. /**
  218.  * Get the number of stored ir-times in the array
  219.  *
  220.  * @return
  221.  *      The number of stored ir-times in the array
  222.  */
  223. uint8_t getRawDataCnt(void) {
  224.     return timesCounter;
  225. }
  226.  
  227. #if 1
  228.  
  229. /**
  230.  * Test data on SIRC protocol, 12-bit version
  231.  * http://www.sbprojects.com/knowledge/ir/sirc.htm
  232.  *
  233.  * @param address
  234.  *      Pointer to store the address of the received data
  235.  * @param command
  236.  *      Pointer to store the command of the received data
  237.  * @return
  238.  *      IR_OK if data parsed successfully, one of several errormessages if not
  239.  */
  240. uint8_t testSIRC(uint8_t *address, uint8_t *command) {
  241.     /* parse times[], max is timesCounter */
  242.  
  243.     /* check if we have correct amount of data */
  244.     if (timesCounter != 25) {
  245.         return IR_NOT_CORRECT_DATA;
  246.     }
  247.    
  248.     /* check startbit */
  249.     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) {
  250.         return IR_NOT_CORRECT_DATA;
  251.     }
  252.    
  253.     uint16_t rawbits=0;
  254.    
  255.     for (uint8_t i = 1; i < timesCounter; i++) {
  256.         if ((i&1) == 1) {       /* if odd, ir-pause */
  257.             /* check length of pause between bits */
  258.             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) {
  259.                 return IR_NOT_CORRECT_DATA;
  260.             }
  261.         } else {            /* if even, ir-bit */
  262.             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) {
  263.                 /* write a one */
  264.                 rawbits |= 1<<((i-2)>>1);
  265.             } 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) {
  266.                 /* do nothing, a zero is already in rawbits */
  267.             } else {
  268.                 return IR_NOT_CORRECT_DATA;
  269.             }
  270.         }
  271.     }
  272.    
  273.     *command = ((uint8_t)rawbits&0x7f);
  274.     *address = ((uint8_t)(rawbits>>7)&0x1f);
  275.    
  276.     return IR_OK;
  277. }
  278.  
  279. /**
  280.  * Test data on RC5 protocol
  281.  * http://www.sbprojects.com/knowledge/ir/rc5.htm
  282.  *
  283.  * @param address
  284.  *      Pointer to store the address of the received data
  285.  * @param command
  286.  *      Pointer to store the command of the received data
  287.  * @return
  288.  *      IR_OK if data parsed successfully, one of several errormessages if not
  289.  */
  290. uint8_t testRC5(uint8_t *address, uint8_t *command) {
  291.     uint8_t halfbitscnt = 1;
  292.     uint16_t rawbits = 0;
  293.    
  294.     for (uint8_t i = 0; i<timesCounter; i++) {
  295.         //halfbitscnt&1==1 in the middle of bits
  296.         //i&1==0 positive flank
  297.  
  298.         if ((halfbitscnt&1)==1 && (i&1)==0) {       /* in the middle of bit AND a positve flank */
  299.             rawbits |= (1<<(13-(halfbitscnt>>1)));
  300.         }
  301.        
  302.         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) {
  303.             halfbitscnt += 1;
  304.         } 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) {
  305.             halfbitscnt += 2;
  306.         } else {
  307.             return IR_NOT_CORRECT_DATA;
  308.         }
  309.        
  310.     }
  311.  
  312.     *command = ((uint8_t)rawbits&0x3f);
  313.     *address = ((uint8_t)(rawbits>>6)&0x7f);   
  314.  
  315.     //support RC5-extended by putting the inversion of startbit 2 as the 7th commandbit
  316.     *command |= (~(*address) & 0x40);
  317.     *address &= 0x1f;       //remove togglebit and both startbits from address
  318.    
  319.     return IR_OK;
  320. }
  321.  
  322. /**
  323.  * Test data on SHARP protocol
  324.  * http://www.sbprojects.com/knowledge/ir/sharp.htm
  325.  *
  326.  * @param address
  327.  *      Pointer to store the address of the received data
  328.  * @param command
  329.  *      Pointer to store the command of the received data
  330.  * @return
  331.  *      IR_OK if data parsed successfully, one of several errormessages if not
  332.  */
  333. uint8_t testSharp(uint8_t *address, uint8_t *command) {
  334.     /* parse times[], max is timesCounter */
  335.  
  336.     /* check if we have correct amount of data */
  337.     if (timesCounter != 31) {
  338.         return IR_NOT_CORRECT_DATA;
  339.     }
  340.    
  341.     uint16_t rawbits=0;
  342.    
  343.     for (uint8_t i = 1; i < timesCounter; i++) {
  344.         if ((i&1) == 1) {       /* if odd, ir-pause */
  345.             /* check length of pause between bits */
  346.             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) {
  347.                 /* write a one */
  348.                 rawbits |= 1<<((i-1)>>1);
  349.             } 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) {
  350.                 /* do nothing, a zero is already in rawbits */
  351.             } else {
  352.                 return IR_NOT_CORRECT_DATA;
  353.             }
  354.         } else {            /* if even, ir-bit */
  355.             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) {
  356.                 return IR_NOT_CORRECT_DATA;
  357.             }
  358.         }
  359.     }
  360.    
  361.     *command = ((uint8_t)(rawbits>>5)&0xff);
  362.     *address = ((uint8_t)rawbits&0x1f);
  363.    
  364.     return IR_OK;
  365. }
  366.  
  367. /**
  368.  * Test data on NEC protocol
  369.  * http://www.sbprojects.com/knowledge/ir/nec.htm
  370.  *
  371.  * @param address
  372.  *      Pointer to store the address of the received data
  373.  * @param command
  374.  *      Pointer to store the command of the received data
  375.  * @return
  376.  *      IR_OK if data parsed successfully, one of several errormessages if not
  377.  */
  378. uint8_t testNEC(uint8_t *address, uint8_t *command) {
  379.     /* parse times[], max is timesCounter */
  380.  
  381.     /* check if we have correct amount of data */
  382.     if (timesCounter != 67) {
  383.         return IR_NOT_CORRECT_DATA;
  384.     }
  385.    
  386.     /* check startbit */
  387.     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) {
  388.         return IR_NOT_CORRECT_DATA;
  389.     }
  390.  
  391.     /* check pause after startbit */
  392.     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) {
  393.         return IR_NOT_CORRECT_DATA;
  394.     }
  395.  
  396.     *command = 0;
  397.     *address = 0;
  398.    
  399.     for (uint8_t i = 3; i < timesCounter; i++) {
  400.         if ((i&1) == 1) {       /* if odd, ir-pause */
  401.             /* check length of pause between bits */
  402.             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) {
  403.                 if (i>2 && i<18) {
  404.                     /* write a one */
  405.                     *address |= 1<<((i-3)>>1);
  406.                 }
  407.                 if (i>34 && i<50) {
  408.                     /* write a one */
  409.                     *command |= 1<<((i-35)>>1);
  410.                 }
  411.             } 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) {
  412.                 /* do nothing, a zero is already in rawbits */
  413.             } else {
  414.                 return IR_NOT_CORRECT_DATA;
  415.             }
  416.         } else {            /* if even, ir-bit */
  417.             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) {
  418.                 return IR_NOT_CORRECT_DATA;
  419.             }
  420.         }
  421.     }
  422.    
  423.     return IR_OK;
  424. }
  425.  
  426.  
  427. /**
  428.  * Test data on Samsung protocol
  429.  * Very much like NEC, different start bit/pause lengths etc.
  430.  * http://www.sbprojects.com/knowledge/ir/nec.htm
  431.  *
  432.  * @param address
  433.  *      Pointer to store the address of the received data
  434.  * @param command
  435.  *      Pointer to store the command of the received data
  436.  * @return
  437.  *      IR_OK if data parsed successfully, one of several errormessages if not
  438.  */
  439. uint8_t testSamsung(uint8_t *address, uint8_t *command) {
  440.     /* parse times[], max is timesCounter */
  441.  
  442.     /* check if we have correct amount of data */
  443.     if (timesCounter != 67) {
  444.         return IR_NOT_CORRECT_DATA;
  445.     }
  446.    
  447.     /* check startbit */
  448.     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) {
  449.         return IR_NOT_CORRECT_DATA;
  450.     }
  451.  
  452.     /* check pause after startbit */
  453.     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) {
  454.         return IR_NOT_CORRECT_DATA;
  455.     }
  456.  
  457.     *command = 0;
  458.     *address = 0;
  459.    
  460.     for (uint8_t i = 3; i < timesCounter; i++) {
  461.         if ((i&1) == 1) {       /* if odd, ir-pause */
  462.             /* check length of pause between bits */
  463.             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) {
  464.                 if (i>2 && i<18) {
  465.                     /* write a one */
  466.                     *address |= 1<<((i-3)>>1);
  467.                 }
  468.                 if (i>34 && i<50) {
  469.                     /* write a one */
  470.                     *command |= 1<<((i-35)>>1);
  471.                 }
  472.             } 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) {
  473.                 /* do nothing, a zero is already in rawbits */
  474.             } else {
  475.                 return IR_NOT_CORRECT_DATA;
  476.             }
  477.         } else {            /* if even, ir-bit */
  478.             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) {
  479.                 return IR_NOT_CORRECT_DATA;
  480.             }
  481.         }
  482.     }
  483.    
  484.     return IR_OK;
  485. }
  486.  
  487. uint8_t IrReceive_CheckIR(uint8_t *proto, uint8_t *address, uint8_t *command, uint16_t *timeout) {
  488.     IrTransceiver_Start();
  489.    
  490.     while (!data_received);
  491.    
  492.    
  493. #if 0
  494.     if (IRPIN & (1<<IRBIT)) return IR_NO_DATA;      //om irmodulen ger en etta så återgå
  495.    
  496.     initTimer();
  497.    
  498.     //this routine should sample the timings for received irdata
  499.     timesCounter = 0;
  500.    
  501.     uint8_t gotTimout = 0;  // a timeout is a very long break in irdata (such as occurs between ir pulsetrains)
  502.     while (!gotTimout && timesCounter < MAX_NR_TIMES-1) { //loop as long as no timeout occured and not to many pulses received
  503.         setTimerVal(TIM_OVFL_RELOAD_VAL);
  504.         //wait for positiv slope, while checking timer overflow
  505.         while (!(IRPIN & (1<<IRBIT))) {
  506.             //if timeout (if timer-ovflow-flaggan is set)
  507.             if (isTimerOvfl() == 1) return IR_TIME_OVFL;    //this timeout is not good (irsignal low which means active)
  508.         }
  509.        
  510.         times[timesCounter] = getTimerVal()-TIM_OVFL_RELOAD_VAL;
  511.         //TODO: should we check times[timesCounter] so its a realistic time-value? use IR_MIN_PULSE_WIDTH
  512.         timesCounter++;
  513.        
  514.         setTimerVal(TIM_OVFL_RELOAD_VAL);
  515.         //wait for negative slope, while checking timer overflow
  516.         while ((IRPIN & (1<<IRBIT)) && !gotTimout) {
  517.             //om timeout (om timer-ovflow-flaggan sätt)
  518.             if (isTimerOvfl() == 1) gotTimout=1;    //return IR_TIME_OVFL;
  519.         }
  520.  
  521.         if (!gotTimout) {
  522.             times[timesCounter] = getTimerVal()-TIM_OVFL_RELOAD_VAL;
  523.             //TODO: should we check times[timesCounter] so its a realistic time-value?
  524.             timesCounter++;
  525.         }
  526.     }
  527.     if (timesCounter >= MAX_NR_TIMES-1) {
  528.         //to much irdata, not good, abort
  529.         return IR_TO_MUCH_DATA;
  530.     }
  531. #endif
  532.    
  533.     if (testSIRC(&*address, &*command) == IR_OK) {
  534.         *proto = IR_PROTO_SIRC;
  535.         *timeout = IR_SIRC_REPETITION;
  536.         return IR_OK;
  537.     } else if (testRC5(&*address, &*command) == IR_OK) {
  538.         *proto = IR_PROTO_RC5;
  539.         *timeout = IR_RC5_REPETITION;
  540.         return IR_OK;
  541.     } else if (testSharp(&*address, &*command) == IR_OK) {
  542.         *proto = IR_PROTO_SHARP;
  543.         *timeout = IR_SHARP_REPETITION;
  544.         return IR_OK;
  545.     } else if (testNEC(&*address, &*command) == IR_OK) {
  546.         *proto = IR_PROTO_NEC;
  547.         *timeout = IR_NEC_REPETITION;
  548.         return IR_OK;
  549.     } else if (testSamsung(&*address, &*command) == IR_OK) {
  550.         *proto = IR_PROTO_SAMS;
  551.         *timeout = IR_SAMS_REPETITION;
  552.         return IR_OK;
  553.     }
  554.        
  555.     return IR_NO_PROTOCOL;
  556.    
  557. }
  558. #endif
  559.  
  560. //TODO: skriv doxygen-header som för de andra funktionerna
  561. /**
  562.  *
  563.  *
  564.  *
  565.  *
  566.  */
  567. void IrReceive_Init(void) {
  568.     IrTransceiver_Init();
  569.     /*IRDDR &= ~(1<<IRBIT);*/
  570. }
  571.  
  572. //varför är denna funktion så komplex? jo den filtrerar bort korta ir-pulser
  573. //TODO: skriv doxygen-header som för de andra funktionerna
  574. uint8_t IrReceive_CheckIdle(void) {
  575.     if (IRPIN & (1<<IRBIT)) return IR_NO_DATA;      //om irmodulen ger en etta så återgå
  576.    
  577.     //nu lägger irmodulen ut en nolla, "startbiten" alltså
  578.    
  579.     uint16_t timerVal;
  580.    
  581.     //Läs in längden på startbiten
  582.     initTimer();
  583.     while (!(IRPIN & (1<<IRBIT))) {     //vänta på att irmodulen lägger ut en etta
  584.         //om timeout (om timer-ovflow-flaggan sätt)
  585.         if (isTimerOvfl() == 1) return IR_TIME_OVFL;
  586.     }
  587.     timerVal = getTimerVal();
  588.    
  589.     if ((timerVal < IR_MAX_PULSE_WIDTH) && (timerVal > IR_MIN_PULSE_WIDTH)) {
  590.         return IR_OK;
  591.     } //else if ...
  592.    
  593.    
  594.     return IR_NO_PROTOCOL;
  595. }
  596.