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

📄 communicate.c

📁 基于S3C2410和SM501的彩屏控制器程序
💻 C
📖 第 1 页 / 共 2 页
字号:
#define __COMMUNICATE
#include "communicate.h"
#undef __COMMUNICATE


//********************** Global Variable **********************
unsigned char connect = 0;		// 连接标记
unsigned char cLocalAddress = 1;	// 本机地址
DWORD dwTemp;

char cIpAddr[16];
ushort wport;
uchar bTouchAddr = 1;
//*************************************************************



//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// 函数: 计算并添加数据包校验和.
// 描述: 计算数据阿伯的校验和字节, 并添加到数据包末端.
//		若发送方式为串口, 赋值串口发送长度.
//
// [参数表]
//	port: 串口号. 0-UART0; 1-UART1; 2-UART2.
//	data: 数据数组始地址.
// 	sendType: 通信方式. 0-串口; 1-网络.
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
void CalCommSum (uchar port, uchar *data, uchar sendType)
{
	unsigned long	i, sum = 0;

	// 计算校验和
	for( i=0; i<data[1]-1; i++ )
		sum += data[i];
	sum &= 0xff;	
	sum = 0x100-sum;

	data[i] = sum;		// 将校验和添加到数据包末端

	if( sendType == UART_SEND )
		UartSendLens[port] = data[1]-1;		// 为串口发送赋长度
	// 注: 由于后续用到UartStartSend函数, 所以此长度不含第一个字节.
}//CalCommSum()



//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// 函数: 检查UART0.
// 描述: 串口0与PC机通信.
//
// [参数表]
//	Uart0ReceData: 串口0接收数据数组始地址.
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
void CheckUart0(unsigned char *Uart0ReceData)
{
	uchar 	i, sum = 0;
	ulong	DataLen;	// 数据长度

	DataLen = Uart0ReceData[1] + (Uart0ReceData[2]<<8);		// 长度两个字节
	
	if((DataLen >= 6) && (DataLen == UartReceLen[UART0]))
	// 通过数据长度判断数据包是否已接收完毕
	{
		for( i=0; i<UartReceLen[UART0]; i++ )	// 计算累加和
		{
			sum += Uart0ReceData[i];
		}

		UartReceLen[UART0] = 0;		// 串口0接收长度清零
		DataLen = 0;				// 数据长度清零

		UARTprintf("%d ", Uart0ReceData[3]);

		if( (sum & 0xff) == 0 )		// 校验和判断
		{
			// 接收方地址与本机地址不等时,不处理
			if( Uart0ReceData[3] != cLocalAddress )
				return;

			switch(Uart0ReceData[4])	//命令
			{
				case 127:
					Uart0_CommProcess(Uart0ReceData);	//子命令
					break;

				default:	break;
			}
		}
		else
		{
			Uart0_SendCommOK(0xAA);		//发送通信成功
		}
	}
}//CheckUart0()



//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// 函数: UART0发送通信成功.
// 描述: 向上位机发送通信成功数据包.
//
// [参数表]
// 	status: 状态.
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
void Uart0_SendCommOK(unsigned char status)
{
	Uart0_SendBuf(0) = 2;
	Uart0_SendBuf(1) = 7+1;
	Uart0_SendBuf(2) = Uart0_ReceBuf(4);
	Uart0_SendBuf(3) = Uart0_ReceBuf(3);
	Uart0_SendBuf(4) = cLocalAddress;			//本机地址
	Uart0_SendBuf(5) = Uart0_ReceBuf(6);		//子命令
	Uart0_SendBuf(6) = status;
	
	CalCommSum(UART0, UartSendBuf[UART0], UART_SEND);		// 计算校验和
	UartStartSend(UART0);	// 启动串口发送
}//Uart0_SendCommOK()



//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// 函数: 串口0通信处理.
// 描述: 根据数据包的子命令执行相应的通信处理操作.
//
// [参数表]
//	RecData: 接收数据数组的始地址.
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
void Uart0_CommProcess(unsigned char *RecData)
{	
//	ulong	dwDstAddress;
	ulong	dwLength;
	uchar 	subCmd = RecData[6];	// 子命令
	ulong	i,j;

	switch(subCmd)
	{
		case 0:	//读控制板地址
			Uart0_SendCommOK(1);
			break;
			
		case 1:	//获取当前时间								
			SendCurrTime(UART0,UartSendBuf[UART0],RecData, UART_SEND);
			break;

		case 2:	//建立联络
			BuildConnect(UART0,UartSendBuf[UART0],RecData, UART_SEND);
			break;	
		
		case 7:		//读内存											
			ReadMemory(UartSendBuf[UART0],RecData,UART_SEND);
			UartStartSend(UART0);	
			break;
			
		case 28:	//go, 程序复位
			goCommand(MAIN_ENTRY);	// 强制跳转到目标地址
			// 注: 要根据list文件中main_boot的入口地址进行赋值.
			break;
			
		case 29:	//
			Uart0_SendCommOK(0x29);
			break;
		
		case 30:	//把程序搬到Norflash
			dwLength = RecData[7]+(RecData[8]<<8)+(RecData[9]<<16)+(RecData[10]<<24);
			j = (dwLength - 1)/NOR_FLASH_SECTOR_SIZE + 1;//擦除块数
			
			if(connect == 1)
			{
				for( i=0; i<j; i++)
				{
					if(EraseSector(i) == FALSE)
						return;
				}
				Writeflash((uchar *)DOWNLOAD_SDRAM_ADDR,0,dwLength);

				Uart0_SendCommOK(0x55);
			}
			break;

		case 255://卸去连接			
			connect = 0;			
			Uart0_SendCommOK(0x55);	
			break;				

		default:	break;
	}//switch(SubCmd)	
}//Uart0_CommProcess()



//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// 函数: 网络发送通信成功.
// 描述: 向上位机发送通信成功数据包.
//
// [参数表]
//	port: 串口号. 0-UART0; 1-UART1; 2-UART2.
//	sendData: 发送数据数组始地址.
//	RecData: 接收数据数组始地址.
// 	status: 状态.
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
void NetSendCommOK(uchar port,uchar *sendData, uchar *RecData, uchar status)
{
	DWORD i;

	sendData[0] = 2;
	sendData[1] = 12;
	sendData[2] = RecData[5];
	sendData[3] = RecData[4];
	sendData[4] = RecData[3];	// 本机地址
	sendData[5] = RecData[6];	// 子命令
	sendData[6] = status;
	sendData[7] = RecData[7];
	sendData[8] = RecData[8];
	sendData[9] = RecData[9];
	sendData[10] = RecData[10];

	CalCommSum(port, sendData, NET_SEND);

	for(i=0;i<2000;i++);
	NetTrPack(sendData,cIpAddr,wport,sendData[1]);//NETTS
}//NetSendCommOK()



//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// 函数: 发送当前时间.
//
// [参数表]
//	port: 串口号. 0-UART0; 1-UART1; 2-UART2.
//	sendData: 发送数据数组的始地址.
//	RecData: 接收数据数组的始地址.
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
void SendCurrTime (uchar port,uchar *sendData, uchar *RecData, uchar sendType)
{
	int i;
	
	connect = 0;
	sendData[0] = 2;
	sendData[1] = 7+6;
	sendData[2] = RecData[5];
	sendData[3] = RecData[4];
	sendData[4] = bTouchAddr;		//本机地址
	sendData[5] = RecData[6];//子命令										
	
	dwTemp = rTCNTO4;
	sendData[6] = dwTemp&0xFF;
	sendData[7] = (dwTemp>>8);			
	
	dwTemp = dwTickCount+300;		//记录当前时间
	sendData[8] = (dwTemp-300)&0xFF;
	sendData[9] = ((dwTemp-300)>>8) ^ sendData[6];
	sendData[10] = ((dwTemp-300)>>16) ^ sendData[6] ^ 0x78;
	sendData[11] = ((dwTemp-300)>>24) ^ sendData[5] ^ 0x34;							
	CalCommSum(port,sendData,sendType);
	
	if(sendType == UART_SEND)
		UartStartSend(port);
	else
	{
		for(i=0;i<2000;i++);
		NetTrPack(sendData,cIpAddr,wport,sendData[1]);
	}
}//SendCurrTime()



//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// 函数: 建立连接.
//
// [参数表]
//	port: 串口号. 0-UART0; 1-UART1; 2-UART2.
//	sendData: 发送的数据数组的始地址.
//	RecData: 接收数据数组的始地址.
// 	sendType: 通信方式. 0-串口; 1-网络.
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
void BuildConnect(uchar port, uchar *sendData, uchar *RecData, uchar sendType)
{
	int i,j;
	
	if( dwTemp > dwTickCount )
	{	
		//以dwTickCount(dwTemp - 300)为种子 经上位机做作计算的值(加上了一个
		//随机值RecData[7]*60*1000)
		i = RecData[8] + (RecData[9]<<8) + (RecData[10]<<16) + (RecData[11]<<24);
		
		j = RecData[7] *60000;

		if( i == (j + dwTemp - 300) )
		{	
			connect = 1;							
			if( sendType == UART_SEND )
				Uart0_SendCommOK(0x55);
			else
				NetSendCommOK(UART0,UartSendBuf[UART0],RecData,0x55);
		}
		else
			if( sendType == UART_SEND )
				Uart0_SendCommOK(0x55);
			else
				NetSendCommOK(UART0,UartSendBuf[UART0],RecData,0x57);
	}
	else
		if( sendType == UART_SEND )
			Uart0_SendCommOK(0x55);
		else
			NetSendCommOK(UART0,UartSendBuf[UART0],RecData,0x56);
}//BuildConnect()




//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// 函数: 网络通信处理.
// 描述: 根据数据包的子命令执行相应的通信处理操作.
//
// [参数表]
//	RecData: 接收数据数组的始地址.
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
void NetCommProcess (uchar *RecData)
{	
	ulong	dwDstAddress;
	ulong	j,k;
	ulong 	dwLength;
	uchar 	subCmd = RecData[6];	// 子命令
	uchar 	udpData[4096];
	
	switch( subCmd )
	{
		case 0:	//读控制板地址
			NetSendCommOK(UART0,UartSendBuf[UART0],RecData,bTouchAddr);
			break;
			
		case 1:	//获取当前时间								
			SendCurrTime(UART0,UartSendBuf[UART0], RecData, NET_SEND);
			break;

		case 2:	//建立联络
			BuildConnect(UART0,UartSendBuf[UART0], RecData, NET_SEND);
			break;	

			
		case 7:		//读内存											
			ReadMemory(udpData,RecData,NET_SEND);
			NetTrPack(udpData,cIpAddr,wport,udpData[1]);
			break;
			
		case 8:		//写内存
			dwDstAddress = RecData[7]+(RecData[8]<<8)+(RecData[9]<<16)+(RecData[10]<<24);							
			dwLength = RecData[11]|(RecData[12]<<8);								
			memcpy((char *)dwDstAddress,(char *)&RecData[13],dwLength);
			NetSendCommOK(UART0,UartSendBuf[UART0],RecData,0x55);
			break;  
			
		case 26:
			nand_init();
			break;

		case 28:	//go
			goCommand(MAIN_ENTRY);
			break;
			
		case 29:	//
			NetSendCommOK(UART0,UartSendBuf[UART0],RecData,0x55);
			break;
			
		case 30:	//把程序从SDRAM搬到Norflash
			dwLength = RecData[7]+(RecData[8]<<8)+(RecData[9]<<16)+(RecData[10]<<24);
			j = (dwLength - 1)/NOR_FLASH_SECTOR_SIZE + 1;//擦除块数
			
			if(connect == 1)
			{
				for(k=0;k<j;k++)
				{
					if(EraseSector(k) == FALSE) return;
				}
				Writeflash((uchar *)DOWNLOAD_SDRAM_ADDR,0,dwLength);

				NetSendCommOK(UART0,UartSendBuf[UART0],RecData,0x55);
			}
			break;

		case 31:	// 当程序下载到SDRAM后, 直接跳转到其入口运行
			NetSendCommOK(UART0,UartSendBuf[UART0],RecData,0x55);
			goCommand(DOWNLOAD_SDRAM_ADDR);
			break;
			
		case 33:	// 读NandFlash
			break;
			
		case 34:	// 写NandFlash
			dwDstAddress = RecData[7]+(RecData[8]<<8)+(RecData[9]<<16)+(RecData[10]<<24);							
			dwLength = RecData[11]|(RecData[12]<<8);
			if(NandWriteData((u32)dwDstAddress,(u32)&RecData[13],(u32)dwLength) == 0)
			{
				NetSendCommOK(UART0,UartSendBuf[UART0],RecData,0x55);
			}
			break;
			
		case 82:	// 初始化网络
			DM9000_init();
			break;

		case 83:	// 检查网卡数据	

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -