Subversion Repositories HomeAutomation

Rev

Rev 800 | Blame | Compare with Previous | Last modification | View Log | SVN | RSS feed

  1. /**
  2.  * Mitel DTMF receiver driver.
  3.  *
  4.  * @date    2007-08-24
  5.  *
  6.  * @author  Anders Runeson
  7.  *  
  8.  */
  9.  
  10. /*-----------------------------------------------------------------------------
  11.  * Includes
  12.  *---------------------------------------------------------------------------*/
  13. //#include <config.h>
  14. #include <avr/io.h>
  15. #include <avr/interrupt.h>
  16. #include <drivers/timer/timer.h>
  17. #include <drivers/DTMF/mt8870/mt8870.h>
  18. #include <config.h>
  19.  
  20. /*-----------------------------------------------------------------------------
  21.  * Globals
  22.  *---------------------------------------------------------------------------*/
  23. uint8_t *rxbuf;
  24. uint8_t rxlen;
  25.  
  26. uint8_t data_overflow;
  27. uint8_t data_received;
  28.  
  29. /*-----------------------------------------------------------------------------
  30.  * Prerequisites
  31.  *---------------------------------------------------------------------------*/
  32.  
  33. #if defined(__AVR_ATmega8__)
  34. #define INT0_REG GICR
  35. #define INT0_CTRL MCUCR
  36. #elif defined(__AVR_ATmega88__) || defined(__AVR_ATmega168__)
  37. #define INT0_REG EIMSK
  38. #define INT0_CTRL EICRA
  39. #else
  40. #error AVR device not supported!
  41. #endif
  42.  
  43. #define MT8870_INT_VECTOR       INT0_vect
  44. #define MT8870_INT_ENABLE()     INT0_REG |= _BV(INT0)
  45. #define MT8870_INT_DISABLE()    INT0_REG &= ~(_BV(INT0))
  46.  
  47. /*-----------------------------------------------------------------------------
  48.  * Interrupt Handlers
  49.  *---------------------------------------------------------------------------*/
  50.  
  51. ISR(MT8870_INT_VECTOR) {
  52.     /* External interrupt 0, rising edge detected */
  53.     uint8_t datain;
  54.    
  55.     /* Read data on input pins */
  56.     datain = ((MT_Q1_PIN >> MT_Q1_BIT) & 0x1);
  57.     datain |= (((MT_Q2_PIN >> MT_Q2_BIT) & 0x1)<<1);
  58.     datain |= (((MT_Q3_PIN >> MT_Q3_BIT) & 0x1)<<2);
  59.     datain |= (((MT_Q4_PIN >> MT_Q4_BIT) & 0x1)<<3);
  60.    
  61.     /* Parse read data and place in buffer */
  62.     switch(datain) {
  63.     case 0:     //DTMF0  = D
  64.         rxbuf[rxlen++] = 0xd;
  65.         break;
  66.     case 1:
  67.     case 2:
  68.     case 3:
  69.     case 4:
  70.     case 5:
  71.     case 6:
  72.     case 7:
  73.     case 8:
  74.     case 9:
  75.         rxbuf[rxlen++] = datain;
  76.         break;
  77.     case 0xa:   //DTMF10 = number 0
  78.         rxbuf[rxlen++] = 0;
  79.         break;
  80.     case 0xb:   //DTMF11 = *
  81.         rxbuf[rxlen++] = 0xe;
  82.         break;
  83.     case 0xc:   //DTMF12 = #
  84.         rxbuf[rxlen++] = 0xf;
  85.         break;
  86.     case 0xd:   //DTMF13 = A
  87.         rxbuf[rxlen++] = 0xa;
  88.         break;
  89.     case 0xe:   //DTMF14 = B
  90.         rxbuf[rxlen++] = 0xb;
  91.         break;
  92.     case 0xf:   //DTMF15 = C
  93.         rxbuf[rxlen++] = 0xc;
  94.         break;
  95.     }
  96.    
  97.     /* Set/reset timer for dial timeout */
  98.     Timer_SetTimeout(MT_TIMER, MT_DIAL_TIMEOUT, TimerTypeOneShot, &DTMFin_timer_callback);
  99.    
  100.     if (rxlen == MT_MAX_TONES) {
  101.         data_overflow = 1;
  102.         MT8870_INT_DISABLE();
  103.     }
  104. }
  105.  
  106.  
  107. /*-----------------------------------------------------------------------------
  108.  * Public Functions
  109.  *---------------------------------------------------------------------------*/
  110.  
  111. // Timer callback function
  112. void DTMFin_timer_callback(uint8_t timer) {
  113.     data_received = 1;
  114.     MT8870_INT_DISABLE();
  115. }
  116.  
  117. void DTMFin_Start(uint8_t *buffer) {
  118.     rxbuf = buffer;
  119.     rxlen = 0;
  120.     data_overflow = 0;
  121.     data_received = 0;
  122.    
  123.     MT8870_INT_ENABLE();
  124. }
  125.  
  126. MT8870_Ret_t DTMFin_Poll(uint8_t *len) {
  127.     *len = rxlen;
  128.     if (data_overflow) {
  129.         return MT8870_Ret_Overflow;
  130.     }
  131.     if (data_received) {
  132.         return MT8870_Ret_Finished;
  133.     }
  134.     return MT8870_Ret_Not_Finished;
  135. }
  136.  
  137. void DTMFin_Init(void) {
  138.     /* set up interrupt on rising edge */
  139.     INT0_CTRL |= _BV(ISC01);
  140.     INT0_CTRL |= _BV(ISC00);
  141.     /* set ports to input */
  142.     MT_StD_DDR &= ~(1<<MT_StD_BIT);
  143.     MT_Q1_DDR &= ~(1<<MT_Q1_BIT);
  144.     MT_Q2_DDR &= ~(1<<MT_Q2_BIT);
  145.     MT_Q3_DDR &= ~(1<<MT_Q3_BIT);
  146.     MT_Q4_DDR &= ~(1<<MT_Q4_BIT);
  147. }
  148.  
  149.