mbed Phone Platform
Dependencies: ulaw mbed ConfigFile
main.cpp
- Committer:
- okini3939
- Date:
- 2011-01-21
- Revision:
- 6:bd62b12de751
- Parent:
- 5:30e2847d241b
File content as of revision 6:bd62b12de751:
/* * mbed Phone Platform * Copyright (c) 2010 Hiroshi Suga * Released under the MIT License: http://mbed.org/license/mit */ /** @file main.cpp * @brief mbed Phone Platform */ #include "mbed.h" #include "EthernetNetIf.h" #include "phone.h" #include "Line.h" #include "IpLine.h" EthernetNetIf *eth; 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); IpLine *ipline; volatile int timeout, dialcount, useipline; volatile enum PhoneType activesrc, activedest; char dial[DIAL_SIZE]; struct PhoneBook phonebook[PB_SIZE]; void int_sample () { line1.intr(); line2.intr(); if (useipline) { ipline->intr(); } if (timeout) timeout --; } int getpb (enum PhoneType *target, char *hostname) { int i, j; if (dial[0] == 11 && dial[1] >= 1 && dial[1] <= 3) { *target = (enum PhoneType)dial[1]; hostname[0] = 0; return 1; } for (i = 0; i < PB_SIZE; i ++) { for (j = 0; j < DIAL_SIZE; j ++) { if (phonebook[i].dial[j] == 0 && dial[j] == 0) { *target = phonebook[i].target; strncpy(hostname, phonebook[i].hostname, HOSTNAME_SIZE); return 1; } if (phonebook[i].dial[j] == 0 || dial[j] == 0 || j >= dialcount || phonebook[i].dial[j] != dial[j]) break; } } return 0; } void enteranalog (enum PhoneType target) { micsp = 0; mixlocal = 0; mixline = 0; wait_ms(1); dac.write_u16(0x7fff); switch (target) { case PhoneLine1: case PhoneLine2: case PhoneIpLine: 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: 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: 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 && i < 12) { // detect dial dial[dialcount] = i; dialcount ++; pc.printf("Dial [%d]\r\n", i); if (scanline(num, ScanMode) == ModeDT) enterline(num, ModeDial); timeout = DIAL_TIMEOUT; } if ((! timeout && dialcount > 0) || dialcount >= DIAL_SIZE || i >= 12) { char buf[HOSTNAME_SIZE]; enum PhoneType p; // call dial[dialcount] = 0; if (getpb(&p, buf)) { printf("-> %d %s\r\n", p, buf); if (buf[0] == 0) { activedest = p; } else if (useipline) { activedest = PhoneIpLine; ipline->settarget(p, buf); } enterline(num, ModeCall); enterline(activedest, ModeRing); timeout = CALL_TIMEOUT; } else { enterline(num, ModeBT); } } break; case ModeCall: if (scanline(num, ScanHook) == HookOff) { // off hook, exit enterline(num, ModeReady); enterline(activedest, ModeDisconnect); activesrc = PhoneNone; break; } i = scanline(activedest, ScanStatus); if (i == StatusOk) { // ok call, ring back tone enterline(num, ModeRBT); } if (timeout == 0 || i == StatusNg) { // timeout, busy enterline(num, ModeBT); enterline(activedest, ModeDisconnect); break; } 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(PhoneIpLine); } 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(activedest, 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; timeout = 0; useipline = 0; dialcount = 0; activesrc = PhoneNone; activedest = PhoneNone; config(); line1.enter(ModeReady); line2.enter(ModeReady); if (useipline) { ipline = new IpLine(eth, dac, adc); ipline->enter(ModeReady); } // NVIC_SetPriority(TIMER3_IRQn, 0); // preemption=1, sub-priority=1 ticker.attach_us(&int_sample, 1000000 / FREQ); for (;;) { if (useipline) { led1 = 1; ipline->poll(); led1 = 0; } led2 = 1; line1.poll(); led2 = 0; led3 = 1; line2.poll(); led3 = 0; i = scanline(PhoneLine1, ScanMode); checkline(PhoneLine1); if (i != scanline(PhoneLine1, ScanMode)) pc.printf("(1) %d -> %d\r\n", i, scanline(PhoneLine1, ScanMode)); i = scanline(PhoneLine2, ScanMode); checkline(PhoneLine2); if (i != scanline(PhoneLine2, ScanMode)) pc.printf("(2) %d -> %d\r\n", i, scanline(PhoneLine2, ScanMode)); if (useipline) { i = scanline(PhoneIpLine, ScanMode); checkline(PhoneIpLine); if (i != scanline(PhoneIpLine, ScanMode)) pc.printf("(3) %d -> %d\r\n", i, scanline(PhoneIpLine, ScanMode)); } } }