mbed Phone Platform

Dependencies:   ulaw mbed ConfigFile

Committer:
okini3939
Date:
Thu Jan 20 13:50:10 2011 +0000
Revision:
5:30e2847d241b
Parent:
4:41a3534d085f
Child:
6:bd62b12de751

        

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