mbed Phone Platform

Dependencies:   ulaw mbed ConfigFile

Committer:
okini3939
Date:
Fri Jan 21 16:06:15 2011 +0000
Revision:
6:bd62b12de751
Parent:
5:30e2847d241b

        

Who changed what in which revision?

UserRevisionLine numberNew contents of line
okini3939 2:e37117117e79 1 /** @file Line.cpp
okini3939 2:e37117117e79 2 * @brief Line Controller (mbed Phone Platform)
okini3939 2:e37117117e79 3 */
okini3939 2:e37117117e79 4
okini3939 1:0f82c574096f 5 #include "Line.h"
okini3939 1:0f82c574096f 6
okini3939 1:0f82c574096f 7 #define RING_ON FREQ
okini3939 1:0f82c574096f 8 #define RING_OFF (FREQ * 3)
okini3939 1:0f82c574096f 9 #define RING_PULSE (FREQ / 16)
okini3939 1:0f82c574096f 10 #define TONE_DT (FREQ / 400)
okini3939 1:0f82c574096f 11 #define TONE_RBT_ON FREQ
okini3939 1:0f82c574096f 12 #define TONE_RBT_OFF (FREQ * 3)
okini3939 1:0f82c574096f 13 #define TONE_BT_ON (FREQ / 2)
okini3939 1:0f82c574096f 14 #define TONE_BT_OFF FREQ
okini3939 1:0f82c574096f 15 #define HOOK_TIME FREQ
okini3939 1:0f82c574096f 16 #define DIAL_TIME (FREQ / 2)
okini3939 1:0f82c574096f 17
okini3939 1:0f82c574096f 18 const unsigned short tonetable[TONE_DT] = {
okini3939 1:0f82c574096f 19 0x7fff, 0x98f4, 0xaf78, 0xc156, 0xcccf, 0xd0c3, 0xcccf, 0xc156, 0xaf78, 0x98f4,
okini3939 1:0f82c574096f 20 0x7fff, 0x6709, 0x5085, 0x3ea7, 0x332e, 0x2f3a, 0x332e, 0x3ea7, 0x5085, 0x6709
okini3939 1:0f82c574096f 21 };
okini3939 1:0f82c574096f 22
okini3939 1:0f82c574096f 23 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) {
okini3939 1:0f82c574096f 24 hook.mode(PullUp);
okini3939 1:0f82c574096f 25 mode = ModeOff;
okini3939 1:0f82c574096f 26 status = StatusOk;
okini3939 1:0f82c574096f 27 dialtimer = 0;
okini3939 1:0f82c574096f 28 dialcount = 0;
okini3939 1:0f82c574096f 29 hooktimer = 0;
okini3939 1:0f82c574096f 30 tonecount = 0;
okini3939 6:bd62b12de751 31 hooktimer2 = 0;
okini3939 1:0f82c574096f 32 hook_last = hook;
okini3939 1:0f82c574096f 33 }
okini3939 1:0f82c574096f 34
okini3939 2:e37117117e79 35 /**
okini3939 2:e37117117e79 36 * @brief 8KHz interrupt
okini3939 2:e37117117e79 37 */
okini3939 2:e37117117e79 38 void Line::intr () {
okini3939 1:0f82c574096f 39
okini3939 1:0f82c574096f 40 switch (mode) {
okini3939 1:0f82c574096f 41 case ModeRing:
okini3939 1:0f82c574096f 42 ring();
okini3939 1:0f82c574096f 43 break;
okini3939 1:0f82c574096f 44
okini3939 1:0f82c574096f 45 case ModeDT:
okini3939 1:0f82c574096f 46 tone(DialTone);
okini3939 1:0f82c574096f 47 break;
okini3939 1:0f82c574096f 48
okini3939 1:0f82c574096f 49 case ModeRBT:
okini3939 1:0f82c574096f 50 tone(RingBackTone);
okini3939 1:0f82c574096f 51 break;
okini3939 1:0f82c574096f 52
okini3939 1:0f82c574096f 53 case ModeBT:
okini3939 1:0f82c574096f 54 tone(BusyTone);
okini3939 1:0f82c574096f 55 break;
okini3939 1:0f82c574096f 56
okini3939 1:0f82c574096f 57 }
okini3939 1:0f82c574096f 58
okini3939 1:0f82c574096f 59 if (hook) {
okini3939 1:0f82c574096f 60 // off hook
okini3939 1:0f82c574096f 61 if (hooktimer) hooktimer --;
okini3939 1:0f82c574096f 62
okini3939 6:bd62b12de751 63 if (! hook_last && (dialcount > 0 || hooktimer2 >= DIAL_TIME)) {
okini3939 1:0f82c574096f 64 // dial trigger
okini3939 1:0f82c574096f 65 dialtimer = DIAL_TIME;
okini3939 1:0f82c574096f 66 dialcount ++;
okini3939 6:bd62b12de751 67 hooktimer2 = 0;
okini3939 1:0f82c574096f 68 }
okini3939 1:0f82c574096f 69 } else {
okini3939 1:0f82c574096f 70 // on hook
okini3939 1:0f82c574096f 71 hooktimer = HOOK_TIME;
okini3939 6:bd62b12de751 72 hooktimer2 ++;
okini3939 1:0f82c574096f 73 }
okini3939 1:0f82c574096f 74 hook_last = hook;
okini3939 1:0f82c574096f 75
okini3939 1:0f82c574096f 76 if (dialtimer) {
okini3939 1:0f82c574096f 77 dialtimer --;
okini3939 1:0f82c574096f 78
okini3939 1:0f82c574096f 79 if (dialtimer == 0 && dialcount && ! hook) {
okini3939 1:0f82c574096f 80 // dial detected
okini3939 1:0f82c574096f 81 dial.put(dialcount);
okini3939 1:0f82c574096f 82 dialcount = 0;
okini3939 1:0f82c574096f 83 }
okini3939 1:0f82c574096f 84 } else {
okini3939 1:0f82c574096f 85 dialcount = 0;
okini3939 1:0f82c574096f 86 }
okini3939 1:0f82c574096f 87 }
okini3939 1:0f82c574096f 88
okini3939 4:41a3534d085f 89 void Line::poll () {
okini3939 4:41a3534d085f 90 }
okini3939 4:41a3534d085f 91
okini3939 2:e37117117e79 92 /**
okini3939 2:e37117117e79 93 * @brief change mode
okini3939 2:e37117117e79 94 * @param newmode mode of line
okini3939 2:e37117117e79 95 * @retval 0 ok
okini3939 2:e37117117e79 96 */
okini3939 1:0f82c574096f 97 int Line::enter (enum Mode newmode) {
okini3939 1:0f82c574096f 98
okini3939 1:0f82c574096f 99 // cleanup
okini3939 1:0f82c574096f 100 switch (mode) {
okini3939 1:0f82c574096f 101 case ModeRing:
okini3939 1:0f82c574096f 102 case ModeOff:
okini3939 1:0f82c574096f 103 power(1);
okini3939 1:0f82c574096f 104 break;
okini3939 1:0f82c574096f 105
okini3939 1:0f82c574096f 106 case ModeDT:
okini3939 1:0f82c574096f 107 case ModeRBT:
okini3939 1:0f82c574096f 108 case ModeBT:
okini3939 5:30e2847d241b 109 dac.write_u16(0x7fff);
okini3939 1:0f82c574096f 110 break;
okini3939 1:0f82c574096f 111
okini3939 1:0f82c574096f 112 }
okini3939 1:0f82c574096f 113
okini3939 1:0f82c574096f 114 mode = newmode;
okini3939 1:0f82c574096f 115
okini3939 1:0f82c574096f 116 switch (mode) {
okini3939 1:0f82c574096f 117 case ModeReady:
okini3939 1:0f82c574096f 118 // ready
okini3939 1:0f82c574096f 119 power(1);
okini3939 1:0f82c574096f 120 status = StatusOk;
okini3939 1:0f82c574096f 121 break;
okini3939 1:0f82c574096f 122
okini3939 1:0f82c574096f 123 case ModeDT:
okini3939 1:0f82c574096f 124 case ModeRBT:
okini3939 1:0f82c574096f 125 case ModeBT:
okini3939 1:0f82c574096f 126 // tone
okini3939 1:0f82c574096f 127 tonecount = 0;
okini3939 1:0f82c574096f 128 status = StatusOk;
okini3939 1:0f82c574096f 129 break;
okini3939 1:0f82c574096f 130
okini3939 1:0f82c574096f 131 case ModeOff:
okini3939 1:0f82c574096f 132 // suspend
okini3939 1:0f82c574096f 133 power(0);
okini3939 1:0f82c574096f 134 status = StatusOk;
okini3939 1:0f82c574096f 135 break;
okini3939 1:0f82c574096f 136
okini3939 1:0f82c574096f 137 default:
okini3939 1:0f82c574096f 138 status = StatusOk;
okini3939 1:0f82c574096f 139 break;
okini3939 1:0f82c574096f 140
okini3939 1:0f82c574096f 141 }
okini3939 1:0f82c574096f 142
okini3939 1:0f82c574096f 143 return 0;
okini3939 1:0f82c574096f 144 }
okini3939 1:0f82c574096f 145
okini3939 2:e37117117e79 146 /**
okini3939 2:e37117117e79 147 * @brief return status
okini3939 2:e37117117e79 148 * @param type Type of status
okini3939 2:e37117117e79 149 * @return status
okini3939 2:e37117117e79 150 */
okini3939 1:0f82c574096f 151 int Line::scan (enum Scan type) {
okini3939 1:0f82c574096f 152
okini3939 1:0f82c574096f 153 switch (type) {
okini3939 1:0f82c574096f 154 case ScanMode:
okini3939 1:0f82c574096f 155 return (int)mode;
okini3939 1:0f82c574096f 156
okini3939 1:0f82c574096f 157 case ScanStatus:
okini3939 1:0f82c574096f 158 return (int)status;
okini3939 1:0f82c574096f 159
okini3939 1:0f82c574096f 160 case ScanHook:
okini3939 1:0f82c574096f 161 return hooktimer ? HookOn : HookOff;
okini3939 1:0f82c574096f 162
okini3939 1:0f82c574096f 163 case ScanDial:
okini3939 1:0f82c574096f 164 char c;
okini3939 1:0f82c574096f 165 if (! dial.get(c)) {
okini3939 1:0f82c574096f 166 return c;
okini3939 1:0f82c574096f 167 }
okini3939 1:0f82c574096f 168 break;
okini3939 1:0f82c574096f 169
okini3939 1:0f82c574096f 170 }
okini3939 1:0f82c574096f 171
okini3939 1:0f82c574096f 172 return -1;
okini3939 1:0f82c574096f 173 }
okini3939 1:0f82c574096f 174
okini3939 2:e37117117e79 175 /**
okini3939 2:e37117117e79 176 * @brief power of line
okini3939 2:e37117117e79 177 * @param flg 0:off, 1:on(positive), -1:on(negative)
okini3939 2:e37117117e79 178 */
okini3939 1:0f82c574096f 179 void Line::power (int flg) {
okini3939 1:0f82c574096f 180 if (flg > 0) {
okini3939 1:0f82c574096f 181 xline = 0;
okini3939 1:0f82c574096f 182 wait_ms(1);
okini3939 1:0f82c574096f 183 line = 1;
okini3939 1:0f82c574096f 184 } else
okini3939 1:0f82c574096f 185 if (flg < 0) {
okini3939 1:0f82c574096f 186 line = 0;
okini3939 1:0f82c574096f 187 wait_ms(1);
okini3939 1:0f82c574096f 188 xline = 1;
okini3939 1:0f82c574096f 189 } else {
okini3939 1:0f82c574096f 190 line = 0;
okini3939 1:0f82c574096f 191 xline = 0;
okini3939 1:0f82c574096f 192 }
okini3939 1:0f82c574096f 193 }
okini3939 1:0f82c574096f 194
okini3939 1:0f82c574096f 195 /// ring
okini3939 1:0f82c574096f 196 void Line::ring () {
okini3939 1:0f82c574096f 197 if (hook && tonecount < RING_ON) {
okini3939 1:0f82c574096f 198 // off hook
okini3939 1:0f82c574096f 199 switch (tonecount % RING_PULSE) {
okini3939 1:0f82c574096f 200 case 0:
okini3939 1:0f82c574096f 201 Line::power(0);
okini3939 1:0f82c574096f 202 break;
okini3939 1:0f82c574096f 203 case RING_PULSE / 10:
okini3939 1:0f82c574096f 204 Line::power(-1);
okini3939 1:0f82c574096f 205 break;
okini3939 1:0f82c574096f 206 case RING_PULSE / 2:
okini3939 1:0f82c574096f 207 Line::power(0);
okini3939 1:0f82c574096f 208 break;
okini3939 1:0f82c574096f 209 case RING_PULSE / 2 + RING_PULSE / 10:
okini3939 1:0f82c574096f 210 Line::power(1);
okini3939 1:0f82c574096f 211 break;
okini3939 1:0f82c574096f 212 }
okini3939 1:0f82c574096f 213 }
okini3939 1:0f82c574096f 214
okini3939 1:0f82c574096f 215 tonecount ++;
okini3939 1:0f82c574096f 216 if (tonecount >= RING_OFF) tonecount = 0;
okini3939 1:0f82c574096f 217 }
okini3939 1:0f82c574096f 218
okini3939 1:0f82c574096f 219 /// tone
okini3939 1:0f82c574096f 220 void Line::tone (enum Tone type) {
okini3939 1:0f82c574096f 221 if (! hook && ( type == DialTone ||
okini3939 4:41a3534d085f 222 (type == RingBackTone && tonecount < TONE_RBT_ON && (tonecount % RING_PULSE) < (RING_PULSE / 2)) ||
okini3939 1:0f82c574096f 223 (type == BusyTone && tonecount < TONE_BT_ON) ) ) {
okini3939 1:0f82c574096f 224 // on hook
okini3939 1:0f82c574096f 225 dac.write_u16(tonetable[tonecount % TONE_DT]);
okini3939 1:0f82c574096f 226 } else {
okini3939 1:0f82c574096f 227 // off hook
okini3939 1:0f82c574096f 228 dac.write_u16(0x7fff);
okini3939 1:0f82c574096f 229 }
okini3939 1:0f82c574096f 230
okini3939 1:0f82c574096f 231 tonecount ++;
okini3939 1:0f82c574096f 232 if ( (type == DialTone && tonecount >= TONE_DT) ||
okini3939 1:0f82c574096f 233 (type == RingBackTone && tonecount >= TONE_RBT_OFF) ||
okini3939 1:0f82c574096f 234 (type == BusyTone && tonecount >= TONE_BT_OFF) ) {
okini3939 1:0f82c574096f 235 tonecount = 0;
okini3939 1:0f82c574096f 236 }
okini3939 1:0f82c574096f 237 }