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

📄 obj_svcxmodem.c

📁 基于K9 AT91RM9200 学习板的loader源码
💻 C
字号:
//*----------------------------------------------------------------------------//*      ATMEL Microcontroller Software Support  -  ROUSSET  -//*----------------------------------------------------------------------------//* The software is delivered "AS IS" without warranty or condition of any//* kind, either express, implied or statutory. This includes without//* limitation any warranty or condition with respect to merchantability or//* fitness for any particular purpose, or against the infringements of//* intellectual property rights of others.//*----------------------------------------------------------------------------//* File Name           : obj_svcxmodem.c//* Object              : Send and receive funtions for USB device peripheral//*//* 1.0 20/06/01 	    : ODi Creation//*----------------------------------------------------------------------------#include "services/obj_buffer.h"#include "services/obj_svcxmodem.h"#include "periph/usart2/lib_usart2.h"#define CRC16POLY   0x1021              /* CRC 16  polynom *///*----------------------------------------------------------------------------//* Function Name       : XmCheckHeader//* Object              : Compute the CRC//* Input Parameters    : <ptr>  char pointer//*                       <count> nb of char//* Output Parameters   : crc value//*----------------------------------------------------------------------------char AT91F_SvcXmodemCheckHeader(unsigned char currentPacket, char *packet){	// Check that bloc number and bloc checksum are OK	if ( (packet[0] + packet[1]) != 0xff )		return 0;	// Check that this is a sequential block number	if ( packet[0] != currentPacket )		return 0;	return 1;}//*----------------------------------------------------------------------------//* Function Name       : AT91F_SvcXmodemCheckCrc//* Object              : Compute the CRC//* Input Parameters    : <ptr>  char pointer//*                       <count> nb of char//* Output Parameters   : crc value//*----------------------------------------------------------------------------unsigned short AT91F_SvcXmodemGetCrc(char *ptr, unsigned int count){    unsigned short crc, cmpt;    crc = 0;    //* For  all char    while (count--)    {        crc = crc ^ (int) *ptr++ << 8;        //* For All bit        for (cmpt = 0; cmpt < 8; cmpt++)        {            if (crc & 0x8000)                crc = crc << 1 ^ CRC16POLY;            else                crc = crc << 1;        }//* end bit    }//* Frame end    return (crc & 0xFFFF);}//*----------------------------------------------------------------------------//* Function Name       : AT91F_SvcXmodemCheckData//* Object              : check the data frame, increment the address if OK//* Input Parameters    : pointer to XmData//* Output Parameters   : 1 OK, 0 not OK//*----------------------------------------------------------------------------char AT91F_SvcXmodemCheckData(AT91PS_SvcXmodem pSvcXmodem){	unsigned short crc;	char         *pData   = pSvcXmodem->pData;	unsigned int dataSize = pSvcXmodem->dataSize;	crc = pSvcXmodem->GetCrc(pData, dataSize);	if ( (pData[dataSize]   == (unsigned char)(crc >> 8)) &&	     (pData[dataSize+1] == (unsigned char)(crc)) )	{		pSvcXmodem->pData += dataSize;		return 1;	}	else		return 0;}//*----------------------------------------------------------------------------//* Function Name       : OpenUdpService()//* Object              ://* Input Parameters    ://* Output Parameters   : none//*----------------------------------------------------------------------------AT91PS_SvcComm AT91F_OpenSvcXmodem(	AT91PS_SvcXmodem pSvcXmodem,	AT91PS_USART2    pUsart,	AT91PS_CtlTempo  pCtlTempo){	AT91PS_SvcComm pSvcComm = &(pSvcXmodem->parent);	// Init AT91S_CommSvc base structure	// Init AT91PS_SvcComm methods	pSvcComm->Reset        = (AT91PF_SvcCommReset)   0;	pSvcComm->StartTx      = AT91F_SvcXmodemStartTx;	pSvcComm->StartRx      = AT91F_SvcXmodemStartRx;	pSvcComm->StopTx       = AT91F_SvcXmodemStopTx;	pSvcComm->StopRx       = AT91F_SvcXmodemStopRx;	pSvcComm->TxReady      = AT91F_SvcXmodemTxReady;	pSvcComm->RxReady      = AT91F_SvcXmodemRxReady;	// Init AT91PS_SvcComm data	pSvcComm->pChild       = (void *) pSvcXmodem;	pSvcComm->pBuffer      = (AT91PS_Buffer) 0;	// Init AT91PS_SvcXmodem methods	pSvcXmodem->ReadHandler  = AT91F_SvcXmodemReadHandler;	pSvcXmodem->WriteHandler = AT91F_SvcXmodemWriteHandler;	pSvcXmodem->GetCrc       = AT91F_SvcXmodemGetCrc;	pSvcXmodem->CheckHeader  = AT91F_SvcXmodemCheckHeader;	pSvcXmodem->CheckData    = AT91F_SvcXmodemCheckData;	// Init AT91PS_SvcXmodem data	pSvcXmodem->pUsart = pUsart;	// Attach the tempo to a tempo controler	pCtlTempo->CtlTempoCreate(pCtlTempo, &(pSvcXmodem->tempo));	return pSvcComm;}//*----------------------------------------------------------------------------//* Function Name       : AT91F_SvcXmodemRead()//* Object              : Receive an XMODEM file with the USART, update the//*                       linked buffer structure//* Input Parameters    : AT91PS_SvcXmodem, AT91PS_USART2->US_CSR//* Output Parameters   : none//*----------------------------------------------------------------------------AT91S_SvcCommStatus AT91F_SvcXmodemReadHandler(AT91PS_SvcXmodem pSvcXmodem, unsigned int csr){	AT91PS_USART2      pUsart  = pSvcXmodem->pUsart;	AT91PS_Buffer      pBuffer = (AT91PS_Buffer) pSvcXmodem->parent.pBuffer;	char *pData;	unsigned int bufSize;	char c;	if ( (csr & US_RXRDY) ) {		// Stop sending 'C'		pSvcXmodem->tempo.Stop(&(pSvcXmodem->tempo));		pSvcXmodem->isPacketDesc = 1;		pBuffer->GetRdBuffer(pBuffer, &pData, &bufSize);		pSvcXmodem->pData    = pData;		c = at91_usart2_getChar(pUsart);		switch (c) {			case AT91C_XMODEM_STX:				pSvcXmodem->dataSize = AT91C_XMODEM_DATA_SIZE_STX;				at91_usart2_receive_frame (					pUsart,					pSvcXmodem->packetDesc, AT91C_XMODEM_PACKET_SIZE,					pData, AT91C_XMODEM_DATA_SIZE_STX + AT91C_XMODEM_CRC_SIZE);				break;			case AT91C_XMODEM_SOH:				pSvcXmodem->dataSize = AT91C_XMODEM_DATA_SIZE_SOH;				at91_usart2_receive_frame (					pUsart,					pSvcXmodem->packetDesc, AT91C_XMODEM_PACKET_SIZE,					pData, AT91C_XMODEM_DATA_SIZE_SOH + AT91C_XMODEM_CRC_SIZE);				break;			case AT91C_XMODEM_EOT:				at91_usart2_sendChar(pUsart, AT91C_XMODEM_ACK);				at91_usart2_usidr(pUsart, US_RXRDY | US_ENDRX | US_RXBUFF);												if ( (pSvcXmodem->packetId == 1) || bufSize)					pBuffer->FillRdBuffer(pBuffer, bufSize);				pSvcXmodem->eot = 1;				return AT91C_COMMSVC_SUCCESS;			default:				at91_usart2_receive_frame (					pUsart,					pData, AT91C_XMODEM_PACKET_SIZE + AT91C_XMODEM_DATA_SIZE_SOH + AT91C_XMODEM_CRC_SIZE,					0, 0);				at91_usart2_sendChar(pUsart, AT91C_XMODEM_ACK);				break;		}		at91_usart2_usidr(pUsart, US_RXRDY);		at91_usart2_usier(pUsart, US_ENDRX);	}	else if ( (csr & US_ENDRX) || (csr & US_RXBUFF) ) {		if (pSvcXmodem->isPacketDesc) {			pSvcXmodem->packetStatus = pSvcXmodem->CheckHeader(pSvcXmodem->packetId, pSvcXmodem->packetDesc);			pSvcXmodem->isPacketDesc = 0;			at91_usart2_usidr(pUsart, US_ENDRX);			at91_usart2_usier(pUsart, US_RXBUFF);		}		else {			if (pSvcXmodem->packetStatus && pSvcXmodem->CheckData(pSvcXmodem)) {				pBuffer->FillRdBuffer(pBuffer, pSvcXmodem->dataSize);				at91_usart2_sendChar(pUsart, AT91C_XMODEM_ACK);				++(pSvcXmodem->packetId);			}			else				at91_usart2_sendChar(pUsart, AT91C_XMODEM_NAK);			at91_usart2_usidr(pUsart, US_ENDRX | US_RXBUFF);			at91_usart2_usier(pUsart, US_RXRDY);		}	}	return AT91C_COMMSVC_SUCCESS;}//*----------------------------------------------------------------------------//* Function Name       : AT91F_SvcXmodemWrite()//* Object              : Receive an XMODEM file with the USART, update the//*                       linked buffer structure//* Input Parameters    : AT91PS_SvcXmodem, AT91PS_USART2->US_CSR//* Output Parameters   : none//*----------------------------------------------------------------------------AT91S_SvcCommStatus AT91F_SvcXmodemWriteHandler(AT91PS_SvcXmodem pSvcXmodem, unsigned int csr){	AT91PS_USART2      pUsart  = pSvcXmodem->pUsart;	AT91PS_Buffer      pBuffer = (AT91PS_Buffer) pSvcXmodem->parent.pBuffer;	char const *pData;	unsigned int bufSize;	unsigned short crc;	if ( (csr & US_RXRDY) ) {		pBuffer->GetWrBuffer(pBuffer, &pData, &bufSize);		switch ( at91_usart2_getChar(pUsart) ) {		case 'C':			pSvcXmodem->packetId = 1; // Current packet			if (bufSize == 0)				pBuffer->EmptyWrBuffer(pBuffer, 0);			break;		case AT91C_XMODEM_ACK:			// Previous block has been received correctly			if ( !(pSvcXmodem->eot) ) {				pBuffer->EmptyWrBuffer(pBuffer, AT91C_XMODEM_DATA_SIZE_SOH);				bufSize = 0;			}			++(pSvcXmodem->packetId);			break;		case AT91C_XMODEM_NAK:			// Previous block must be resent			break;		default:			break;		}		if (bufSize == 0) {			at91_usart2_usidr(pUsart, US_ENDRX | US_ENDTX | US_TXRDY);			at91_usart2_sendChar(pUsart, AT91C_XMODEM_EOT);			pSvcXmodem->eot = 1;		}		else {			pSvcXmodem->pData = (char *) pData;			pSvcXmodem->eot           = 0;			at91_usart2_sendChar(pUsart, AT91C_XMODEM_SOH);			at91_usart2_usier(pUsart, US_TXRDY);		}	}	else if ( (csr & US_TXRDY) ) {		pSvcXmodem->packetDesc[0] = pSvcXmodem->packetId;		pSvcXmodem->packetDesc[1] = ~(pSvcXmodem->packetId);		at91_usart2_send_frame (			pUsart,			pSvcXmodem->packetDesc, AT91C_XMODEM_PACKET_SIZE,			pSvcXmodem->pData,      AT91C_XMODEM_DATA_SIZE_SOH);		at91_usart2_usidr(pUsart, US_TXRDY);		at91_usart2_usier(pUsart, US_ENDTX);	}	else if ( (csr & US_ENDTX) ) {		crc = pSvcXmodem->GetCrc(pSvcXmodem->pData, AT91C_XMODEM_DATA_SIZE_SOH);		crc = ((crc & 0xff00) >> 8) | ((crc & 0x00ff) << 8 );		at91_usart2_send_frame (			pUsart,			(char *) &crc, AT91C_XMODEM_CRC_SIZE,			(char *) 0,0);		at91_usart2_usidr(pUsart, US_ENDTX);	}	return AT91C_COMMSVC_SUCCESS;}//*----------------------------------------------------------------------------//* Function Name       : AT91F_SvcUdpStartTx()//* Object              ://* Input Parameters    : AT91PS_SvcComm//* Output Parameters   : none//*----------------------------------------------------------------------------AT91S_SvcCommStatus AT91F_SvcXmodemStartTx(AT91PS_SvcComm pSvcComm){	AT91PS_SvcXmodem   pSvcXmodem = (AT91PS_SvcXmodem) pSvcComm->pChild;	AT91PS_USART2      pUsart     = pSvcXmodem->pUsart;	pSvcXmodem->Handler = pSvcXmodem->WriteHandler;	at91_usart2_usier(pUsart, US_RXRDY);	return AT91C_COMMSVC_SUCCESS;}//*----------------------------------------------------------------------------//* Function Name       : AT91F_SvcUdpStoptTx()//* Object              ://* Input Parameters    : AT91PS_SvcComm//* Output Parameters   : none//*----------------------------------------------------------------------------AT91S_SvcCommStatus AT91F_SvcXmodemStopTx(AT91PS_SvcComm pSvcComm){	return AT91C_COMMSVC_SUCCESS;}//*----------------------------------------------------------------------------//* Function Name       : AT91F_SvcXmodemSendC()//* Object              ://* Input Parameters    : AT91PS_SvcComm//* Output Parameters   : none//*----------------------------------------------------------------------------void AT91F_SvcXmodemSendC(AT91S_TempoStatus status, void *pVoid){		AT91PS_USART2 pUsart = (AT91PS_USART2) pVoid;		at91_usart2_sendChar(pUsart, 'C');}//*----------------------------------------------------------------------------//* Function Name       : AT91F_SvcXmodemStartRx()//* Object              ://* Input Parameters    : AT91PS_SvcComm//* Output Parameters   : none//*----------------------------------------------------------------------------AT91S_SvcCommStatus AT91F_SvcXmodemStartRx(AT91PS_SvcComm pSvcComm){	AT91PS_SvcXmodem   pSvcXmodem = (AT91PS_SvcXmodem) pSvcComm->pChild;	AT91PS_USART2      pUsart     = pSvcXmodem->pUsart;	pSvcXmodem->Handler = pSvcXmodem->ReadHandler;	pSvcXmodem->packetId     = 1; // Current packet	pSvcXmodem->eot          = 0; // end of transmition	pSvcXmodem->isPacketDesc = 0;	at91_usart2_usier(pUsart, US_RXRDY);	at91_usart2_usidr(pUsart, US_ENDRX | US_ENDTX | US_TXRDY);		pSvcXmodem->tempo.Start(&(pSvcXmodem->tempo), 1000, 1000, AT91F_SvcXmodemSendC, pUsart);//	pSvcXmodem->tempo.Start(&(pSvcXmodem->tempo), 5, 5, AT91F_SvcXmodemSendC, pUsart);	return AT91C_COMMSVC_SUCCESS;}//*----------------------------------------------------------------------------//* Function Name       : AT91F_SvcUdpStoptRx()//* Object              ://* Input Parameters    : AT91PS_SvcComm//* Output Parameters   : none//*----------------------------------------------------------------------------AT91S_SvcCommStatus AT91F_SvcXmodemStopRx(AT91PS_SvcComm pSvcComm){	return AT91C_COMMSVC_SUCCESS;}//*----------------------------------------------------------------------------//* Function Name       : AT91F_UdpTxReady()//* Object              : Return the status of the USB//* Input Parameters    ://* Output Parameters   : none//*----------------------------------------------------------------------------char AT91F_SvcXmodemTxReady(AT91PS_SvcComm pSvcComm){	AT91PS_SvcXmodem   pSvcXmodem = (AT91PS_SvcXmodem) pSvcComm->pChild;	AT91PS_USART2      pUsart     = pSvcXmodem->pUsart;	return (AT91F_US_CSR(pUsart) & US_TXRDY);}//*----------------------------------------------------------------------------//* Function Name       : AT91F_UdpRxReady()//* Object              : Return the status of the USB//* Input Parameters    ://* Output Parameters   : none//*----------------------------------------------------------------------------char AT91F_SvcXmodemRxReady(AT91PS_SvcComm pSvcComm){	AT91PS_SvcXmodem   pSvcXmodem = (AT91PS_SvcXmodem) pSvcComm->pChild;	AT91PS_USART2      pUsart     = pSvcXmodem->pUsart;	return (AT91F_US_CSR(pUsart) & US_RXRDY);}

⌨️ 快捷键说明

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