Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependencies: ulaw mbed ConfigFile
Line.cpp
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 }
Generated on Wed Jul 13 2022 04:31:14 by
1.7.2