hndshake.c
上传用户:lilishw
上传日期:2021-05-28
资源大小:1542k
文件大小:31k
源码类别:

Modem编程

开发平台:

Visual 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.     wr_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.     
  690.     return(OK);
  691. }