Subversion Repositories HomeAutomation

Rev

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

  1. /**
  2.  * dtmf generator.
  3.  * AVR AppNote314
  4.  *
  5.  * @date    2007-03-15
  6.  * @author  Anders Runeson arune at sf dot net
  7.  *  
  8.  */
  9.  
  10. /*-----------------------------------------------------------------------------
  11.  * Includes
  12.  *---------------------------------------------------------------------------*/
  13. #include "dtmfgenerate.h"
  14.  
  15. /*-----------------------------------------------------------------------------
  16.  * Globals
  17.  *---------------------------------------------------------------------------*/
  18. uint16_t x_SWh = 0x00;               // step width of high frequency
  19. uint16_t x_SWl = 0x00;               // step width of low frequency
  20. uint16_t  i_CurSinValA = 0;           // position freq. A in LUT (extended format)
  21. uint16_t  i_CurSinValB = 0;           // position freq. B in LUT (extended format)
  22. //***************************  x_SW  ***************************************
  23. //Table of x_SW (excess 8): x_SW = ROUND(FP*N_SAMPLES*f*256/Fck)
  24. //**************************************************************************
  25. //high frequency (coloun)   8MHz128     20MHz256
  26. //1209hz  ---> x_SW =       79          1014
  27. //1336hz  ---> x_SW =       87          1121
  28. //1477hz  ---> x_SW =       96          1239
  29. //1633hz  ---> x_SW =       107         1370
  30. uint16_t auc_frequencyH [4] = {1370, 1239, 1121, 1014};
  31.  
  32. //low frequency (row)
  33. //697hz  ---> x_SW =        46          585
  34. //770hz  ---> x_SW =        50          646
  35. //852hz  ---> x_SW =        56          715
  36. //941hz  ---> x_SW =        61          789
  37. uint16_t auc_frequencyL [4] = {789, 715, 646, 585};
  38. /*************************** SIN TABLE *************************************
  39.  * Samples table : one period sampled on 128 samples and
  40.  * quantized on 7 bit
  41.  **************************************************************************/
  42. //nu i flash? prog_
  43. //skala om till 7bit amplitud       prog_
  44. int8_t auc_SinParam [64] = {
  45. 63, 63, 63, 63, 63, 63, 62, 62, 62, 61, 61, 61, 60, 60, 59, 59, 58, 58, 57,
  46. 56, 56, 55, 54, 53, 52, 52, 51, 50, 49, 48, 47, 46, 45, 43, 42, 41, 40, 39,
  47. 38, 36, 35, 34, 32, 31, 30, 28, 27, 26, 24, 23, 21, 20, 18, 17, 15, 14, 12,
  48. 11,  9,  8,  6,  5,  3,  2 };
  49.  
  50.  
  51. /*
  52.  * Timer0 overflow interrupt
  53.  * occurs at 78.125kHz (20MHz/256)
  54.  */
  55. ISR(SIG_OVERFLOW0) {
  56.     uint8_t  i_TmpSinValA;               // position freq. A in LUT (actual position)
  57.     uint8_t  i_TmpSinValB;               // position freq. B in LUT (actual position)
  58.  
  59.     // move Pointer about step width aheaed
  60.     i_CurSinValA += x_SWh;
  61.     i_CurSinValB += x_SWl;
  62.     // normalize Temp-Pointer
  63.     i_TmpSinValA    =   (uint8_t)(((i_CurSinValA+4) >> FPSHIFT)&(N_SAMPLES-1));
  64.     i_TmpSinValB    =   (uint8_t)(((i_CurSinValB+4) >> FPSHIFT)&(N_SAMPLES-1));
  65.     // calculate PWM value: high frequency value + 3/4 low frequency value
  66.     //OCR0A = (auc_SinParam[i_TmpSinValA] + (auc_SinParam[i_TmpSinValB]-(auc_SinParam[i_TmpSinValB]>>2)));
  67.     int8_t tmpVal;
  68.     if (i_TmpSinValB<N_SAMPLES/4) {
  69.         tmpVal = auc_SinParam[ i_TmpSinValB ];
  70.         tmpVal -= tmpVal/4;
  71.     } else if (i_TmpSinValB<N_SAMPLES/2) {
  72.         tmpVal = -auc_SinParam[ (N_SAMPLES/2-1)-i_TmpSinValB ];
  73.         tmpVal -= tmpVal/4;
  74.     } else if (i_TmpSinValB<N_SAMPLES*3/4) {
  75.         tmpVal = -auc_SinParam[ i_TmpSinValB-(N_SAMPLES/2) ];
  76.         tmpVal -= tmpVal/4;
  77.     } else {
  78.         tmpVal = auc_SinParam[ (N_SAMPLES-1)-i_TmpSinValB ];
  79.         tmpVal -= tmpVal/4;
  80.     }
  81.     if (i_TmpSinValA<N_SAMPLES/4) {
  82.         tmpVal += auc_SinParam[ i_TmpSinValA ];
  83.     } else if (i_TmpSinValA<N_SAMPLES/2) {
  84.         tmpVal += -auc_SinParam[ (N_SAMPLES/2-1)-i_TmpSinValA ];
  85.     } else if (i_TmpSinValA<N_SAMPLES*3/4) {
  86.         tmpVal += -auc_SinParam[ i_TmpSinValA-(N_SAMPLES/2) ];
  87.     } else {
  88.         tmpVal += auc_SinParam[ (N_SAMPLES-1)-i_TmpSinValA ];
  89.     }
  90.  
  91.     OCR0A = tmpVal+128;
  92.     //OCR0A = 128;
  93. }
  94.  
  95.  
  96. uint8_t DTMFOUT_Init (void) {
  97.     TIMSK0 = (1<<TOIE0);                // Timer0 interrupt overflow enabled
  98.     TCCR0A = ((1<<COM0A1)|(1<<WGM00)|(1<<WGM01));   // non inverting / 8Bit PWM
  99.     TCCR0B = (1<<CS00);                 // CLK/1
  100.     DDRD |= (1<<PD6);                   // PD5 (OC0A) as output
  101.    
  102.     x_SWh=1014;
  103.     x_SWl=789;
  104.     return 1;
  105. }
  106.  
  107. void DTMFOUT_Send (uint8_t tone) {
  108.     /*
  109.     {0x1, 0x2, 0x3, 0xA},
  110.     {0x4, 0x5, 0x6, 0xB},
  111.     {0x7, 0x8, 0x9, 0xC},
  112.     {0xE, 0x0, 0xF, 0xD}};
  113.     */
  114.    
  115.        
  116. }
  117.  
  118. //funktion man anropar med 0/1/2/3/4/5/6/7/8/9/a/b/c/d/*/# och den öppnar porten (ddrd|=(1>>pd6)),
  119. //aktiverar timer overfl int, lägger rätt värden i x_SWh och x_SWl,
  120. //efter en viss tid ska tysnad läggas ut, stänger av timer ovfl int och sätter porten högimpedans
  121.  
  122. //en funktion som kallas under tiden ska returnera status, om man sänder ton eller tysnad eller klar
  123. //ISRen kan sköta statemashinen med ton och tystnad
  124.  
  125. //x_SWh = auc_frequencyH[0];
  126.  
  127.