hndshake.c
上传用户:sdttscl
上传日期:2010-01-04
资源大小:683k
文件大小:26k
源码类别:

Modem编程

开发平台:

C/C++

  1. //---------------------------------------------------------------------------------------------------
  2. // Project:- DE8681
  3. //   Filename:- HNDSHAKE.C
  4. // Description:- Handshaking Routines for CMX868.
  5. // Programmer:- D.T.F
  6. // Version:- 2.0
  7. // Created:- 28th February 2002
  8. // Last modified:- 
  9. //---------------------------------------------------------------------------------------------------
  10. // (C) Consumer Microcircuits Ltd 2002
  11. //
  12. // This firmware was designed by:-
  13. // Consumer Microcircuits Ltd,
  14. // Langford, Maldon,
  15. // ESSEX
  16. // CM9 6WG.
  17. // in the UK for use with CML evaluation kits only and is based on UK originated technology.
  18. // Please contact
  19. // sales@cmlmicro.co.uk
  20. // +44 (0)1621 875500
  21. // for licensing details.
  22. //---------------------------------------------------------------------------------------------------
  23. #define HNDSHAKE_C
  24. #include "ef8681.h"
  25. void hndshake_init()
  26. {
  27. reset_cbus(); // Reset the CBUS before we start, will clear all shadow write registers
  28. pwrup(); // Power Up CMX868 with correct Xtal and fixed equalisers initially enabled.
  29. CMXTXMODE ^= (((int) S25) << 9) & 0x0E00; // Extract required Tx level from S25.
  30. wr16_cbus(CMXTXMODE_ADDR, CMXTXMODE); // Update CBUS register
  31. CMXRXMODE ^= (((int) S26) << 9) & 0x0E00; // Extract required Rx level from S26.
  32. wr16_cbus(CMXRXMODE_ADDR, CMXRXMODE); // Update CBUS register
  33. FIX_EQU = USER_FIX_EQU; // Extract required Tx and Rx Fixed Equaliser settings from S24.
  34. wr16_cbus(CMXGENCTRL_ADDR, CMXGENCTRL); // Update CBUS register
  35. }
  36. unsigned char hndshake_go()
  37. {
  38. unsigned char tmpresult;
  39. if (ANSORIG) // Check S14 Bit 7, if set we are originating a call
  40. {
  41. GPT6 = S7; // Load GPT6 (1s) with Wait for carrier after dial S-Register
  42. switch(S27 & 0b11110000)
  43. {
  44. case PROTB0: case PROTB1:
  45. tmpresult = orig_V22bis();
  46. break;
  47. case PROTB2:
  48. tmpresult = orig_V23();
  49. break;
  50. case PROTB3:
  51. tmpresult = orig_V23r();
  52. break;
  53. case PROTB4:
  54. tmpresult = orig_V22_600();
  55. break;
  56. case PROTB5:
  57. tmpresult = orig_V21();
  58. break;
  59. case PROTB6:
  60. tmpresult = orig_212a();
  61. break;
  62. case PROTB7:
  63. tmpresult = orig_202();
  64. break;
  65. case PROTB8:
  66. tmpresult = orig_202r();
  67. break;
  68. case PROTB9:
  69. tmpresult = orig_103();
  70. break;
  71. default:
  72. return(ERROR); // Indicate Error has occured 
  73. }
  74. }
  75. else
  76. {
  77. GPT6 = S18; // Load GPT6 (1s) with General Purpose timer setting
  78. switch(S27 & 0b11110000)
  79. {
  80. case PROTB0: case PROTB1:
  81. ans_tone();
  82. tmpresult = ans_V22bis();
  83. break;
  84. case PROTB2:
  85. ans_tone();
  86. tmpresult = ans_V23();
  87. break;
  88. case PROTB3:
  89. ans_tone();
  90. tmpresult = ans_V23r();
  91. break;
  92. case PROTB4:
  93. ans_tone();
  94. tmpresult = ans_V22_600();
  95. break;
  96. case PROTB5:
  97. ans_tone();
  98. tmpresult = ans_V21();
  99. break;
  100. case PROTB6:
  101. tmpresult = ans_212a();
  102. break;
  103. case PROTB7:
  104. tmpresult = ans_202();
  105. break;
  106. case PROTB8:
  107. tmpresult = ans_202r();
  108. break;
  109. case PROTB9:
  110. tmpresult = ans_103();
  111. break;
  112. default:
  113. return(ERROR); // Indicate Error has occured
  114. }
  115. }
  116. if ((tmpresult != NYI) && (tmpresult != NOCARRIER))
  117. {
  118. DATAXFER = 1;
  119. ATCMDMODE = 0;
  120. switch(S22 & 0b11100000)
  121. {
  122. case X0CALLING:
  123. return(CONNECT);
  124. default:
  125. return(tmpresult);
  126. }
  127. }
  128. else
  129. {
  130. return(tmpresult);
  131. }
  132. }
  133. unsigned char orig_V22bis()
  134. {
  135. unsigned char det32ones = 0;
  136. unsigned char tx2400flag = 0;
  137. unsigned char gotS1pattern = 0;
  138. // Stage 1 Look for unscrambled 1's or 2225Hz tone
  139. CMXRXMODE &= 0x0E00; // Mask Rx Gain settings 
  140. CMXRXMODE ^= 0x1002; // Setup Rx for 2225Hz Answer Tone Detection (will detect unscram 1's)
  141. wr16_cbus(CMXRXMODE_ADDR, CMXRXMODE); // Update Rx Mode CBUS register
  142. GPT1 = 12; // Start 150ms timer (Answer Tone detector has approx 30ms response time)
  143. do {
  144. DelayMs(5); // Insert 5ms polling delay 
  145. if (KEYABORT || (GPT6 == 0))
  146. { // Return No Carrier message if key pushed or
  147. return(NOCARRIER); // if wait carrier after dial timer has expired
  148. }
  149. CMXSTAT = rd16_cbus(CMXSTAT_ADDR); // Read status register and update shadow register
  150. if (!ANS2225DET) // If 2225Hz Answer Tone is not detected
  151. {
  152. GPT1 = 12; // Restart 2225Hz Answer Tone detect timer
  153. }
  154. } while(GPT1 != 0); // Continue to loop until unscram 1's detected for approx 150ms
  155. // Stage 2 Wait for 450ms
  156. CMXRXMODE &= 0x0E00; // Mask Rx Gain settings 
  157. CMXRXMODE ^= 0xD0F8; // Setup Rx for high band V.22 1200bps, auto-equaliser disabled,
  158. // Descrambler enabled and synchronous operation
  159. wr16_cbus(CMXRXMODE_ADDR,CMXRXMODE); // Update Rx Mode CBUS register
  160. GPT1 = 45; // Start 450ms timer
  161. do {
  162. if (KEYABORT || (GPT6 == 0))
  163. { // Return No Carrier message if key pushed or
  164. return(NOCARRIER); // if wait carrier after dial timer has expired
  165. }
  166. } while (GPT1 != 0);
  167. // Stage 3 Tx S1 Pattern if V22bis selected
  168. if ((S27 & 0b11110000) == PROTB0) 
  169. {
  170. CMXTXMODE &= 0x0E00; // Mask Tx Gain settings 
  171. CMXTXMODE ^= 0xC018; // Initially setup Tx for low band V.22 1200bps, no guard tone
  172. // No Guard tone, scrambler Disabled, synchronous operation and Tx S1 pattern
  173. wr16_cbus(CMXTXMODE_ADDR, CMXTXMODE); // Update Tx Mode CBUS register
  174. GPT1 = 10; // Start 100ms timer
  175. do {
  176. if (KEYABORT || (GPT6 == 0))
  177. { // Return No Carrier message if key pushed or
  178. return(NOCARRIER); // if wait carrier after dial timer has expired
  179. }
  180. } while(GPT1 !=0); // Wait for 100ms timer to expire
  181. }
  182. // Stage 4 Tx 1200bps scrambled 1's
  183. CMXTXDATA = 0xFF;
  184. wr_cbus(CMXTXDATA_ADDR, CMXTXDATA); // Ensure Tx data reg is all 1's
  185. CMXTXMODE &= 0x0E00; // Mask Tx gain settings
  186. CMXTXMODE ^= 0xC07F; // Setup Tx for low band V.22 1200bps, no guard tone
  187. // Scrambler enabled, sync operation and Tx data byte reg
  188. wr16_cbus(CMXTXMODE_ADDR,CMXTXMODE); // Update Tx Mode CBUS register
  189. // Stage 5 Look for S1 pattern if V22bis selected
  190. if ((S27 & 0b11110000) == PROTB0)
  191. {
  192. GPT1 = 27; // Start 270ms timer
  193. do {
  194. DelayMs(5); // Insert 5ms polling delay 
  195. if (KEYABORT || (GPT6 == 0))
  196. { // Return No Carrier message if key pushed or
  197. return(NOCARRIER); // if wait carrier after dial timer has expired
  198. }
  199. CMXSTAT = rd16_cbus(CMXSTAT_ADDR); // Read status register and update shadow register
  200. if (RXENERGYDET && S1DET)
  201. {
  202. gotS1pattern = 1; // Set flag to indicate S1 pattern was found
  203. }
  204. } while((GPT1 != 0) && !gotS1pattern); // Continue to loop until timer expires or S1 pattern is detected
  205. }
  206. if (gotS1pattern)
  207. {
  208. // Stage 6 If the S1 pattern was detected wait until it goes away 
  209. do {
  210. DelayMs(5); // Insert 5ms polling delay 
  211. if (KEYABORT || (GPT6 == 0))
  212. { // Return No Carrier message if key pushed or
  213. return(NOCARRIER); // if wait carrier after dial timer has expired
  214. }
  215. CMXSTAT = rd16_cbus(CMXSTAT_ADDR); // Read status register and update shadow register
  216. } while(S1DET); // Wait until S1 Pattern has gone
  217. // Stage 7
  218. GPT1 = 60; // Start 600ms timer
  219. do {
  220. if (KEYABORT || (GPT6 == 0))
  221. { // Return No Carrier message if key pushed or
  222. return(NOCARRIER); // if general purpose timer (S18) has expired
  223. }
  224. } while (GPT1 >= 30); // Wait until 300ms has expired
  225. AUTO_EQU = 1; // Enable Rx Auto-Equaliser for training (must be enabled for 2400bps operation)
  226. wr16_cbus(CMXRXMODE_ADDR, CMXRXMODE); // Update Rx Mode CBUS register
  227. do {
  228. if (KEYABORT || (GPT6 == 0))
  229. { // Return No Carrier message if key pushed or
  230. return(NOCARRIER); // if wait carrier after dial timer has expired
  231. }
  232. } while (GPT1 >= 15); // Wait until 450ms has expired
  233. // Stage 8 Switch Rx Mode to 2400bps (Detectors and associated status flags will be reset)
  234. CMXRXMODE &= 0x0FFF; // Unmask Rx Mode bit settings
  235. CMXRXMODE ^= 0xF000; // Setup Rx for high band V.22bis 2400bps
  236. wr16_cbus(CMXRXMODE_ADDR, CMXRXMODE); // Update Rx Mode CBUS register
  237. // Stage 9 Wait until 32 continuous 1's are detected and transmitter has switched to 2400bps scram 1's
  238. do {
  239. DelayMs(5); // Insert 5ms polling delay 
  240. if (KEYABORT || (GPT6 == 0))
  241. { // Return No Carrier message if key pushed or
  242. return(NOCARRIER); // if wait carrier after dial timer has expired
  243. }
  244. if (!tx2400flag)
  245. {
  246. if (GPT1 == 0) // Check if 600ms timer has expired
  247. {
  248. CMXTXMODE &= 0x0FFF; // Unmask Tx Mode bit settings
  249. CMXTXMODE ^= 0xE000; // Setup Tx for low band V.22 bis 2400bps
  250. wr16_cbus(CMXTXMODE_ADDR, CMXTXMODE); // Update Tx Mode CBUS register
  251. GPT1 = 20; // Load 200ms Timer
  252. tx2400flag = 1;
  253. }
  254. }
  255. CMXSTAT = rd16_cbus(CMXSTAT_ADDR); // Read status register and update shadow register
  256. if (RXENERGYDET && CONTA && CONTB && !det32ones)
  257. {
  258. DCDN = 0; // Clear DCDN line.
  259. DCDIND = 1; // Turn on CD LED.
  260. det32ones = 1; // Set detect 32 1's flag
  261. }
  262. } while(!RXENERGYDET || !CONTA || !CONTB || !tx2400flag); // Wait until 2400bps cont 1's is detected and
  263. // 2400bps has started transmitting
  264. // Stage 10 Ensure final 200ms timer has expired
  265. do {
  266. if (KEYABORT || (GPT6 == 0))
  267. { // Return No Carrier message if key pushed or
  268. return(NOCARRIER); // if wait carrier after dial timer has expired
  269. }
  270. } while (GPT1 != 0); // Ensure 200ms timer has expired
  271. }
  272. else
  273. {
  274. if (((S27 & 0b11110000) == PROTB0) && !FALLBACK)
  275. {
  276. return(NOCARRIER); // Return No Carrier message
  277. }
  278. // Stage 11 Detect scrambled 1's for 270ms
  279. GPT1 = 24; // Start 270ms timer (scram 1's detect has approx 30ms (32 bits) response time)
  280. do {
  281. DelayMs(5); // Insert 5ms polling delay 
  282. if (KEYABORT || (GPT6 == 0))
  283. { // Return No Carrier message if key pushed or
  284. return(NOCARRIER); // if wait carrier after dial timer has expired
  285. }
  286. CMXSTAT = rd16_cbus(CMXSTAT_ADDR); // Read status register and update shadow register
  287. if (!RXENERGYDET || !CONTA || !CONTB) // If rx energy or scram 1's are not detected
  288. {
  289. GPT1 = 24; // Restart scram 1's detect timer
  290. }
  291. } while(GPT1 != 0); // Continue to loop until scram 1's detected for approx 270ms
  292. AUTO_EQU = USER_AUTO_EQU; // Extract Auto Equaliser setting from S24.
  293. wr16_cbus(CMXRXMODE_ADDR,CMXRXMODE); // Update Rx Mode CBUS register
  294. DCDN = 0; // Clear DCDN line.
  295. DCDIND = 1; // Turn on CD LED.
  296. // Stage 12 Start 770ms timer
  297. GPT1 = 77;
  298. do {
  299. if (KEYABORT || (GPT6 == 0))
  300. { // Return No Carrier message if key pushed or
  301. return(NOCARRIER); // if wait carrier after dial timer has expired
  302. }
  303. } while (GPT1 != 0); // Wait until 770ms has expired
  304. }
  305. // Stage 13
  306. async_setup(); // Configure Tx/Rx for async operation (settings extracted from S25 and S26)
  307. if (!gotS1pattern)
  308. {
  309. return(CON1200); // Return Connect 1200
  310. }
  311. else
  312. {
  313. return(CON2400); // Return Connect 2400
  314. }
  315. }
  316. unsigned char orig_V23()
  317. {
  318. // Stage 1
  319. CMXRXMODE &= 0x0E00; // Mask Rx Gain settings
  320. CMXRXMODE ^= 0x5038; // Setup Rx for V23 1200bps and auto-equaliser disabled
  321. // Descrambler Disabled, synchronous operation
  322. wr16_cbus(CMXRXMODE_ADDR,CMXRXMODE); // Update Rx Mode CBUS register
  323. if (unscram1sdet(12) != OK) return(NOCARRIER); // Detect unscram 1's for 150ms (1's detect has approx 30ms (32bits) response time)
  324. // Stage 2
  325. DCDN = 0; // Clear DCDN line.
  326. DCDIND = 1; // Turn on CD LED.
  327. GPT1 = 77; // Start 770ms timer
  328. do {
  329. if (KEYABORT || (GPT6 == 0))
  330. { // Return No Carrier message if key pushed or
  331. return(NOCARRIER); // if wait carrier after dial timer has expired
  332. }
  333. } while (GPT1 >= 32); // Wait until 450ms has expired
  334. // Stage 3
  335. CMXTXDATA = 0xFF;
  336. wr_cbus(CMXTXDATA_ADDR,CMXTXDATA); // Ensure Tx data reg is all 1's
  337. CMXTXMODE &= 0x0E00; // Mask Tx Gain Settings
  338. CMXTXMODE ^= 0x401F; // Setup Tx for V23 75bps, no guard tone
  339. // No Guard tone, scram disabled, sync operation, Tx data byte reg
  340. wr16_cbus(CMXTXMODE_ADDR,CMXTXMODE); // Update Tx Mode CBUS register
  341. // Stage 4
  342. do {
  343. if (KEYABORT || (GPT6 == 0))
  344. { // Return No Carrier message if key pushed or
  345. return(NOCARRIER); // if wait carrier after dial timer has expired
  346. }
  347. } while (GPT1 != 0); // Ensure 770ms timer has expired
  348. // Stage 5
  349. async_setup(); // Configure Tx/Rx for async operation (settings extracted from S25 and S26)
  350. return(CON751200); // Return Connect 75/1200
  351. }
  352. unsigned char orig_V23r()
  353. {
  354. return(NYI);
  355. }
  356. unsigned char orig_V22_600()
  357. {
  358. return(NYI);
  359. }
  360. unsigned char orig_V21()
  361. {
  362. return(NYI);
  363. }
  364. unsigned char orig_212a()
  365. {
  366. return(NYI);
  367. }
  368. unsigned char orig_202()
  369. {
  370. return(NYI);
  371. }
  372. unsigned char orig_202r()
  373. {
  374. return(NYI);
  375. }
  376. unsigned char orig_103()
  377. {
  378. // Stage 1
  379. CMXRXMODE &= 0x0E00; // Mask Rx Gain settings
  380. CMXRXMODE ^= 0x7038; // Setup Rx for high band Bell 103 300bps and auto-equaliser disabled
  381. // Descrambler Disabled and synchronous operation
  382. wr16_cbus(CMXRXMODE_ADDR,CMXRXMODE); // Update Rx Mode CBUS register
  383. if (unscram1sdet(5) != OK) return(NOCARRIER); // Detect unscram 1's for 150ms (1's detect has approx 100ms (32bits) response time)
  384. // Stage 2
  385. DCDN = 0; // Clear DCDN line.
  386. DCDIND = 1; // Turn on CD LED.
  387. GPT1 = 77; // Start 770ms timer
  388. do {
  389. if (KEYABORT || (GPT6 == 0))
  390. { // Return No Carrier message if key pushed or
  391. return(NOCARRIER); // if wait carrier after dial timer has expired
  392. }
  393. } while (GPT1 >= 32); // Wait until 450ms has expired
  394. // Stage 3
  395. CMXTXDATA = 0xFF;
  396. wr_cbus(CMXTXDATA_ADDR,CMXTXDATA); // Ensure Tx data reg is all 1's
  397. CMXTXMODE &= 0x0E00; // Mask Tx Gain settings
  398. CMXTXMODE ^= 0x601F; // Setup Tx for low band Bell 103 300bps, no guard tone
  399. // No Guard tone, scram disabled, sync operation, Tx data byte reg
  400. wr16_cbus(CMXTXMODE_ADDR,CMXTXMODE); // Update Tx Mode CBUS register
  401. // Stage 4
  402. do {
  403. if (KEYABORT || (GPT6 == 0))
  404. { // Return No Carrier message if key pushed or
  405. return(NOCARRIER); // if wait carrier after dial timer has expired
  406. }
  407. } while (GPT1 != 0); // Ensure 770ms timer has expired
  408. // Stage 5
  409. async_setup(); // Configure Tx/Rx for async operation (settings extracted from S25 and S26)
  410. return(CON300); // Return Connect 300
  411. }
  412. void ans_tone()
  413. {
  414. // Stage 1 Tx No Tone for 2.2s
  415. CMXTXMODE &= 0x0E00; // Mask Tx Gain settings
  416. CMXTXMODE ^= 0x1000; // Initially setup Tx for tones, no guard tone
  417. // No Guard tone, scrambler Disabled, fixed tone, no tone
  418. wr16_cbus(CMXTXMODE_ADDR,CMXTXMODE); // Update Tx Mode CBUS register
  419. GPT3 = 22; // Start 2.2s timer
  420. while(GPT3 != 0)
  421. continue;
  422. // Stage 2 Tx 2100Hz for 3.3s
  423. CMXTXMODE ^= 0x000A; // No Guard tone, scrambler Disabled, fixed tone, 2100Hz
  424. wr16_cbus(CMXTXMODE_ADDR,CMXTXMODE); // Update Tx Mode CBUS register
  425. GPT3 = 33; // Start 3.3s timer
  426. while(GPT3 != 0)
  427. continue;
  428. // Stage 3 Tx No Tone for 80ms
  429. CMXTXMODE &= 0xFF00; // No Guard tone, scrambler Disabled, fixed tone, no tone
  430. wr16_cbus(CMXTXMODE_ADDR,CMXTXMODE); // Update Tx Mode CBUS register
  431. GPT1 = 8; // Start 80ms timer
  432. while(GPT1 != 0)
  433. continue;
  434. }
  435. unsigned char ans_V22bis()
  436. {
  437. unsigned char det32ones = 0;
  438. unsigned char tx2400flag = 0;
  439. unsigned char gotS1pattern = 0;
  440. // Stage 1 Tx unscrambled 1's
  441. CMXRXMODE &= 0x0E00; // Mask Rx Gain settings
  442. CMXRXMODE ^= 0xC0F8; // Setup Rx for low band V.22 1200bps and auto-equaliser disabled
  443. // Descrambler enabled, synchronous operation
  444. wr16_cbus(CMXRXMODE_ADDR,CMXRXMODE); // Update Rx Mode CBUS register
  445. CMXTXDATA = 0xFF;
  446. wr_cbus(CMXTXDATA_ADDR,CMXTXDATA); // Ensure Tx data reg is all 1's
  447. CMXTXMODE &= 0x0E00; // Mask Tx Gain settings
  448. CMXTXMODE ^= (((int) S23) << 1) & 0x0180; // Extract Guard Tone setting from S23.
  449. CMXTXMODE ^= 0xD01F; // Initially setup Tx for high band V.22 1200bps
  450. // Scrambler Disabled, sync and Tx data byte
  451. wr16_cbus(CMXTXMODE_ADDR,CMXTXMODE); // Update CBUS register
  452. // Stage 2 Look for scrambled 1's and also S1 pattern if V22bis selected
  453. GPT1 = 24; // Start 270ms timer (scram 1's detect has approx 30ms (32 bits) response time)
  454. do {
  455. DelayMs(5); // Insert 5ms polling delay 
  456. if (KEYABORT || (GPT6 == 0))
  457. { // Return No Carrier message if key pushed or
  458. return(NOCARRIER); // if general purpose timer (S18) has expired
  459. }
  460. CMXSTAT = rd16_cbus(CMXSTAT_ADDR); // Read status register and update shadow register
  461. if (!RXENERGYDET || !CONTA || !CONTB) // If rx energy or scram 1's are not detected
  462. {
  463. GPT1 = 24; // Restart scram 1's detect timer
  464. }
  465. if ((S27 & 0b11110000) == PROTB0) // Look for S1 Pattern if V22bis was selected 
  466. {
  467. if (!FALLBACK) // If modulation fallback is not enabled 
  468. { // prevent detection of V22 handshaking sequence
  469. GPT1 = 24; // by restarting scram 1's detect timer
  470. }
  471. if (RXENERGYDET && S1DET)
  472. {
  473. gotS1pattern = 1; // Set flag to indicate S1 pattern was found
  474. }
  475. }
  476. } while(GPT1 != 0 && !gotS1pattern); // Continue to loop until scram 1's detected for approx 270ms
  477. if (gotS1pattern)
  478. {
  479. // Stage 3 If the S1 pattern was detected wait until it goes away
  480. do { // Wait until end of S1 pattern
  481. DelayMs(5); // Insert 5ms polling delay 
  482. if (KEYABORT || (GPT6 == 0))
  483. { // Return No Carrier message if key pushed or
  484. return(NOCARRIER); // if wait carrier after dial timer has expired
  485. }
  486. CMXSTAT = rd16_cbus(CMXSTAT_ADDR); // Read status register and update shadow register
  487. } while(S1DET); // Wait until S1 Pattern has gone
  488. // Stage 4 Tx S1 pattern for 100ms
  489. CMXTXMODE &= 0xFFF8; // Now Tx S1 pattern
  490. wr16_cbus(CMXTXMODE_ADDR,CMXTXMODE); // Update Tx Mode CBUS register
  491. GPT1 = 60; // Start 600ms timer
  492. do {
  493. if (KEYABORT || (GPT6 == 0))
  494. { // Return No Carrier message if key pushed or
  495. return(NOCARRIER); // if general purpose timer (S18) has expired
  496. }
  497. } while(GPT1 >= 50); // Wait for 100ms timer to expire
  498. // Stage 5 Tx scrambled 1's
  499. CMXTXMODE &= 0xFF98; // Unmask scrambler and Tx Data source bit settings
  500. CMXTXMODE ^= 0x0067; // Scrambler enabled and Tx data byte
  501. wr16_cbus(CMXTXMODE_ADDR,CMXTXMODE); // Update Tx Mode CBUS register
  502. // Stage 6 Wait for 300ms timer to expire before enabling Rx Auto-Equaliser (will ensure it is receiving randomised data)
  503. do {
  504. if (KEYABORT || (GPT6 == 0))
  505. { // Return No Carrier message if key pushed or
  506. return(NOCARRIER); // if general purpose timer (S18) has expired
  507. }
  508. } while (GPT1 >= 30); // Wait until 300ms has expired
  509. AUTO_EQU = 1; // Enable Rx Auto-Equaliser for training (must be enabled for 2400bps operation)
  510. wr16_cbus(CMXRXMODE_ADDR,CMXRXMODE); // Update Rx Mode CBUS register
  511. // Stage 7 wait for 450ms timer to expire
  512. do {
  513. if (KEYABORT || (GPT6 == 0))
  514. { // Return No Carrier message if key pushed or
  515. return(NOCARRIER); // if general purpose timer (S18) has expired
  516. }
  517. } while (GPT1 >= 15); // Wait until 450ms has expired
  518. // Stage 8 Switch Rx Mode to 2400bps (Detectors and associated status flags will be reset)
  519. CMXRXMODE &= 0x0FFF; // Unmask Rx Mode bit settings
  520. CMXRXMODE ^= 0xE000; // Setup Rx for low band V.22bis 2400bps
  521. wr16_cbus(CMXRXMODE_ADDR,CMXRXMODE); // Update Rx Mode CBUS register
  522. // Stage 9 Wait until 32 continuous scram 1's at 2400bps are detected and the transmitter has switched to 2400bps scram 1's
  523. do {
  524. DelayMs(5); // Insert 5ms polling delay 
  525. if (KEYABORT || (GPT6 == 0))
  526. { // Return No Carrier message if key pushed or
  527. return(NOCARRIER); // if wait carrier after dial timer has expired
  528. }
  529. if (!tx2400flag)
  530. {
  531. if (GPT1 == 0) // Check if 600ms timer has expired
  532. {
  533. CMXTXMODE &= 0x0FFF; // Unmask Tx Mode bit settings
  534. CMXTXMODE ^= 0xF000; // Setup Tx for high band V.22 bis 2400bps
  535. wr16_cbus(CMXTXMODE_ADDR,CMXTXMODE); // Update Tx Mode CBUS register
  536. GPT1 = 20; // Load 200ms Timer
  537. tx2400flag = 1;
  538. }
  539. }
  540. CMXSTAT = rd16_cbus(CMXSTAT_ADDR); // Read status register and update shadow register
  541. if (RXENERGYDET && CONTA && CONTB && !det32ones)
  542. {
  543. DCDN = 0; // Clear DCDN line.
  544. DCDIND = 1; // Turn on CD LED.
  545. det32ones = 1; // Set detect 32 1's flag
  546. }
  547. } while(!RXENERGYDET || !CONTA || !CONTB || !tx2400flag); // Wait until 2400bps cont 1's is detected and
  548. // 2400bps has started transmitting
  549. // Stage 10 Ensure final 200ms timer has expired
  550. do {
  551. if (KEYABORT || (GPT6 == 0))
  552. { // Return No Carrier message if key pushed or
  553. return(NOCARRIER); // if general purpose timer (S18) has expired
  554. }
  555. } while (GPT1 != 0); // Ensure 200ms timer has expired
  556. }
  557. else
  558. {
  559. // Stage 11 Tx scrambled 1's
  560. CMXTXMODE &= 0xFF9F; // Unmask scrambler bit settings
  561. CMXTXMODE ^= 0x0060; // Enable scrambler
  562. wr16_cbus(CMXTXMODE_ADDR,CMXTXMODE); // Update Tx Mode CBUS register
  563. AUTO_EQU = USER_AUTO_EQU; // Extract Auto Equaliser setting from S24.
  564. wr16_cbus(CMXRXMODE_ADDR,CMXRXMODE); // Update Rx Mode CBUS register
  565. // Stage 12 Wait for 770ms timer to expire
  566. GPT1 = 77; // Start 770ms timer
  567. do {
  568. if (KEYABORT || (GPT6 == 0))
  569. { // Return No Carrier message if key pushed or
  570. return(NOCARRIER); // if general purpose timer (S18) has expired
  571. }
  572. } while (GPT1 != 0); // Wait until 770ms has expired
  573. DCDN = 0; // Clear DCDN line.
  574. DCDIND = 1; // Turn on CD LED.
  575. }
  576. // Stage 13
  577. async_setup(); // Configure Tx/Rx for async operation (settings extracted from S25 and S26)
  578. if (!gotS1pattern)
  579. {
  580. return(CON1200); // Return Connect 1200
  581. }
  582. else
  583. {
  584. return(CON2400); // Return Connect 2400
  585. }
  586. }
  587. unsigned char ans_V23()
  588. {
  589. // Stage 1 Tx unscrambled cont 1's
  590. CMXRXMODE &= 0x0E00; // Mask Rx Gain settings
  591. CMXRXMODE ^= 0x4038; // Setup Rx for V23 75bps and auto-equaliser disabled
  592. // Descrambler disabled, synchronous operation
  593. wr16_cbus(CMXRXMODE_ADDR,CMXRXMODE); // Update Rx Mode CBUS register
  594. CMXTXDATA = 0xFF;
  595. wr_cbus(CMXTXDATA_ADDR,CMXTXDATA); // Ensure Tx data reg is all 1's
  596. CMXTXMODE &= 0x0E00; // Mask Tx Gain settings
  597. CMXTXMODE ^= 0x501F; // Setup Tx for V23 1200bps, no guard tones
  598. // Scrambler disabled, sync operation, Tx data byte
  599. wr16_cbus(CMXTXMODE_ADDR,CMXTXMODE); // Update CBUS register
  600. // Stage 2 Detect unscram 1's for 150ms (use FSK demod output for this low baud rate detection)
  601. GPT1 = 15; // Start timer
  602. do {
  603. if (KEYABORT || (GPT6 == 0))
  604. { // Return No Carrier message if key pushed or
  605. return(NOCARRIER); // if GPT6 has expired
  606. }
  607. CMXSTAT = rd16_cbus(CMXSTAT_ADDR); // Read status register and update shadow register
  608. if (!RXENERGYDET || !FSKOUT) // If rx energy not detected or FSK demod output low
  609. {
  610. GPT1 = 15; // Restart unscram 1's detect timer
  611. }
  612. } while(GPT1 != 0); // Continue to loop until unscram 1's detected for 150ms
  613. // Stage 3
  614. async_setup(); // Configure Tx/Rx for async operation (settings extracted from S25 and S26)
  615. DCDN = 0; // Clear DCDN line.
  616. DCDIND = 1; // Turn on CD LED.
  617. return(CON120075); // Return Connect 1200/75
  618. }
  619. unsigned char ans_V23r()
  620. {
  621. return(NYI);
  622. }
  623. unsigned char ans_V22_600()
  624. {
  625. return(NYI);
  626. }
  627. unsigned char ans_V21()
  628. {
  629. return(NYI);
  630. }
  631. unsigned char ans_212a()
  632. {
  633. return(NYI);
  634. }
  635. unsigned char ans_202()
  636. {
  637. return(NYI);
  638. }
  639. unsigned char ans_202r()
  640. {
  641. return(NYI);
  642. }
  643. unsigned char ans_103()
  644. {
  645. // Stage 1 Tx unscrambled cont 1's
  646. CMXRXMODE &= 0x0E00; // Mask Rx Gain settings
  647. CMXRXMODE ^= 0x6038; // Setup Rx for low band Bell 103 300bps and auto-equaliser disabled
  648. // Descrambler disabled, synchronous operation
  649. wr16_cbus(CMXRXMODE_ADDR,CMXRXMODE); // Update Rx Mode CBUS register
  650. CMXTXDATA = 0xFF;
  651. wr16_cbus(CMXTXDATA_ADDR,CMXTXDATA); // Ensure Tx data reg is all 1's
  652. CMXTXMODE &= 0x0E00; // Mask Tx Gain settings
  653. CMXTXMODE ^= 0x701F; // Setup Tx for high band Bell 103 300bps, no guard tones
  654. // Scrambler disabled, sync operation and Tx data byte
  655. wr16_cbus(CMXTXMODE_ADDR,CMXTXMODE); // Update CBUS register
  656. // Stage 2
  657. if (unscram1sdet(5) != OK) return(NOCARRIER); // Detect unscram 1's for 150ms (1's detect has approx 100ms (32bits) response time)
  658. // Stage 3
  659. async_setup(); // Configure Tx/Rx for async operation (settings extracted from S25 and S26)
  660. DCDN = 0; // Clear DCDN line.
  661. DCDIND = 1; // Turn on CD LED.
  662. return(CON300); // Return Connect 300
  663. }
  664. void async_setup()
  665. {
  666. CMXTXMODE &= 0xFFE0; // Unmask Tx Data format bit settings
  667. CMXTXMODE ^= ((((int) S25) >> 3) & 0x001F); // Extract Tx Data/Stop bit and async mode settings from S25.
  668. wr16_cbus(CMXTXMODE_ADDR,CMXTXMODE); // Update Tx Mode CBUS register
  669. RXUSART = 1; // Ensure Rx USART is enabled 
  670. CMXRXMODE &= 0xFFE0; // Unmask Rx USART bit settings
  671. CMXRXMODE ^= ((((int) S26) >> 3) & 0x001F); // Extract Rx Data/parity and async mode settings from S26.
  672. wr16_cbus(CMXRXMODE_ADDR,CMXRXMODE); // Update Rx Mode CBUS register
  673. }
  674. unsigned char unscram1sdet(unsigned char dettime) // Uses general purpose timers GPT1 and GPT6
  675. {
  676. GPT1 = dettime; // Start timer
  677. do {
  678. DelayMs(5); // Insert 5ms polling delay 
  679. if (KEYABORT || (GPT6 == 0))
  680. { // Return No Carrier message if key pushed or
  681. return(NOCARRIER); // if GPT6 has expired
  682. }
  683. CMXSTAT = rd16_cbus(CMXSTAT_ADDR); // Read status register and update shadow register
  684. if (!RXENERGYDET || !CONTA || CONTB) // If rx energy or unscram 1's are not detected
  685. {
  686. GPT1 = dettime; // Restart unscram 1's detect timer
  687. }
  688. } while(GPT1 != 0); // Continue to loop until unscram 1's detected for specified time
  689. return(OK);
  690. }