Suga koubou / Mbed 2 deprecated PhonePlatform

Dependencies:   ulaw mbed ConfigFile

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers Line.cpp Source File

Line.cpp

Go to the documentation of this file.
00001 /** @file Line.cpp
00002  * @brief Line Controller (mbed Phone Platform)
00003  */
00004 
00005 #include "Line.h"
00006 
00007 #define RING_ON FREQ
00008 #define RING_OFF (FREQ * 3)
00009 #define RING_PULSE (FREQ / 16)
00010 #define TONE_DT (FREQ / 400)
00011 #define TONE_RBT_ON FREQ
00012 #define TONE_RBT_OFF (FREQ * 3)
00013 #define TONE_BT_ON (FREQ / 2)
00014 #define TONE_BT_OFF FREQ
00015 #define HOOK_TIME FREQ
00016 #define DIAL_TIME (FREQ / 2)
00017 
00018 const unsigned short tonetable[TONE_DT] = {
00019     0x7fff, 0x98f4, 0xaf78, 0xc156, 0xcccf, 0xd0c3, 0xcccf, 0xc156, 0xaf78, 0x98f4,
00020     0x7fff, 0x6709, 0x5085, 0x3ea7, 0x332e, 0x2f3a, 0x332e, 0x3ea7, 0x5085, 0x6709
00021 };
00022 
00023 Line::Line (PinName p_line, PinName p_xline, PinName p_hook, AnalogOut p_dac) : line(p_line), xline(p_xline), hook(p_hook), dac(p_dac), dial(DIAL_SIZE) {
00024     hook.mode(PullUp);
00025     mode = ModeOff;
00026     status = StatusOk;
00027     dialtimer = 0;
00028     dialcount = 0;
00029     hooktimer = 0;
00030     tonecount = 0;
00031     hooktimer2 = 0;
00032     hook_last = hook;
00033 }
00034 
00035 /**
00036  * @brief 8KHz interrupt
00037  */
00038 void Line::intr () {
00039 
00040     switch (mode) {
00041     case ModeRing:
00042         ring();
00043         break;
00044 
00045     case ModeDT:
00046         tone(DialTone);
00047         break;
00048 
00049     case ModeRBT:
00050         tone(RingBackTone);
00051         break;
00052 
00053     case ModeBT:
00054         tone(BusyTone);
00055         break;
00056 
00057     }
00058 
00059     if (hook) {
00060         // off hook
00061         if (hooktimer) hooktimer --;
00062 
00063         if (! hook_last && (dialcount > 0 || hooktimer2 >= DIAL_TIME)) {
00064             // dial trigger
00065             dialtimer = DIAL_TIME;
00066             dialcount ++;
00067             hooktimer2 = 0;
00068         }
00069     } else {
00070         // on hook
00071         hooktimer = HOOK_TIME;
00072         hooktimer2 ++;
00073     }
00074     hook_last = hook;
00075 
00076     if (dialtimer) {
00077         dialtimer --;
00078 
00079         if (dialtimer == 0 && dialcount && ! hook) {
00080             // dial detected
00081             dial.put(dialcount);
00082             dialcount = 0;
00083         }
00084     } else {
00085         dialcount = 0;
00086     }
00087 }
00088 
00089 void Line::poll () {
00090 }
00091 
00092 /**
00093  * @brief change mode
00094  * @param newmode mode of line
00095  * @retval 0 ok
00096  */
00097 int Line::enter (enum Mode newmode) {
00098 
00099     // cleanup
00100     switch (mode) {
00101     case ModeRing:
00102     case ModeOff:
00103         power(1);
00104         break;
00105 
00106     case ModeDT:
00107     case ModeRBT:
00108     case ModeBT:
00109         dac.write_u16(0x7fff);
00110         break;
00111 
00112     }
00113 
00114     mode = newmode;
00115 
00116     switch (mode) {
00117     case ModeReady:
00118         // ready
00119         power(1);
00120         status = StatusOk;
00121         break;
00122 
00123     case ModeDT:
00124     case ModeRBT:
00125     case ModeBT:
00126         // tone
00127         tonecount = 0;
00128         status = StatusOk;
00129         break;
00130 
00131     case ModeOff:
00132         // suspend
00133         power(0);
00134         status = StatusOk;
00135         break;
00136 
00137     default:
00138         status = StatusOk;
00139         break;
00140 
00141     }
00142 
00143     return 0;
00144 }
00145 
00146 /**
00147  * @brief return status
00148  * @param type Type of status
00149  * @return status
00150  */
00151 int Line::scan (enum Scan type) {
00152 
00153     switch (type) {
00154     case ScanMode:
00155         return (int)mode;
00156 
00157     case ScanStatus:
00158         return (int)status;
00159 
00160     case ScanHook:
00161         return hooktimer ? HookOn : HookOff;
00162 
00163     case ScanDial:
00164         char c;
00165         if (! dial.get(c)) {
00166             return c;
00167         }
00168         break;
00169 
00170     }
00171 
00172     return -1;
00173 }
00174 
00175 /**
00176  * @brief power of line
00177  * @param flg 0:off, 1:on(positive), -1:on(negative)
00178  */
00179 void Line::power (int flg) {
00180     if (flg > 0) {
00181         xline = 0;
00182         wait_ms(1);
00183         line = 1;
00184     } else
00185     if (flg < 0) {
00186         line = 0;
00187         wait_ms(1);
00188         xline = 1;
00189     } else {
00190         line = 0;
00191         xline = 0;
00192     }
00193 }
00194 
00195 /// ring
00196 void Line::ring () {
00197     if (hook && tonecount < RING_ON) {
00198         // off hook
00199         switch (tonecount % RING_PULSE) {
00200         case 0:
00201             Line::power(0);
00202             break;
00203         case RING_PULSE / 10:
00204             Line::power(-1);
00205             break;
00206         case RING_PULSE / 2:
00207             Line::power(0);
00208             break;
00209         case RING_PULSE / 2 + RING_PULSE / 10:
00210             Line::power(1);
00211             break;
00212         }
00213     }
00214 
00215     tonecount ++;
00216     if (tonecount >= RING_OFF) tonecount = 0;
00217 }
00218 
00219 /// tone
00220 void Line::tone (enum Tone type) {
00221     if (! hook && ( type == DialTone ||
00222       (type == RingBackTone && tonecount < TONE_RBT_ON && (tonecount % RING_PULSE) < (RING_PULSE / 2)) ||
00223       (type == BusyTone && tonecount < TONE_BT_ON) ) ) {
00224         // on hook
00225         dac.write_u16(tonetable[tonecount % TONE_DT]);
00226     } else {
00227         // off hook
00228         dac.write_u16(0x7fff);
00229     }
00230 
00231     tonecount ++;
00232     if ( (type == DialTone && tonecount >= TONE_DT) ||
00233       (type == RingBackTone && tonecount >= TONE_RBT_OFF) ||
00234       (type == BusyTone && tonecount >= TONE_BT_OFF) ) {
00235         tonecount = 0;
00236     }
00237 }