📄 modem.~c
字号:
//*----------------------------------------------------------------------------
//* NANTIAN DONGHUA TECHNOLOGY CO.,Ltd COPYRIGHT 2006
//*----------------------------------------------------------------------------
//* The software is delivered by henry huang for driver develop.
//* Write in 2007-10-28
//*----------------------------------------------------------------------------
#include "modem.h"
#include "string.h"
#include "DataType.h"
//-----------------------------------------------
#define LEN_MODEM_DATA 4096
#define SYN_TIMER_VALUE 0xffff
#define MODEM_DELAY
#define SPEED_BYTEPS 150 //==1200/8
//-----------------------------------------------
#define I_FRAME 0
#define S_FRAME 1
#define U_FRAME 3
#define PFBIT (1<<4)
#define UA_FRAME (U_FRAME+PFBIT+0x60)
#define RD_FRAME (U_FRAME+PFBIT+0x40)
#define RR_FRAME (S_FRAME+PFBIT)
#define MSG_FRAME (I_FRAME+PFBIT)
#define DIAL_WAIT 1724 //15S
#define SYNC_WAIT 500 //120 //1S
#define WAIT_TIME 500 //1200MS
//#define WAIT_TIME 130 //1200MS
#define REPEAT_COUNT 3 //重复最大次数
#define EM 0x19
#define TERMINATECARRUE 0xba
#define NSADDINDEX 1
#define NRADDINDEX 1
#define FRAME_LEMGTH (2060)
#define PACK_LENGTH (2048)
volatile static INT8U NR;
volatile static INT8U NS;
volatile static INT16U WaitConfirm;
volatile static INT8U RepeatState;
volatile static INT16U WaitEvent;
volatile INT8U bFSDLSta;
volatile static INT32U lModemSta=0;
extern volatile INT32U StTick;
extern char modempatch[];
//-----------------------------------------------
extern unsigned char ModemBuff[LEN_MODEM_DATA];
extern unsigned short iModemRead;
extern unsigned short iModemWrite;
extern void timer3_asm_irq_handler(void);
static unsigned char bSynModemBuff[LEN_MODEM_DATA];
static unsigned char bSynReadPo=0;
static unsigned char bCon,bOne,bTwo;
void timer3_c_irq_handler(void);
//-----------------------------------------------
//发送缓冲区
struct SYN_MODEM_STUCT
{
INT8U SendEndFlag;
INT32U lSendLen;
INT8U bSynSendBuff[PACK_LENGTH];
};
static struct SYN_MODEM_STUCT SynModemStu;
typedef enum
{
S_RESET,S_SET,S_WORK,S_INS,
S_CMD,S_CTRL,S_SND,S_DAT,S_REC
}MODEMCMDSTATE;
//----------------------------------------------------------------
static INT16U iV80Flag=0;
static int BCDToV80(INT8U *inbuf,INT8U *outbuf,INT16U inlen);
static INT8U AnalyV80Pack(void);
static INT16U V80ToBCD(INT8U *inbuf,INT8U *outbuf,INT16U inlen);
struct V80_PACKGE
{
INT32U lLen;
INT8U cData[PACK_LENGTH];
};
static struct V80_PACKGE RecV80Data,pRecV80Data;
//----------------------------------------------------------------
static void ClearModemBuff(void)
{
iModemRead =0;
iModemWrite =0;
memset(ModemBuff,0,LEN_MODEM_DATA);
}
static INT8U ModemSendFrame(INT8U control,INT8S *pStr,INT16U iLen)
{
INT16U i;
INT16U iSLen;
INT8U SendBuff[FRAME_LEMGTH];
INT8U OutBuff[FRAME_LEMGTH];
memset(SendBuff,0,FRAME_LEMGTH);
memset(OutBuff,0,FRAME_LEMGTH);
ClearModemBuff();
SendBuff[0] =0x30;
SendBuff[1] =control;
memcpy(SendBuff+2,pStr,iLen);
iSLen =BCDToV80(SendBuff,OutBuff,iLen+2);
OutBuff[iSLen]=0x19;
OutBuff[iSLen+1] =0xb1;
for(i=0; i<iSLen+2; i++)
{
set_char(2,OutBuff[i]);
}
#ifdef MODEM_DEBUG
DebugString(0,"\r\n");
DebugData(0,iSLen+2,10,OutBuff);
#endif
return TRUE;
}
static void SendFrameMsg(void)
{
if (SynModemStu.SendEndFlag==SEND_START)
{
#ifdef MODEM_DEBUG
//DebugString(0,"\r\n");
//DebugData(0,SynModemStu.lSendLen,10,SynModemStu.bSynSendBuff);
#endif
ModemSendFrame(MSG_FRAME+((NS&0x7)<<1)+((NR&0x7)<<5),SynModemStu.bSynSendBuff,SynModemStu.lSendLen);
SynModemStu.SendEndFlag=SEND_SENDING;
lModemSta =STA_SEND_DATA;
bFSDLSta=S_DAT;
//WaitConfirm=WAIT_TIME;
WaitConfirm=SynModemStu.lSendLen*115/SPEED_BYTEPS+100;
NS=NS+NSADDINDEX;
RepeatState++;
}
}
static INT8U ModemSendRev(INT8S *pStr,INT8S *pRes,INT16U iRevDelayMs,INT16U iSendDelayMs)
{
INT32U lTmpStic;
INT16U i =0;
char *p;
ClearModemBuff();
for(i=0; i<strlen(pStr); i++)
{
set_char(2,pStr[i]);
}
DelayMs(iSendDelayMs);
lTmpStic =StTick;
while((StTick - lTmpStic) < iRevDelayMs)
{
p=strstr(ModemBuff,pRes);
if(p)
{
return TRUE;
}
}
return FALSE;
}
INT8U ModemInit(void)
{
INT32U temp;
INT16U i;
//PortOpen(2,9600);
//PortOpen(2,14400);//ok
//PortOpen(2,19200);
//PortOpen(2,38400);
//PortOpen(2,56000);
PortOpen(2,57600);//ok
//PortOpen(2,115200);
SynModemStu.lSendLen =0;
RecV80Data.lLen =0;
WaitConfirm=0;
lModemSta=STA_TEL_IDLE;
if (ModemSendRev("AT\r\n","OK",1000,200) != TRUE) return FALSE+1;
if(ModemSendRev("ATS12=20\r\n","OK",2000,50) != TRUE) return FALSE+2;
//if(ModemSendRev("ATS11=95E0S8=1S7=71S10=50;-TRV\r\n","OK",2000,50) != TRUE) return FALSE+3;
if(ModemSendRev("ATS11=50;!48AF=2C;E0;S8=1;S7=71;S10=50;-TRV\r\n","OK",2000,50) != TRUE) return FALSE+3;
//--------------------------------------------------------------
return 0;
}
INT8U ModemDial(INT8U *pDialNum,INT8U Mode)
{
INT8U bDialBuff[100];
INT16U i,dialnum;
INT8U *p,cres;
lModemSta =STA_TEL_IDLE;
memset(bDialBuff,0,100);
memcpy(bDialBuff,"ATDT",4);
memcpy(bDialBuff+4,pDialNum,strlen(pDialNum));
memcpy(bDialBuff+4+strlen(pDialNum),"\r\n",2);
#ifdef MODEM_DEBUG
DebugString(0,"发送AT指令.\r\n");
#endif
//------------------------------------------------------------
dialnum=3;
while (dialnum--)
{
if(ModemSendRev("AT\r\n","OK",1000,100) != TRUE) continue;
//使MODEM 切断电话
if(ModemSendRev("ATH0\r\n","OK",1000,100) != TRUE) continue;
if(ModemSendRev("ATZ\r\n","OK",1000,200) != TRUE) continue;
break;
};
if (dialnum==0)
return FALSE+1;
//--------------------------------------------------------------
//(X0=1) MODEM在拨号不辨别拨号音和忙音,结果只显示CONNECT,不显示MODEM的速度.
//(%C0\\N0) 假定数据载波一直存在
//(&Q1) MODEM不返回结果码
if(ModemSendRev("ATX0=1;%C0\\N0;&Q1\r\n","OK",2000,100) != TRUE) return FALSE+4;
//--------------------------------------------------------------
#ifdef MODEM_DEBUG
DebugString(0,"设定同步参数.\r\n");
#endif
//V.22fastconnect 同步模式
//(+A8E=,,,0) 关闭V8bis (*)
//(+ES=6,,8) 使能v.80同步访问模式 (*)
//(+ESA=0,0,,,1,0) 使能CRC frame (*)
//(+ITF=255,250,0)
//(+MS=V22B) (or+MS=V22,or+MS=B212) 采用v.22bis/v.22/Bell212A
if(ModemSendRev("AT+A8E=,,,0;+ES=6,,8;+ESA=0,0,,,1,0;+ITF=255,250,0;+MS=V22B\r\n","OK",2000,100) != TRUE) return FALSE+5;
//------------------------------------------
//(S17=13)
//(S7=15) 拨号完后等待远端信号时间
//(Q0) MODEM返回结果码,并在屏显示
//(B0) 以1200BPS,选择CCITT V.22标准通信
//($F2) v.22 fastconnect
//(E0) 关闭指令态字符回显
if(ModemSendRev("ATS17=13;S7=15X3;S38=1;S12=12;S6=2-STE=0;S91=10Q0B0$F2E0\r\n","OK",2000,100) != TRUE) return FALSE+6;
//if(ModemSendRev("AT+A8E=,,,0;$F2;+MS=V22;+ES=6,,8;+ESA=0,0,,,1,0;S17=13\r\n","OK",2000,100) != TRUE) return FALSE+6;
//------------------------------------------
#ifdef MODEM_DEBUG
DebugString(0,"同步参数设定完成.\r\n");
#endif
//同步通信
ClearModemBuff();
//拔电话号码
#ifdef MODEM_DEBUG
DebugString(0,"\r\n");
DebugString(0,"拔电话号码.\r\n");
#endif
SynModemStu.SendEndFlag=SEND_END;
i =0;
while(bDialBuff[i] != 0)
{
if(set_char(2,bDialBuff[i++]) != TRUE) return FALSE+1;
}
//---------------------------------------
WaitEvent=DIAL_WAIT;
//---------------------------------------
lModemSta=STA_DIAL_GO;
timer3_c_irq_handler();
//---------------------------------------
if (Mode==BEFOREHAND_DIAL)
return 0;
if (Mode==NORMAL_DIAL)
{
while(1)
{
cres=ModemState();
if (cres==STA_LINE_IDLE||
cres==STA_DIAL_FAIL||
cres==STA_SYNC_FAIL||
cres==STA_NO_CCARRIER)
break;
}
}
return 0;
//---------------------------------------
}
static INT8U AnalyV80Pack(void)
{
INT8U *p;
INT8U Temp;
INT8U TempBuff[PACK_LENGTH];
if(get_char(2,&Temp) != TRUE) return FALSE;
switch(iV80Flag)
{
case 0:
if(Temp == 0x30)
{
iV80Flag =1;
RecV80Data.cData[RecV80Data.lLen] =Temp;
RecV80Data.lLen +=1;
}
else
RecV80Data.lLen =0;
break;
case 1:
// if(Temp == 0xB2)
// iV80Flag =2;
// else
// iV80Flag =0;
// break;
case 2:
if(Temp == 0x19)
iV80Flag =3;
else
{
RecV80Data.cData[RecV80Data.lLen] =Temp;
RecV80Data.lLen +=1;
}
break;
case 3:
if(Temp == 0xB1)
{
RecV80Data.cData[RecV80Data.lLen] =0x19;
RecV80Data.lLen +=1;
RecV80Data.cData[RecV80Data.lLen] =Temp;
RecV80Data.lLen +=1;
iV80Flag =0;
memcpy(TempBuff,RecV80Data.cData,RecV80Data.lLen);
// DebugData(0,RecV80Data.lLen,10,RecV80Data.cData);
RecV80Data.lLen=V80ToBCD(TempBuff,RecV80Data.cData,RecV80Data.lLen);
// DebugData(0,RecV80Data.lLen,10,RecV80Data.cData);
return TRUE;
}
else
{
RecV80Data.cData[RecV80Data.lLen] =0x19;
RecV80Data.lLen +=1;
RecV80Data.cData[RecV80Data.lLen] =Temp;
RecV80Data.lLen +=1;
iV80Flag =2;
}
break;
default:
iV80Flag =0;
break;
}
return FALSE;
}
void timer3_c_irq_handler(void)
{
INT32U temp,SdlcPos;
INT8U Tmp;
INT32U j;
INT8U i,TmpBuff[5],msg[100];
INT8U confirmNS,confirmNR;
INT8U V80PackState;
//*AT91C_TC3_IDR =AT91C_TC_CPCS;
//temp = *AT91C_TC3_SR;
if (lModemSta==STA_DIAL_GO)
{
if (WaitEvent==0)
{
lModemSta=STA_DIAL_FAIL;
return;
}
WaitEvent--;
if(strstr(ModemBuff,"CONNECT") != 0)
{
lModemSta=STA_SYNC_GO;
NR=0;
NS=0;
WaitConfirm=0;
bFSDLSta=S_CMD;
WaitEvent=SYNC_WAIT;
#ifdef MODEM_DEBUG
DebugString(0,"\r\n");
DebugString(0,"接通,发送同步数据.\r\n");
#endif
}
else if(strstr(ModemBuff,"NO CARRIER") != 0)
{
lModemSta=STA_LINE_OFF;
return;
}
//*AT91C_TC3_IER =AT91C_TC_CPCS;
return;
}
if (lModemSta==STA_SYNC_GO)
{
if (WaitEvent==0)
{
lModemSta=STA_SYNC_FAIL;
return;
}
WaitEvent--;
V80PackState=AnalyV80Pack();
if (bFSDLSta==S_CMD)
{
if(V80PackState == TRUE)
{
RecV80Data.lLen =0;
if(strstr(ModemBuff,"\x30\x93\x19\xB1") != 0)
{
bFSDLSta=S_CTRL;
#ifdef MODEM_DEBUG
DebugPrint("收到SNRM帧。\r\n");
#endif
}
ModemSendFrame(UA_FRAME,0,0);
}
}
else if (bFSDLSta==S_CTRL)
{
if(V80PackState == TRUE)
{
RecV80Data.lLen =0;
if(RecV80Data.cData[1] != RR_FRAME)
{
ModemSendFrame(UA_FRAME,0,0);
#ifdef MODEM_DEBUG
DebugPrint("没有收到UA的确认帧 \r\n");
#endif
}
else
{
goto online_step;
bFSDLSta=S_SND;
ModemSendFrame(RR_FRAME,0,0);
#ifdef MODEM_DEBUG
DebugPrint("收到UA的确认帧,本机再发送RR帧 \r\n");
#endif
}
}
}
else if (bFSDLSta==S_SND)
{
if(V80PackState == TRUE)
{
RecV80Data.lLen =0;
if(RecV80Data.cData[1] != RR_FRAME)
{
ModemSendFrame(UA_FRAME,0,0);
bFSDLSta=S_CTRL;
#ifdef MODEM_DEBUG
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -