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

📄 xmodem.c

📁 基于2410的一个iis总线测试程序 声音控制芯片是飞利浦的UTS1341 可通过xmodem发送声音文件(WAV)到内存
💻 C
字号:
//=====================
//file name: xmodem.c
//Discription: provide some xmodem-relative method used by the monitor program
//Author: Decell.Zhou
//Version:
//			0.1|071107
//			0.2|071108
//=====================
#include "xmodem.h"

//define a array to store the data package
unsigned char dataBuffer[135];
//define a variable to store the the port number we are using to transmit the data
static unsigned char portNum;
//the pointer point to the physical start address of a new block
static unsigned char *pDestinationHead;
//the pointer point to the physical stop address of a new block
static unsigned char *pDestinationTail;

//==============[portSelect]================
//Discription:the method is used to select a uart port for transmission
//Author:Decell.Zhou
//Version:
//pram:argPortNum|char|the uart port number
//return:none
//==========================================
void portSelect(char argPortNum){
	if(argPortNum == 0 || argPortNum == 1){//we only allow to used port 0 and port 1
		portNum = argPortNum;
	}
}


//==============[xmodemGetByte]=====
//Discription: get a Byte from the serial port, it's different from the 2410lib.c's Uart_Getch() because it
//turn on the RxD FIFO for xmodem transmission
//Author: Decell.Zhou
//Version:
//pram: none
//return:the content of the serial receive buffer|unsigned char
//==================================
unsigned char xmodemGetByte(void){
	switch(portNum){
		case 0:{
			while((rUFSTAT0 & (0xF)) == 0);//wait while the Rx FIFO have no data
			return RdURXH0();
			break;
		}
		case 1:{
			while((rUFSTAT1 & (0xF)) == 0);//wait while the Rx FIFO have no data
			return RdURXH1();
			break;
		}
		default:{
			break;
		}
	}
}

//==============[xmodemGetKey]=====
//Discription: get a Byte from the serial port, it's different from the 2410lib.c's Uart_GetKey() because it
//turn on the RxD FIFO for xmodem transmission
//Author: Decell.Zhou
//Version:
//pram: none
//return:	0|when the receive FIFO is null
//			context of the receive buffer|unsigned char
//==================================
unsigned char xmodemGetKey(void){
	switch(portNum){
		case 0:{
			if((rUFSTAT0 & (0xF)) == 0){//if the Rx FIFO have no data
				return 0;
			}else{
				return RdURXH0();
			}
			break;
		}
		case 1:{
			if((rUFSTAT1 & (0xF)) == 0){//if the Rx FIFO have no data
				return 0;
			}else{
				return RdURXH1();
			}
			break;
		}
		default:{
			break;
		}
	}
}

//==============[xmodemSendByte]=====
//Discription: Send a Byte to the serial port, it's different from the 2410lib.c's Uart_Getch() because it
//turn on the TxD FIFO for xmodem transmission
//Author: Decell.Zhou
//Version:
//pram: data|unsigned char|the data you want to transmit
//return:none
//==================================
void xmodemSendByte(unsigned char data){
	int i;
	switch(portNum){
		case 0:{
			while((rUFSTAT0 & (0x1<<9)) == 1);//wait while the Tx FIFO have not been full
			for(i = 0;i <= 1000;i++);
			WrUTXH0(data);
			break;
		}
		case 1:{
			while((rUFSTAT1 & (0x1<<9)) == 1);//wait while the Tx FIFO have not been full
			for(i = 0;i <= 1000;i++);
			WrUTXH1(data);
			break;
		}
		default:{
			break;
		}
	}
}


//==============[xmodemFIFOReset]==========
//Discription:Reset the uartFIFO
//Author:Decell.Zhou
//Version:
//pram:none
//return:
//=========================================
void xmodemFIFOReset(void ){}

//==============[xmodemLEDON]=============
//Discription:turn on the LED,that is GPF7 and GPF4
//Author:Decell.Zhou
//Version:
//pram:none
//return: none
//=========================================
void xmodemLEDON(void){
	rGPFCON |= ((0x1 << 14)|(0x1 <<8));//set GPF7 and GPF4 as output
	rGPFDAT &= ~((0x1 << 7)|(0x1 << 4));//set the out put the low, turn on the LED
}

//==============[xmodemLEDOFF]=============
//Discription:turn off the LED
//Author:Decell.Zhou
//Version:
//pram:none
//return:none
//=========================================
void xmodemLEDOFF(void){
	
	rGPFDAT |= ((0x1 << 7)|(0x1 << 4));//set the out put the high, turn off the LED
	rGPFCON &= ~((0x2 << 14) | (0x2 << 8));//set GPF7 and GPF4 as input 
}


//==============[xmodemInit]========
//Discription: make preparation for the xmodem transmit
//Author:Decell.Zhou
//Version:
//pram:destination|unsigned int|the destination address to store the data
//return:none
//==================================
void xmodemInit(unsigned int destination){
	int i;
	pDestinationHead = (unsigned char *)destination;//set the destination head pointer to the target RAM address
	pDestinationTail = (unsigned char *)destination;//set the destination tail pointer to the target RAM address
	
	for(i = 0;i < 135;i++){//clear the data buffer
		dataBuffer[i] = 0;
	}
	
	Uart_FIFOON();//turn on the FIFO for the UART
	portSelect(0);//select port0 as our transmit port
	
	
}

//=============[xmodemTransmit]=====
//Discription: transmit data to a sepcified address under the xmodem protocal
//				this method will store the data to the address PROGRAM_RO_BASE
//Author:Decell.Zhou
//Version:
//pram:destination|unsigned int|the destination address to store the data
//return:
//		0|char|transmit successful
//		1|char|transmit fault 
//==================================
char xmodemTransmit(unsigned int destination){
	

	char receiveReady ;//this variable indicate the 
	unsigned char nextBlockNum;//this variable indicate the number of the block me are going to receive
	unsigned char curBlockNum;//this variable indicate the number of the block me received in the last time
	unsigned char checkSum;//the checksum for each block
	unsigned char byteCount;
	unsigned int i;
	unsigned char nakCount;//store how many times that the receiver has been send
	unsigned char transResp;//the respond from the transmitter
	//the varivable indicatting the receiver's state
	unsigned char receiverStat;	//1: send ACK
								//2: send NAK
								//3: send CAN
								//4: reserve
								//5: reserve
								//6: reserve
								//7: reserve
								//8: reserve
								  
 	xmodemInit(destination);//make preparation for xmodem transmition
	receiveReady = 1;//now we are ready to receive the data
	curBlockNum = 0;//initial blockNum
	nextBlockNum = 1;//initial blockNum
	receiverStat = 0;
	transResp = 0;
	
	//waiting for the SOHsignal
	xmodemSendByte(NAK);//send NAK signal, waiting for the sender's SOH signal
	setTimer(2);//set ten second to expire
	for(;xmodemGetKey() != SOH ;){//if we don't get the SOH signal
		if(timerExpire() == 1){//if the receiver has been time out,send another NAK
			xmodemSendByte(NAK);
			setTimer(2);
		}
	}	
	
	
	
	//receive the data block
	for(;receiveReady == 1;){
		
		xmodemLEDOFF();
		//receive 131 bytes in total
		setTimer(1);//set time  to count down 1 second
		for(byteCount = 0;(byteCount < 131) && (!timerExpire());){//received 131byte
			dataBuffer[byteCount] = xmodemGetByte();				  //include 2 numbyte, 128 data byte, 
			setTimer(1);										  //1 chechsum byte
			byteCount ++;							              
		}
		
		//========================================
		/*
		//for package debuging
		for(i = 0;i<=1000;i++){
			xmodemSendByte(ACK);
		}
		
		for(i = 0; i < 135;i++){
			Uart_Printf("%x ",dataBuffer[i]);
		}
		for(;;);
		*/
		//========================================
		
		
		//analyizing the data block 
		if(dataBuffer[0] == (~dataBuffer[1] & 0xff)){//the blockNum is avaiable	//if(dataBuffer[0] == (~dataBuffer[1] & 0xff))		
			if(dataBuffer[0] == nextBlockNum){//if the blockNum is correct
				if(byteCount == 131){//the count of the byte is correct			
					for(i = 2,checkSum = 0;i <= 129;i++){//calculate the ckecksum
						checkSum += dataBuffer[i];
					}
					if(checkSum == dataBuffer[130]){//the ckeckSum is correct						
						receiverStat = 1;//every goes right, send ACK
						//copy the data to ram
						for(i = 2;i <= 129;i++){
							*pDestinationTail = dataBuffer[i];
							pDestinationTail ++;
						}
					pDestinationHead = pDestinationTail;
					curBlockNum = nextBlockNum;//increase the block number
					nextBlockNum ++;	
					}else{
						receiverStat = 2;//the ckeck Sum isn't correct, send NAK
					}
				}else{			
					receiverStat = 2;//the count of the byte isn't have correct length, send NAK signal
				}
			}else if (dataBuffer[0] == curBlockNum){
				receiverStat = 1;//data block repeated, resend ACK again
			}else{
				receiverStat = 3;//fatal eorro occur,send CAN return and request resend 
			}
		}else{
			receiverStat = 2;//the blockNum is not avaiable,send NAK signal
		}
		
		
		
		xmodemLEDON();
		//receiver makes action according to the receiver status
		if(receiverStat == 1){//send ACK
			xmodemSendByte(ACK);
			nakCount = 0;//clear nak counter
			//wating for the next time transmission
			setTimer(2);//set timer for 10sec time out
			transResp = xmodemGetKey();
			for(;transResp != SOH && transResp != EOT && transResp != CAN ;){//if we don't get the SOH signal
				if(timerExpire() == 1){//if the receiver has been time out,send NAK
					xmodemSendByte(NAK);
					nakCount++;
					setTimer(2);
				}
				if(nakCount == 10){//fatal error, we may be losting the host,return,request for resend
					xmodemSendByte(CAN);//send CAN for three times
					xmodemSendByte(CAN);
					xmodemSendByte(CAN);
					return 1;
				}
				
				transResp = xmodemGetKey();//get responding from the host 
			}
			if(transResp == SOH){
				receiveReady = 1;
				nakCount = 0;
			}else if(transResp == EOT){//transmission complete!
				xmodemSendByte(ACK);
				//xmodemSendByte(ACK);
				return 0;
			}else{//get CAN singnal
				return 1;//transmission cancel;
				//=============================
				//cleaning code add here
				//=============================
			}

		}else if(receiverStat == 2){//send NAK
			xmodemSendByte(NAK);
			nakCount = 0;//clear nak counter
			//wating for the next time transmission
			setTimer(2);//set timer for 10sec time out
			transResp = xmodemGetKey();
			for(;transResp != SOH && transResp != EOT && transResp != CAN ;){//if we don't get the SOH signal
				if(timerExpire() == 1){//if the receiver has been time out,send NAK
					xmodemSendByte(NAK);
					nakCount++;
					setTimer(2);
				}
				if(nakCount == 10){//fatal error, we may be losting the host,return,request for resend
					xmodemSendByte(CAN);//send CAN for three times
					xmodemSendByte(CAN);
					xmodemSendByte(CAN);
					return 1;
				}
				
				transResp = xmodemGetKey();//get responding from the host 
			}
			if(transResp == SOH){
				receiveReady = 1;
				nakCount = 0;
			}else if(transResp == EOT){//transmission complete!
				xmodemSendByte(ACK);
				//xmodemSendByte(ACK);
				return 0;
			}else{//get CAN singnal
				return 1;//transmission cancel;
				//=============================
				//cleaning code add here
				//=============================
			}
		}else if(receiverStat == 3){//send CAN
			
			xmodemSendByte(CAN);//send CAN for three times
			xmodemSendByte(CAN);
			xmodemSendByte(CAN);
			return 1;
		}else{
			//reserve for futher improvment
		}
		

	}
	
	
	
	
	
		
}

//=============[xmodemJump]=========
//Discription: jump to the  PROGRAM_RO_BASE,exeute the user prgram
//Author:Decell.Zhou
//Version:
//pram:none
//return:none
//==================================
void xmodemJump(void){
	void (*pProgramEntrance)(void);
	
	pProgramEntrance = (void (*)(void))PROGRAM_RO_BASE;//set up the entance
	
	pProgramEntrance();
}



⌨️ 快捷键说明

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