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