mbed Phone Platform

Dependencies:   ulaw mbed ConfigFile

Committer:
okini3939
Date:
Mon Dec 20 22:55:29 2010 +0000
Revision:
0:f18953137cb4
Child:
1:0f82c574096f

        

Who changed what in which revision?

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