📄 hndshake.c
字号:
//---------------------------------------------------------------------------------------------------
// Project:- DE8681
// Filename:- HNDSHAKE.C
// Description:- Handshaking Routines for CMX868.
// Programmer:- D.T.F
// Version:- 2.0
// Created:- 28th February 2002
// Last modified:-
//---------------------------------------------------------------------------------------------------
// (C) Consumer Microcircuits Ltd 2002
//
// This firmware was designed by:-
// Consumer Microcircuits Ltd,
// Langford, Maldon,
// ESSEX
// CM9 6WG.
// in the UK for use with CML evaluation kits only and is based on UK originated technology.
// Please contact
// sales@cmlmicro.co.uk
// +44 (0)1621 875500
// for licensing details.
//---------------------------------------------------------------------------------------------------
#define HNDSHAKE_C
#include "ef8681.h"
void hndshake_init()
{
reset_cbus(); // Reset the CBUS before we start, will clear all shadow write registers
pwrup(); // Power Up CMX868 with correct Xtal and fixed equalisers initially enabled.
CMXTXMODE ^= (((int) S25) << 9) & 0x0E00; // Extract required Tx level from S25.
wr16_cbus(CMXTXMODE_ADDR, CMXTXMODE); // Update CBUS register
CMXRXMODE ^= (((int) S26) << 9) & 0x0E00; // Extract required Rx level from S26.
wr16_cbus(CMXRXMODE_ADDR, CMXRXMODE); // Update CBUS register
FIX_EQU = USER_FIX_EQU; // Extract required Tx and Rx Fixed Equaliser settings from S24.
wr16_cbus(CMXGENCTRL_ADDR, CMXGENCTRL); // Update CBUS register
}
unsigned char hndshake_go()
{
unsigned char tmpresult;
if (ANSORIG) // Check S14 Bit 7, if set we are originating a call
{
GPT6 = S7; // Load GPT6 (1s) with Wait for carrier after dial S-Register
switch(S27 & 0b11110000)
{
case PROTB0: case PROTB1:
tmpresult = orig_V22bis();
break;
case PROTB2:
tmpresult = orig_V23();
break;
case PROTB3:
tmpresult = orig_V23r();
break;
case PROTB4:
tmpresult = orig_V22_600();
break;
case PROTB5:
tmpresult = orig_V21();
break;
case PROTB6:
tmpresult = orig_212a();
break;
case PROTB7:
tmpresult = orig_202();
break;
case PROTB8:
tmpresult = orig_202r();
break;
case PROTB9:
tmpresult = orig_103();
break;
default:
return(ERROR); // Indicate Error has occured
}
}
else
{
GPT6 = S18; // Load GPT6 (1s) with General Purpose timer setting
switch(S27 & 0b11110000)
{
case PROTB0: case PROTB1:
ans_tone();
tmpresult = ans_V22bis();
break;
case PROTB2:
ans_tone();
tmpresult = ans_V23();
break;
case PROTB3:
ans_tone();
tmpresult = ans_V23r();
break;
case PROTB4:
ans_tone();
tmpresult = ans_V22_600();
break;
case PROTB5:
ans_tone();
tmpresult = ans_V21();
break;
case PROTB6:
tmpresult = ans_212a();
break;
case PROTB7:
tmpresult = ans_202();
break;
case PROTB8:
tmpresult = ans_202r();
break;
case PROTB9:
tmpresult = ans_103();
break;
default:
return(ERROR); // Indicate Error has occured
}
}
if ((tmpresult != NYI) && (tmpresult != NOCARRIER))
{
DATAXFER = 1;
ATCMDMODE = 0;
switch(S22 & 0b11100000)
{
case X0CALLING:
return(CONNECT);
default:
return(tmpresult);
}
}
else
{
return(tmpresult);
}
}
unsigned char orig_V22bis()
{
unsigned char det32ones = 0;
unsigned char tx2400flag = 0;
unsigned char gotS1pattern = 0;
// Stage 1 Look for unscrambled 1's or 2225Hz tone
CMXRXMODE &= 0x0E00; // Mask Rx Gain settings
CMXRXMODE ^= 0x1002; // Setup Rx for 2225Hz Answer Tone Detection (will detect unscram 1's)
wr16_cbus(CMXRXMODE_ADDR, CMXRXMODE); // Update Rx Mode CBUS register
GPT1 = 12; // Start 150ms timer (Answer Tone detector has approx 30ms response time)
do {
DelayMs(5); // Insert 5ms polling delay
if (KEYABORT || (GPT6 == 0))
{ // Return No Carrier message if key pushed or
return(NOCARRIER); // if wait carrier after dial timer has expired
}
CMXSTAT = rd16_cbus(CMXSTAT_ADDR); // Read status register and update shadow register
if (!ANS2225DET) // If 2225Hz Answer Tone is not detected
{
GPT1 = 12; // Restart 2225Hz Answer Tone detect timer
}
} while(GPT1 != 0); // Continue to loop until unscram 1's detected for approx 150ms
// Stage 2 Wait for 450ms
CMXRXMODE &= 0x0E00; // Mask Rx Gain settings
CMXRXMODE ^= 0xD0F8; // Setup Rx for high band V.22 1200bps, auto-equaliser disabled,
// Descrambler enabled and synchronous operation
wr16_cbus(CMXRXMODE_ADDR,CMXRXMODE); // Update Rx Mode CBUS register
GPT1 = 45; // Start 450ms timer
do {
if (KEYABORT || (GPT6 == 0))
{ // Return No Carrier message if key pushed or
return(NOCARRIER); // if wait carrier after dial timer has expired
}
} while (GPT1 != 0);
// Stage 3 Tx S1 Pattern if V22bis selected
if ((S27 & 0b11110000) == PROTB0)
{
CMXTXMODE &= 0x0E00; // Mask Tx Gain settings
CMXTXMODE ^= 0xC018; // Initially setup Tx for low band V.22 1200bps, no guard tone
// No Guard tone, scrambler Disabled, synchronous operation and Tx S1 pattern
wr16_cbus(CMXTXMODE_ADDR, CMXTXMODE); // Update Tx Mode CBUS register
GPT1 = 10; // Start 100ms timer
do {
if (KEYABORT || (GPT6 == 0))
{ // Return No Carrier message if key pushed or
return(NOCARRIER); // if wait carrier after dial timer has expired
}
} while(GPT1 !=0); // Wait for 100ms timer to expire
}
// Stage 4 Tx 1200bps scrambled 1's
CMXTXDATA = 0xFF;
wr_cbus(CMXTXDATA_ADDR, CMXTXDATA); // Ensure Tx data reg is all 1's
CMXTXMODE &= 0x0E00; // Mask Tx gain settings
CMXTXMODE ^= 0xC07F; // Setup Tx for low band V.22 1200bps, no guard tone
// Scrambler enabled, sync operation and Tx data byte reg
wr16_cbus(CMXTXMODE_ADDR,CMXTXMODE); // Update Tx Mode CBUS register
// Stage 5 Look for S1 pattern if V22bis selected
if ((S27 & 0b11110000) == PROTB0)
{
GPT1 = 27; // Start 270ms timer
do {
DelayMs(5); // Insert 5ms polling delay
if (KEYABORT || (GPT6 == 0))
{ // Return No Carrier message if key pushed or
return(NOCARRIER); // if wait carrier after dial timer has expired
}
CMXSTAT = rd16_cbus(CMXSTAT_ADDR); // Read status register and update shadow register
if (RXENERGYDET && S1DET)
{
gotS1pattern = 1; // Set flag to indicate S1 pattern was found
}
} while((GPT1 != 0) && !gotS1pattern); // Continue to loop until timer expires or S1 pattern is detected
}
if (gotS1pattern)
{
// Stage 6 If the S1 pattern was detected wait until it goes away
do {
DelayMs(5); // Insert 5ms polling delay
if (KEYABORT || (GPT6 == 0))
{ // Return No Carrier message if key pushed or
return(NOCARRIER); // if wait carrier after dial timer has expired
}
CMXSTAT = rd16_cbus(CMXSTAT_ADDR); // Read status register and update shadow register
} while(S1DET); // Wait until S1 Pattern has gone
// Stage 7
GPT1 = 60; // Start 600ms timer
do {
if (KEYABORT || (GPT6 == 0))
{ // Return No Carrier message if key pushed or
return(NOCARRIER); // if general purpose timer (S18) has expired
}
} while (GPT1 >= 30); // Wait until 300ms has expired
AUTO_EQU = 1; // Enable Rx Auto-Equaliser for training (must be enabled for 2400bps operation)
wr16_cbus(CMXRXMODE_ADDR, CMXRXMODE); // Update Rx Mode CBUS register
do {
if (KEYABORT || (GPT6 == 0))
{ // Return No Carrier message if key pushed or
return(NOCARRIER); // if wait carrier after dial timer has expired
}
} while (GPT1 >= 15); // Wait until 450ms has expired
// Stage 8 Switch Rx Mode to 2400bps (Detectors and associated status flags will be reset)
CMXRXMODE &= 0x0FFF; // Unmask Rx Mode bit settings
CMXRXMODE ^= 0xF000; // Setup Rx for high band V.22bis 2400bps
wr16_cbus(CMXRXMODE_ADDR, CMXRXMODE); // Update Rx Mode CBUS register
// Stage 9 Wait until 32 continuous 1's are detected and transmitter has switched to 2400bps scram 1's
do {
DelayMs(5); // Insert 5ms polling delay
if (KEYABORT || (GPT6 == 0))
{ // Return No Carrier message if key pushed or
return(NOCARRIER); // if wait carrier after dial timer has expired
}
if (!tx2400flag)
{
if (GPT1 == 0) // Check if 600ms timer has expired
{
CMXTXMODE &= 0x0FFF; // Unmask Tx Mode bit settings
CMXTXMODE ^= 0xE000; // Setup Tx for low band V.22 bis 2400bps
wr16_cbus(CMXTXMODE_ADDR, CMXTXMODE); // Update Tx Mode CBUS register
GPT1 = 20; // Load 200ms Timer
tx2400flag = 1;
}
}
CMXSTAT = rd16_cbus(CMXSTAT_ADDR); // Read status register and update shadow register
if (RXENERGYDET && CONTA && CONTB && !det32ones)
{
DCDN = 0; // Clear DCDN line.
DCDIND = 1; // Turn on CD LED.
det32ones = 1; // Set detect 32 1's flag
}
} while(!RXENERGYDET || !CONTA || !CONTB || !tx2400flag); // Wait until 2400bps cont 1's is detected and
// 2400bps has started transmitting
// Stage 10 Ensure final 200ms timer has expired
do {
if (KEYABORT || (GPT6 == 0))
{ // Return No Carrier message if key pushed or
return(NOCARRIER); // if wait carrier after dial timer has expired
}
} while (GPT1 != 0); // Ensure 200ms timer has expired
}
else
{
if (((S27 & 0b11110000) == PROTB0) && !FALLBACK)
{
return(NOCARRIER); // Return No Carrier message
}
// Stage 11 Detect scrambled 1's for 270ms
GPT1 = 24; // Start 270ms timer (scram 1's detect has approx 30ms (32 bits) response time)
do {
DelayMs(5); // Insert 5ms polling delay
if (KEYABORT || (GPT6 == 0))
{ // Return No Carrier message if key pushed or
return(NOCARRIER); // if wait carrier after dial timer has expired
}
CMXSTAT = rd16_cbus(CMXSTAT_ADDR); // Read status register and update shadow register
if (!RXENERGYDET || !CONTA || !CONTB) // If rx energy or scram 1's are not detected
{
GPT1 = 24; // Restart scram 1's detect timer
}
} while(GPT1 != 0); // Continue to loop until scram 1's detected for approx 270ms
AUTO_EQU = USER_AUTO_EQU; // Extract Auto Equaliser setting from S24.
wr16_cbus(CMXRXMODE_ADDR,CMXRXMODE); // Update Rx Mode CBUS register
DCDN = 0; // Clear DCDN line.
DCDIND = 1; // Turn on CD LED.
// Stage 12 Start 770ms timer
GPT1 = 77;
do {
if (KEYABORT || (GPT6 == 0))
{ // Return No Carrier message if key pushed or
return(NOCARRIER); // if wait carrier after dial timer has expired
}
} while (GPT1 != 0); // Wait until 770ms has expired
}
// Stage 13
async_setup(); // Configure Tx/Rx for async operation (settings extracted from S25 and S26)
if (!gotS1pattern)
{
return(CON1200); // Return Connect 1200
}
else
{
return(CON2400); // Return Connect 2400
}
}
unsigned char orig_V23()
{
// Stage 1
CMXRXMODE &= 0x0E00; // Mask Rx Gain settings
CMXRXMODE ^= 0x5038; // Setup Rx for V23 1200bps and auto-equaliser disabled
// Descrambler Disabled, synchronous operation
wr16_cbus(CMXRXMODE_ADDR,CMXRXMODE); // Update Rx Mode CBUS register
if (unscram1sdet(12) != OK) return(NOCARRIER); // Detect unscram 1's for 150ms (1's detect has approx 30ms (32bits) response time)
// Stage 2
DCDN = 0; // Clear DCDN line.
DCDIND = 1; // Turn on CD LED.
GPT1 = 77; // Start 770ms timer
do {
if (KEYABORT || (GPT6 == 0))
{ // Return No Carrier message if key pushed or
return(NOCARRIER); // if wait carrier after dial timer has expired
}
} while (GPT1 >= 32); // Wait until 450ms has expired
// Stage 3
CMXTXDATA = 0xFF;
wr_cbus(CMXTXDATA_ADDR,CMXTXDATA); // Ensure Tx data reg is all 1's
CMXTXMODE &= 0x0E00; // Mask Tx Gain Settings
CMXTXMODE ^= 0x401F; // Setup Tx for V23 75bps, no guard tone
// No Guard tone, scram disabled, sync operation, Tx data byte reg
wr16_cbus(CMXTXMODE_ADDR,CMXTXMODE); // Update Tx Mode CBUS register
// Stage 4
do {
if (KEYABORT || (GPT6 == 0))
{ // Return No Carrier message if key pushed or
return(NOCARRIER); // if wait carrier after dial timer has expired
}
} while (GPT1 != 0); // Ensure 770ms timer has expired
// Stage 5
async_setup(); // Configure Tx/Rx for async operation (settings extracted from S25 and S26)
return(CON751200); // Return Connect 75/1200
}
unsigned char orig_V23r()
{
return(NYI);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -