mbed Phone Platform
Dependencies: ulaw mbed ConfigFile
Line.cpp
- Committer:
- okini3939
- Date:
- 2010-12-26
- Revision:
- 1:0f82c574096f
- Parent:
- 0:f18953137cb4
- Child:
- 2:e37117117e79
File content as of revision 1:0f82c574096f:
#include "Line.h" #define RING_ON FREQ #define RING_OFF (FREQ * 3) #define RING_PULSE (FREQ / 16) #define TONE_DT (FREQ / 400) #define TONE_RBT_ON FREQ #define TONE_RBT_OFF (FREQ * 3) #define TONE_BT_ON (FREQ / 2) #define TONE_BT_OFF FREQ #define HOOK_TIME FREQ #define DIAL_TIME (FREQ / 2) const unsigned short tonetable[TONE_DT] = { 0x7fff, 0x98f4, 0xaf78, 0xc156, 0xcccf, 0xd0c3, 0xcccf, 0xc156, 0xaf78, 0x98f4, 0x7fff, 0x6709, 0x5085, 0x3ea7, 0x332e, 0x2f3a, 0x332e, 0x3ea7, 0x5085, 0x6709 }; 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) { hook.mode(PullUp); mode = ModeOff; status = StatusOk; dialtimer = 0; dialcount = 0; hooktimer = 0; tonecount = 0; hook_last = hook; } /// 8KHz interrupt void Line::poll () { switch (mode) { case ModeRing: ring(); break; case ModeDT: tone(DialTone); break; case ModeRBT: tone(RingBackTone); break; case ModeBT: tone(BusyTone); break; } if (hook) { // off hook if (hooktimer) hooktimer --; if (! hook_last) { // dial trigger dialtimer = DIAL_TIME; dialcount ++; } } else { // on hook hooktimer = HOOK_TIME; } hook_last = hook; if (dialtimer) { dialtimer --; if (dialtimer == 0 && dialcount && ! hook) { // dial detected dial.put(dialcount); dialcount = 0; } } else { dialcount = 0; } } /// change mode int Line::enter (enum Mode newmode) { // cleanup switch (mode) { case ModeRing: case ModeOff: power(1); break; case ModeDT: case ModeRBT: case ModeBT: dac = 0x7fff; break; } mode = newmode; switch (mode) { case ModeReady: // ready power(1); status = StatusOk; break; case ModeDT: case ModeRBT: case ModeBT: // tone tonecount = 0; status = StatusOk; break; case ModeOff: // suspend power(0); status = StatusOk; break; default: status = StatusOk; break; } return 0; } /// return status int Line::scan (enum Scan type) { switch (type) { case ScanMode: return (int)mode; case ScanStatus: return (int)status; case ScanHook: return hooktimer ? HookOn : HookOff; case ScanDial: char c; if (! dial.get(c)) { return c; } break; } return -1; } /// controll power void Line::power (int flg) { if (flg > 0) { xline = 0; wait_ms(1); line = 1; } else if (flg < 0) { line = 0; wait_ms(1); xline = 1; } else { line = 0; xline = 0; } } /// ring void Line::ring () { if (hook && tonecount < RING_ON) { // off hook switch (tonecount % RING_PULSE) { case 0: Line::power(0); break; case RING_PULSE / 10: Line::power(-1); break; case RING_PULSE / 2: Line::power(0); break; case RING_PULSE / 2 + RING_PULSE / 10: Line::power(1); break; } } tonecount ++; if (tonecount >= RING_OFF) tonecount = 0; } /// tone void Line::tone (enum Tone type) { if (! hook && ( type == DialTone || (type == RingBackTone && tonecount < TONE_RBT_ON) || (type == BusyTone && tonecount < TONE_BT_ON) ) ) { // on hook dac.write_u16(tonetable[tonecount % TONE_DT]); } else { // off hook dac.write_u16(0x7fff); } tonecount ++; if ( (type == DialTone && tonecount >= TONE_DT) || (type == RingBackTone && tonecount >= TONE_RBT_OFF) || (type == BusyTone && tonecount >= TONE_BT_OFF) ) { tonecount = 0; } }