⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 modem.~c

📁 采用cb平台开发
💻 ~C
📖 第 1 页 / 共 2 页
字号:
//*----------------------------------------------------------------------------
//*        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 + -