Subversion Repositories HomeAutomation

Rev

Rev 157 | Blame | 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 "irreceiver.h"
  14. #include <avr/io.h>
  15.  
  16. /*-----------------------------------------------------------------------------
  17.  * Globals
  18.  *---------------------------------------------------------------------------*/
  19. volatile uint16_t lastProtoTimeout = 0;
  20.  
  21.  
  22. /*-----------------------------------------------------------------------------
  23.  * Prerequisites
  24.  *---------------------------------------------------------------------------*/
  25.  
  26.  
  27. /*-----------------------------------------------------------------------------
  28.  * Public Functions
  29.  *---------------------------------------------------------------------------*/
  30.  
  31. void initTimer(void) {
  32.     //sätt upp timer
  33.     #if defined(__AVR_ATmega8__)
  34.     TCCR1B = (0<<CS11) | (1<<CS10); // prescaler: 1
  35.     TIFR  |= (1<<TOV1);             // clear overflow flag.
  36.     TCNT1 = 0;
  37.     #endif
  38.     #if defined(__AVR_ATmega88__)
  39.     TCCR1B = (0<<CS11) | (1<<CS10); // prescaler: 1
  40.     TIFR1  |= (1<<TOV1);            // clear overflow flag.
  41.     TCNT1 = 0;
  42.     #endif
  43. }
  44.  
  45. int isTimerOvfl(void) {
  46.     #if defined(__AVR_ATmega8__)
  47.     if (TIFR  & (1<<TOV1)) return 1;
  48.     #endif
  49.     #if defined(__AVR_ATmega88__)
  50.     if (TIFR1  & (1<<TOV1)) return 1;
  51.     #endif
  52.  
  53.     return 0;
  54. }
  55.  
  56. uint16_t getTimerVal(void) {
  57.     #if defined(__AVR_ATmega8__) || defined(__AVR_ATmega88__)
  58.     return TCNT1;
  59.     #endif
  60. }
  61.  
  62. void setTimerVal(uint16_t value) {
  63.     #if defined(__AVR_ATmega8__)
  64.     TCNT1 = value;
  65.     TIFR |= (1<<TOV1);  // clear overflow flag.
  66.     #endif
  67.     #if defined(__AVR_ATmega88__)
  68.     TCNT1 = value;
  69.     TIFR1 |= (1<<TOV1);  // clear overflow flag.
  70.     #endif
  71. }
  72.  
  73. /**
  74.  * Receive RC5 data
  75.  *
  76.  * @param address
  77.  *      Pointer to store the address of the received data
  78.  * @param command
  79.  *      Pointer to store the command of the received data
  80.  */
  81. int receiveRC5(uint8_t *address, uint8_t *command) {
  82.     //printf("startbit of RC5!\n");
  83.     uint8_t i;
  84.     //read second startbit, togglebit and the 5 addressbits
  85.     for (i=0; i<7; i++) {
  86.         //set up a quarter of a bit period time
  87.         setTimerVal(0xFFFF-(IR_RC5_BIT/4));
  88.         //and wait for time to elapse
  89.         while(!isTimerOvfl());
  90.         //reset timer ovfl flag
  91.         setTimerVal(0);
  92.         if (IRPIN & (1<<IRBIT)) {
  93.             //save a one
  94.             *address |= (1<<(6-i));
  95.             //wait for negative slope, while checking timer overflow
  96.             while ((IRPIN & (1<<IRBIT))) {
  97.                 //om timeout (om timer-ovflow-flaggan sätt)
  98.                 if (isTimerOvfl() == 1) return IR_TIME_OVFL;
  99.             }
  100.         } else {
  101.             //save a zero
  102.            
  103.             //wait for positiv slope
  104.             while (!(IRPIN & (1<<IRBIT))) {
  105.                 //om timeout (om timer-ovflow-flaggan sätt)
  106.                 if (isTimerOvfl() == 1) return IR_TIME_OVFL;
  107.             }
  108.         }
  109.         //set up a half a bit period time
  110.         setTimerVal(0xFFFF-(IR_RC5_BIT/2));
  111.         //and wait for time to elapse
  112.         while(!isTimerOvfl());
  113.     }
  114.    
  115.     //read 5 command bits
  116.     for (i=0; i<6; i++) {
  117.         //set up a quarter of a bit period time
  118.         setTimerVal(0xFFFF-(IR_RC5_BIT/4));
  119.         //and wait for time to elapse
  120.         while(!isTimerOvfl());
  121.         //reset timer ovfl flag
  122.         setTimerVal(0);
  123.         if (IRPIN & (1<<IRBIT)) {
  124.             //save a one
  125.             *command |= (1<<(5-i));
  126.             //wait for negative slope, while checking timer overflow
  127.             while ((IRPIN & (1<<IRBIT))) {
  128.                 //om timeout (om timer-ovflow-flaggan sätt).
  129.                 if (isTimerOvfl() == 1) return IR_TIME_OVFL;
  130.             }
  131.         } else {
  132.             //save a zero
  133.            
  134.             //wait for positiv slope
  135.             while (!(IRPIN & (1<<IRBIT))) {
  136.                 //om timeout (om timer-ovflow-flaggan sätt)
  137.                 if (isTimerOvfl() == 1) return IR_TIME_OVFL;
  138.             }
  139.         }
  140.         //set up a half a bit period time
  141.         setTimerVal(0xFFFF-(IR_RC5_BIT/2));
  142.         //and wait for time to elapse
  143.         while(!isTimerOvfl());
  144.     }
  145.    
  146.     //wait for positiv slope to ensure that ir sequence is over
  147.     setTimerVal(0);
  148.     while (!(IRPIN & (1<<IRBIT))) {
  149.         //om timeout (om timer-ovflow-flaggan sätt)
  150.         if (isTimerOvfl() == 1) return IR_TIME_OVFL;
  151.     }
  152.    
  153.     //support RC5-extended by putting the inversion of startbit 2 as the 7th commandbit
  154.     *command |= (~(*address) & 0x40);
  155.     *address &= 0x1f;
  156.     //printf("address %i\n", *address);
  157.     //printf("command %i\n", *command);
  158.    
  159.     return IR_OK;
  160. }
  161.  
  162. uint16_t getLastProtoTimeout(void) {
  163.     return lastProtoTimeout;
  164. }
  165.  
  166. /**
  167.  * Checks if ir-receiver is outputting data, if so then receive it
  168.  *
  169.  * @param proto
  170.  *      Pointer to store the protocol of the received data
  171.  * @param address
  172.  *      Pointer to store the address of the received data
  173.  * @param command
  174.  *      Pointer to store the command of the received data
  175.  * @return
  176.  *      IR_OK if data received successfully, one of several errormessages if not
  177.  */
  178. int checkIr(uint8_t *proto, uint8_t *address, uint8_t *command) {
  179.     if (IRPIN & (1<<IRBIT)) return IR_NO_DATA;      //om irmodulen ger en etta så återgå
  180.    
  181.     //nu lägger irmodulen ut en nolla, "startbiten" alltså
  182.    
  183.     uint16_t timerVal;
  184.    
  185.     *address = 0;
  186.     *command = 0;
  187.    
  188.     //Läs in längden på startbiten
  189.     initTimer();
  190.     while (!(IRPIN & (1<<IRBIT))) {     //vänta på att irmodulen lägger ut en etta
  191.         //om timeout (om timer-ovflow-flaggan sätt)
  192.         if (isTimerOvfl() == 1) return IR_TIME_OVFL;
  193.     }
  194.     timerVal = getTimerVal();
  195.    
  196.     /*
  197.      * Anropa olika funktioner beroende på längden
  198.      * för vissa protokoll behöver längden på första biten skickas med till funktionen?
  199.      * t.ex. sharp?
  200.      * */
  201.    
  202.     if ((timerVal < IR_RC5_ST_BIT+500) && (timerVal > IR_RC5_ST_BIT-500)) {
  203.         *proto = IR_PROTO_RC5;
  204.         return receiveRC5(&*address, &*command);
  205.     } //else if ...
  206.    
  207.    
  208.     return IR_NO_PROTOCOL;
  209. }
  210.  
  211.  
  212. int checkIrIdle(void) {
  213.     if (IRPIN & (1<<IRBIT)) return IR_NO_DATA;      //om irmodulen ger en etta så återgå
  214.    
  215.     //nu lägger irmodulen ut en nolla, "startbiten" alltså
  216.    
  217.     uint16_t timerVal;
  218.    
  219.     //Läs in längden på startbiten
  220.     initTimer();
  221.     while (!(IRPIN & (1<<IRBIT))) {     //vänta på att irmodulen lägger ut en etta
  222.         //om timeout (om timer-ovflow-flaggan sätt)
  223.         if (isTimerOvfl() == 1) return IR_TIME_OVFL;
  224.     }
  225.     timerVal = getTimerVal();
  226.    
  227.     if ((timerVal < IR_MAX_REPEATE_PULSE_WIDTH) && (timerVal > IR_MIN_REPEATE_PULSE_WIDTH)) {
  228.         return IR_OK;
  229.     } //else if ...
  230.    
  231.    
  232.     return IR_NO_PROTOCOL;
  233. }