mbed Phone Platform

Dependencies:   ulaw mbed ConfigFile

Revision:
0:f18953137cb4
Child:
1:0f82c574096f
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/main.cpp	Mon Dec 20 22:55:29 2010 +0000
@@ -0,0 +1,236 @@
+/*
+ * mbed Phone Platform
+ * Copyright (c) 2010 Hiroshi Suga
+ * Released under the MIT License: http://mbed.org/license/mit
+ */
+
+/** @file
+ * @brief mbed Phone Platform
+ */
+#include "mbed.h"
+#include "Line.h"
+
+Serial pc(USBTX, USBRX);
+Ticker ticker;
+
+DigitalOut led1(LED1), led2(LED2), led3(LED3), led4(LED4);
+
+AnalogIn adc(p17);
+AnalogOut dac(p18);
+DigitalOut mixlocal(p21), mixline(p22), micsp(p23);
+Line line1(p12, p13, p11, dac);
+Line line2(p14, p15, p16, dac);
+
+DigitalOut led_y(p25), led_g(p26);
+DigitalIn eth_link(P1_25), eth_speed(P1_26);
+
+volatile int timeout;
+int dialcount;
+char dial[DIAL_SIZE];
+enum PhoneType activesrc, activedest;
+
+void int_sample () {
+    if (timeout) timeout --;
+    line1.poll();
+    line2.poll();
+//    Net::poll();
+}
+
+int dialbook () {
+    return PhoneLine2;
+}
+
+void enteranalog (enum PhoneType target) {
+
+    micsp = 0;
+    mixlocal = 0;
+    mixline = 0;
+
+    wait_ms(1);
+    dac = 0x7fff;
+
+    switch (target) {
+    case PhoneLine1:
+    case PhoneLine2:
+        mixline = 1;
+        break;
+    case PhoneMicSp:
+        micsp = 1;
+        mixlocal = 1;
+        break;
+    }
+}
+
+int enterline (enum PhoneType target, enum Mode mode) {
+
+    switch (target) {
+    case PhoneLine1:
+        return line1.enter(mode);
+    case PhoneLine2:
+        return line2.enter(mode);
+/*
+    case PhoneMicSp:
+        return micsp.enter(mode);
+    case PhoneIpLine:
+        ipline.target(dial[1]);
+        return ipline.enter(mode);
+*/
+    }
+    return 0;
+}
+
+int scanline (enum PhoneType target, enum Scan type) {
+
+    switch (target) {
+    case PhoneLine1:
+        return line1.scan(type);
+    case PhoneLine2:
+        return line2.scan(type);
+/*
+    case PhoneMicSp:
+        return micsp.scan(type);
+    case PhoneIpLine:
+        ipline.target(dial[1]);
+        return ipline.scan(type);
+*/
+    }
+    return 0;
+}
+
+void checkline (enum PhoneType num) {
+    int i;
+
+    switch ((enum Mode)scanline(num, ScanMode)) {
+    case ModeReady:
+        if (scanline(num, ScanHook) == HookOn && activesrc == PhoneNone) {
+            // on hook, dial tone
+            dialcount = 0;
+            enteranalog(num);
+            enterline(num, ModeDT);
+            activesrc = num;
+        }
+        break;
+
+    case ModeDT:
+    case ModeDial:
+        if (scanline(num, ScanHook) == HookOff) {
+            // off hook, exit
+            enterline(num, ModeReady);
+            activesrc = PhoneNone;
+            break;
+        }
+        i = scanline(num, ScanDial);
+        if (i > 0) {
+            // detect dial
+            dial[dialcount] = i;
+            dialcount ++;
+pc.printf(" [ %d ] ", i);
+            if (scanline(num, ScanMode) == ModeDT) enterline(num, ModeDial);
+            timeout = FREQ * 5;
+        }
+        if ((! timeout && dialcount > 0) || dialcount >= DIAL_SIZE) {
+            // call
+            activedest = (enum PhoneType)dialbook();
+            enterline(num, ModeCall);
+            enterline(activedest, ModeRing);
+            timeout = FREQ * 10;
+        }
+        break;
+
+    case ModeCall:
+        if (scanline(num, ScanHook) == HookOff) {
+            // off hook, exit
+            enterline(num, ModeReady);
+            enterline(activedest, ModeDisconnect);
+            activesrc = PhoneNone;
+            break;
+        }
+        if (timeout == 0) {
+            // timeout, busy
+            enterline(num, ModeBT);
+            enterline(activedest, ModeDisconnect);
+            break;
+        }
+        if (scanline(num, ScanStatus) == StatusOk) {
+            // ok call, ring back tone
+            enterline(num, ModeRBT);
+        }
+        break;
+
+    case ModeRBT:
+        if (scanline(num, ScanHook) == HookOff) {
+            // off hook, exit
+            enterline(num, ModeReady);
+            enterline(activedest, ModeDisconnect);
+            activesrc = PhoneNone;
+        }
+        break;
+
+    case ModeRing:
+        if (scanline(num, ScanHook) == HookOn) {
+            // on hook, connect
+            if (num == PhoneIpLine || activesrc == PhoneIpLine) {
+                enteranalog(activesrc);
+            } else {
+                enteranalog(PhoneNone);
+            }
+            enterline(num, ModeTalk);
+            enterline(activesrc, ModeTalk);
+        }
+        break;
+
+    case ModeTalk:
+        if (scanline(num, ScanHook) == HookOff) {
+            // off hook, exit
+            enterline(num, ModeReady);
+            enterline(num == activesrc ? activedest : activesrc, ModeDisconnect);
+            activesrc = PhoneNone;
+            break;
+        }
+        if (scanline(num, ScanStatus) == StatusNg) {
+            // disconnect
+            enterline(num, ModeBT);
+        }
+        break;
+
+    case ModeBT:
+        if (scanline(num, ScanHook) == HookOff) {
+            // off hook, exit
+            enterline(num, ModeReady);
+            if (activesrc == num) activesrc = PhoneNone;
+            if (activedest == num) activedest = PhoneNone;
+        }
+        break;
+
+    case ModeDisconnect:
+        enterline(num, ModeBT);
+        break;
+
+    }
+
+}
+
+
+int main () {
+    int i, len;
+    char buf[MTU];
+
+    timeout = 0;
+    dialcount = 0;
+    activesrc = PhoneNone;
+    activedest = PhoneNone;
+    line1.enter(ModeReady);
+    line2.enter(ModeReady);
+
+    ticker.attach_us(&int_sample, 1000000 / FREQ);
+
+    for (;;) {
+        pc.printf("1: %d - ", scanline(PhoneLine1, ScanMode));
+        checkline(PhoneLine1);
+        pc.printf("%d / ", scanline(PhoneLine1, ScanMode));
+        pc.printf("2: %d - ", scanline(PhoneLine2, ScanMode));
+        checkline(PhoneLine2);
+        pc.printf("%d\r\n", scanline(PhoneLine2, ScanMode));
+        wait(0.2);
+    }
+}