Suga koubou / Mbed 2 deprecated PhonePlatform

Dependencies:   ulaw mbed ConfigFile

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers main.cpp Source File

main.cpp

Go to the documentation of this file.
00001 /*
00002  * mbed Phone Platform
00003  * Copyright (c) 2010 Hiroshi Suga
00004  * Released under the MIT License: http://mbed.org/license/mit
00005  */
00006 
00007 /** @file main.cpp
00008  * @brief mbed Phone Platform
00009  */
00010 
00011 #include "mbed.h"
00012 #include "EthernetNetIf.h"
00013 #include "phone.h"
00014 #include "Line.h"
00015 #include "IpLine.h"
00016 
00017 EthernetNetIf *eth;
00018 
00019 Serial pc(USBTX, USBRX);
00020 Ticker ticker;
00021 
00022 DigitalOut led1(LED1), led2(LED2), led3(LED3), led4(LED4);
00023 
00024 AnalogIn adc(p17);
00025 AnalogOut dac(p18);
00026 DigitalOut mixlocal(p21), mixline(p22), micsp(p23);
00027 Line line1(p12, p13, p11, dac);
00028 Line line2(p14, p15, p16, dac);
00029 IpLine *ipline;
00030 
00031 volatile int timeout, dialcount, useipline;
00032 volatile enum PhoneType activesrc, activedest;
00033 char dial[DIAL_SIZE];
00034 struct PhoneBook phonebook[PB_SIZE];
00035 
00036 void int_sample () {
00037     line1.intr();
00038     line2.intr();
00039     if (useipline) {
00040         ipline->intr();
00041     }
00042 
00043     if (timeout) timeout --;
00044 }
00045 
00046 int getpb (enum PhoneType *target, char *hostname) {
00047     int i, j;
00048 
00049     if (dial[0] == 11 && dial[1] >= 1 && dial[1] <= 3) {
00050         *target = (enum PhoneType)dial[1];
00051         hostname[0] = 0;
00052         return 1;
00053     }
00054 
00055     for (i = 0; i < PB_SIZE; i ++) {
00056         for (j = 0; j < DIAL_SIZE; j ++) {
00057             if (phonebook[i].dial[j] == 0 && dial[j] == 0) {
00058                 *target = phonebook[i].target;
00059                 strncpy(hostname, phonebook[i].hostname, HOSTNAME_SIZE);
00060                 return 1;
00061             }
00062             if (phonebook[i].dial[j] == 0 || dial[j] == 0 ||
00063               j >= dialcount || phonebook[i].dial[j] != dial[j]) break;
00064         }
00065     }
00066 
00067     return 0;
00068 }
00069 
00070 void enteranalog (enum PhoneType target) {
00071 
00072     micsp = 0;
00073     mixlocal = 0;
00074     mixline = 0;
00075 
00076     wait_ms(1);
00077     dac.write_u16(0x7fff);
00078 
00079     switch (target) {
00080     case PhoneLine1:
00081     case PhoneLine2:
00082     case PhoneIpLine:
00083         mixline = 1;
00084         break;
00085     case PhoneMicSp:
00086         micsp = 1;
00087         mixlocal = 1;
00088         break;
00089     }
00090 }
00091 
00092 int enterline (enum PhoneType target, enum Mode mode) {
00093 
00094     switch (target) {
00095     case PhoneLine1:
00096         return line1.enter(mode);
00097     case PhoneLine2:
00098         return line2.enter(mode);
00099 /*
00100     case PhoneMicSp:
00101         return micsp.enter(mode);
00102 */
00103     case PhoneIpLine:
00104         return ipline->enter(mode);
00105     }
00106     return 0;
00107 }
00108 
00109 int scanline (enum PhoneType target, enum Scan type) {
00110 
00111     switch (target) {
00112     case PhoneLine1:
00113         return line1.scan(type);
00114     case PhoneLine2:
00115         return line2.scan(type);
00116 /*
00117     case PhoneMicSp:
00118         return micsp.scan(type);
00119 */
00120     case PhoneIpLine:
00121         return ipline->scan(type);
00122     }
00123     return 0;
00124 }
00125 
00126 void checkline (enum PhoneType num) {
00127     int i;
00128 
00129     switch ((enum Mode)scanline(num, ScanMode)) {
00130     case ModeReady:
00131         if (scanline(num, ScanHook) == HookOn && activesrc == PhoneNone) {
00132             // on hook, dial tone
00133             dialcount = 0;
00134             enteranalog(num);
00135             enterline(num, ModeDT);
00136             activesrc = num;
00137         }
00138         break;
00139 
00140     case ModeDT:
00141     case ModeDial:
00142         if (scanline(num, ScanHook) == HookOff) {
00143             // off hook, exit
00144             enterline(num, ModeReady);
00145             activesrc = PhoneNone;
00146             break;
00147         }
00148         i = scanline(num, ScanDial);
00149         if (i > 0 && i < 12) {
00150             // detect dial
00151             dial[dialcount] = i;
00152             dialcount ++;
00153 pc.printf("Dial [%d]\r\n", i);
00154             if (scanline(num, ScanMode) == ModeDT) enterline(num, ModeDial);
00155             timeout = DIAL_TIMEOUT;
00156         }
00157         if ((! timeout && dialcount > 0) || dialcount >= DIAL_SIZE || i >= 12) {
00158             char buf[HOSTNAME_SIZE];
00159             enum PhoneType p;
00160             // call
00161             dial[dialcount] = 0;
00162             if (getpb(&p, buf)) {
00163 printf("-> %d %s\r\n", p, buf);
00164                 if (buf[0] == 0) {
00165                     activedest = p;
00166                 } else
00167                 if (useipline) {
00168                     activedest = PhoneIpLine;
00169                     ipline->settarget(p, buf);
00170                 }
00171                 enterline(num, ModeCall);
00172                 enterline(activedest, ModeRing);
00173                 timeout = CALL_TIMEOUT;
00174             } else {
00175                 enterline(num, ModeBT);
00176             }
00177         }
00178         break;
00179 
00180     case ModeCall:
00181         if (scanline(num, ScanHook) == HookOff) {
00182             // off hook, exit
00183             enterline(num, ModeReady);
00184             enterline(activedest, ModeDisconnect);
00185             activesrc = PhoneNone;
00186             break;
00187         }
00188         i = scanline(activedest, ScanStatus);
00189         if (i == StatusOk) {
00190             // ok call, ring back tone
00191             enterline(num, ModeRBT);
00192         }
00193         if (timeout == 0 || i == StatusNg) {
00194             // timeout, busy
00195             enterline(num, ModeBT);
00196             enterline(activedest, ModeDisconnect);
00197             break;
00198         }
00199         break;
00200 
00201     case ModeRBT:
00202         if (scanline(num, ScanHook) == HookOff) {
00203             // off hook, exit
00204             enterline(num, ModeReady);
00205             enterline(activedest, ModeDisconnect);
00206             activesrc = PhoneNone;
00207         }
00208         break;
00209 
00210     case ModeRing:
00211         if (scanline(num, ScanHook) == HookOn) {
00212             // on hook, connect
00213             if (num == PhoneIpLine || activesrc == PhoneIpLine) {
00214                 enteranalog(PhoneIpLine);
00215             } else {
00216                 enteranalog(PhoneNone);
00217             }
00218             enterline(num, ModeTalk);
00219             enterline(activesrc, ModeTalk);
00220         }
00221         break;
00222 
00223     case ModeTalk:
00224         if (scanline(num, ScanHook) == HookOff) {
00225             // off hook, exit
00226             enterline(num, ModeReady);
00227             enterline(num == activesrc ? activedest : activesrc, ModeDisconnect);
00228             activesrc = PhoneNone;
00229             break;
00230         }
00231         if (scanline(activedest, ScanStatus) == StatusNg) {
00232             // disconnect
00233             enterline(num, ModeBT);
00234         }
00235         break;
00236 
00237     case ModeBT:
00238         if (scanline(num, ScanHook) == HookOff) {
00239             // off hook, exit
00240             enterline(num, ModeReady);
00241             if (activesrc == num) activesrc = PhoneNone;
00242             if (activedest == num) activedest = PhoneNone;
00243         }
00244         break;
00245 
00246     case ModeDisconnect:
00247         enterline(num, ModeBT);
00248         break;
00249 
00250     }
00251 
00252 }
00253 
00254 
00255 int main () {
00256     int i;
00257     
00258     timeout = 0;
00259     useipline = 0;
00260     dialcount = 0;
00261     activesrc = PhoneNone;
00262     activedest = PhoneNone;
00263 
00264     config();
00265 
00266     line1.enter(ModeReady);
00267     line2.enter(ModeReady);
00268     if (useipline) {
00269         ipline = new IpLine(eth, dac, adc);
00270         ipline->enter(ModeReady);
00271     }
00272 
00273 //    NVIC_SetPriority(TIMER3_IRQn, 0); // preemption=1, sub-priority=1
00274     ticker.attach_us(&int_sample, 1000000 / FREQ);
00275 
00276     for (;;) {
00277         if (useipline) {
00278             led1 = 1;
00279             ipline->poll();
00280             led1 = 0;
00281         }
00282         led2 = 1;
00283         line1.poll();
00284         led2 = 0;
00285         led3 = 1;
00286         line2.poll();
00287         led3 = 0;
00288 
00289         i = scanline(PhoneLine1, ScanMode);
00290         checkline(PhoneLine1);
00291         if (i != scanline(PhoneLine1, ScanMode))
00292             pc.printf("(1) %d -> %d\r\n", i, scanline(PhoneLine1, ScanMode));
00293         
00294         i = scanline(PhoneLine2, ScanMode);
00295         checkline(PhoneLine2);
00296         if (i != scanline(PhoneLine2, ScanMode))
00297             pc.printf("(2) %d -> %d\r\n", i, scanline(PhoneLine2, ScanMode));
00298         
00299         if (useipline) {
00300             i = scanline(PhoneIpLine, ScanMode);
00301             checkline(PhoneIpLine);
00302             if (i != scanline(PhoneIpLine, ScanMode))
00303                 pc.printf("(3) %d -> %d\r\n", i, scanline(PhoneIpLine, ScanMode));
00304         }
00305         
00306     }
00307 }