Subversion Repositories HomeAutomation

Rev

Rev 1415 | 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/DTMF/dtmf.h>
  17. #include <drivers/DTMF/mt8870/mt8870.h>
  18. #include <config.h>
  19.  
  20. /*-----------------------------------------------------------------------------
  21.  * Globals
  22.  *---------------------------------------------------------------------------*/
  23. uint8_t mt_rxbuf[MT_MAX_TONES];
  24. uint8_t mt_rxlen;
  25.  
  26. uint8_t mt_data_overflow;
  27.  
  28. /*-----------------------------------------------------------------------------
  29.  * Prerequisites
  30.  *---------------------------------------------------------------------------*/
  31.  
  32. #if defined(__AVR_ATmega8__)
  33. #define INT0_REG GICR
  34. #define INT0_CTRL MCUCR
  35. #elif defined(__AVR_ATmega88__) || defined(__AVR_ATmega168__) || defined(__AVR_ATmega168P__) || defined(__AVR_ATmega328P__)
  36. #define INT0_REG EIMSK
  37. #define INT0_CTRL EICRA
  38. #else
  39. #error AVR device not supported!
  40. #endif
  41.  
  42. #define MT8870_INT_VECTOR       INT0_vect
  43. #define MT8870_INT_ENABLE()     INT0_REG |= _BV(INT0)
  44. #define MT8870_INT_DISABLE()    INT0_REG &= ~(_BV(INT0))
  45.  
  46. /*-----------------------------------------------------------------------------
  47.  * Interrupt Handlers
  48.  *---------------------------------------------------------------------------*/
  49.  
  50. ISR(MT8870_INT_VECTOR) {
  51.     /* External interrupt 0, rising edge detected */
  52.     uint8_t mt_datain;
  53.    
  54.     /* Read data on input pins */
  55.     mt_datain = ((MT_Q1_PIN >> MT_Q1_BIT) & 0x1);
  56.     mt_datain |= (((MT_Q2_PIN >> MT_Q2_BIT) & 0x1)<<1);
  57.     mt_datain |= (((MT_Q3_PIN >> MT_Q3_BIT) & 0x1)<<2);
  58.     mt_datain |= (((MT_Q4_PIN >> MT_Q4_BIT) & 0x1)<<3);
  59.    
  60.     /* Parse read data and place in buffer */
  61.     switch(mt_datain) {
  62.     case 0:     //DTMF0  = D
  63.         mt_rxbuf[mt_rxlen++] = 0xd;
  64.         break;
  65.     case 1:
  66.     case 2:
  67.     case 3:
  68.     case 4:
  69.     case 5:
  70.     case 6:
  71.     case 7:
  72.     case 8:
  73.     case 9:
  74.         mt_rxbuf[mt_rxlen++] = mt_datain;
  75.         break;
  76.     case 0xa:   //DTMF10 = number 0
  77.         mt_rxbuf[mt_rxlen++] = 0;
  78.         break;
  79.     case 0xb:   //DTMF11 = *
  80.         mt_rxbuf[mt_rxlen++] = 0xe;
  81.         break;
  82.     case 0xc:   //DTMF12 = #
  83.         mt_rxbuf[mt_rxlen++] = 0xf;
  84.         break;
  85.     case 0xd:   //DTMF13 = A
  86.         mt_rxbuf[mt_rxlen++] = 0xa;
  87.         break;
  88.     case 0xe:   //DTMF14 = B
  89.         mt_rxbuf[mt_rxlen++] = 0xb;
  90.         break;
  91.     case 0xf:   //DTMF15 = C
  92.         mt_rxbuf[mt_rxlen++] = 0xc;
  93.         break;
  94.     }
  95.    
  96.     if (mt_rxlen >= MT_MAX_TONES) {
  97.         mt_data_overflow = 1;
  98.         mt_rxlen=0;
  99.     }
  100. }
  101.  
  102.  
  103. /*-----------------------------------------------------------------------------
  104.  * Public Functions
  105.  *---------------------------------------------------------------------------*/
  106.  
  107. DTMF_Ret_t mt8870_Pop(uint8_t *buffer, uint8_t *len) {
  108.     DTMF_Ret_t mt_returndata = DTMF_Ret_No_data;
  109.     *len = 0;
  110.     if (mt_rxlen > 0) {
  111.         cli();
  112.         *len = mt_rxlen;
  113.         for (uint8_t i=0; i<*len; i++) {
  114.             buffer[i] = mt_rxbuf[i];
  115.         }
  116.         mt_rxlen = 0;
  117.         sei();
  118.         if (mt_data_overflow) {
  119.             mt_data_overflow = 0;
  120.             mt_returndata = DTMF_Ret_Overflow;
  121.         } else {
  122.             mt_returndata = DTMF_Ret_Data_avail;
  123.         }
  124.     }
  125.     return mt_returndata;
  126. }
  127.  
  128. void mt8870_Init(void) {
  129.     /* set up interrupt on rising edge */
  130.     INT0_CTRL |= _BV(ISC01);
  131.     INT0_CTRL |= _BV(ISC00);
  132.     /* set ports to input */
  133.     MT_StD_DDR &= ~(1<<MT_StD_BIT);
  134.     MT_Q1_DDR &= ~(1<<MT_Q1_BIT);
  135.     MT_Q2_DDR &= ~(1<<MT_Q2_BIT);
  136.     MT_Q3_DDR &= ~(1<<MT_Q3_BIT);
  137.     MT_Q4_DDR &= ~(1<<MT_Q4_BIT);
  138.    
  139.     mt_rxlen = 0;
  140.     mt_data_overflow = 0;
  141.     MT8870_INT_ENABLE();
  142. }
  143.  
  144.