📄 obj_svcxmodem.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 + -