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

📄 obj_svcudp.c

📁 AT91rm9200的引导代码
💻 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           : drv_usb.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_svcudp.h"
#include "periph/udp/lib_udp.h"

#ifdef DBG_OBJ_UDP
#include <assert.h>
const char *UdpErrMsg[] = {
	"(AT91_SvcUdp) Receive has failed",
	"(AT91_SvcUdp) Read buffer not ready"
	"(AT91_SvcUdp) Receive not allowed",
	"(AT91_SvcUdp) Write failed",
	"(AT91_SvcUdp) Write not ready",
	"(AT91_SvcUdp) Write aborted",
	"(AT91_SvcUdp) Unknown message"
};
#endif
//*----------------------------------------------------------------------------
//* Function Name       : OpenUdpService()
//* Object              :
//* Input Parameters    :
//* Output Parameters   : none
//*----------------------------------------------------------------------------
AT91PS_SvcComm AT91F_OpenSvcUdp(
	AT91PS_SvcUdp pSvcUdp,
	AT91PS_UDP   pUdp,
	char         epId,
	unsigned int epSize)
{
	AT91PS_SvcComm pSvcComm = &(pSvcUdp->parent);

#ifdef DBG_DRV_UDP
	assert(pSvcUdp);
	assert(pUdp);
	assert(pSvcComm);
#endif

	// Init AT91S_CommSvc base structure

	// Init methods
	pSvcComm->Reset        = (AT91PF_SvcCommReset)   0;
	pSvcComm->StartTx      = AT91F_SvcUdpStartTx;
	pSvcComm->StartRx      = AT91F_SvcUdpStartRx;
	pSvcComm->StopTx       = AT91F_SvcUdpStopTx;
	pSvcComm->StopRx       = AT91F_SvcUdpStopRx;
	pSvcComm->TxReady      = AT91F_SvcUdpTxReady;
	pSvcComm->RxReady      = AT91F_SvcUdpRxReady;

	// Init data
	pSvcComm->pChild       = (void *) pSvcUdp;
	pSvcComm->pBuffer      = (AT91PS_Buffer) 0;

	// Init AT91S_UdpEp structure
	pSvcUdp->HandleRx   = AT91F_SvcUdpControlHandleRx;
	pSvcUdp->HandleTx   = AT91F_SvcUdpControlHandleTx;
	pSvcUdp->pUdp       = pUdp;
	pSvcUdp->epId       = epId;
	pSvcUdp->epSize     = epSize;
	pSvcUdp->bank       = UDP_RCV_DATA_BANK0;
	pSvcUdp->operation  = AT91C_SVCUDP_CTL_RD;

	return pSvcComm;
}

//*----------------------------------------------------------------------------
//* Function Name       : AT91F_SvcUdpStartTx()
//* Object              : Send or receive a payload with the USB, update the
//*                       linked buffer structure
//* Input Parameters    : AT91PS_SvcComm
//* Output Parameters   : none
//*----------------------------------------------------------------------------
AT91S_SvcCommStatus AT91F_SvcUdpStartTx(AT91PS_SvcComm pSvcComm)
{
	AT91PS_Buffer  pBuffer  = (AT91PS_Buffer) pSvcComm->pBuffer;
	AT91S_BufferStatus status = AT91C_COMMSVC_SUCCESS;
	char const *pWrData;
	unsigned int bufSize;
	AT91PS_SvcUdp pSvcUdp  = (AT91PS_SvcUdp) pSvcComm->pChild;

	pSvcUdp->operation = AT91C_SVCUDP_CTL_RD;
	// Get how many bytes to send now
	status = pBuffer->GetWrBuffer(pBuffer, &pWrData, &bufSize);
	if (status )
		status = (AT91C_SVCUDP_WR_FAILED | status);
	// Send the first packet
	if (pSvcUdp->epSize < bufSize)
		AT91F_UdpEpWrite(pSvcUdp->pUdp, pSvcUdp->epId, pWrData, pSvcUdp->epSize);
	else if (bufSize)
		AT91F_UdpEpWrite(pSvcUdp->pUdp, pSvcUdp->epId, pWrData, bufSize);
	// Notify the end of write USB device peripheral
	AT91F_UdpEpEow(pSvcUdp->pUdp, pSvcUdp->epId);

	return AT91C_COMMSVC_SUCCESS;
}

//*----------------------------------------------------------------------------
//* Function Name       : AT91F_SvcUdpStoptTx()
//* Object              :
//* Input Parameters    : AT91PS_SvcComm
//* Output Parameters   : none
//*----------------------------------------------------------------------------
AT91S_SvcCommStatus AT91F_SvcUdpStopTx(AT91PS_SvcComm pSvcComm)
{
	AT91PS_SvcUdp pSvcUdp = (AT91PS_SvcUdp) pSvcComm->pChild;

	AT91F_UdpEpStall(pSvcUdp->pUdp, pSvcUdp->epId);
	return AT91C_COMMSVC_SUCCESS;
}

//*----------------------------------------------------------------------------
//* Function Name       : AT91F_SvcUdpStartRx()
//* Object              :
//* Input Parameters    : AT91PS_SvcComm
//* Output Parameters   : none
//*----------------------------------------------------------------------------
AT91S_SvcCommStatus AT91F_SvcUdpStartRx(AT91PS_SvcComm pSvcComm)
{
	AT91PS_SvcUdp pSvcUdp  = (AT91PS_SvcUdp) pSvcComm->pChild;

	pSvcUdp->operation = AT91C_SVCUDP_CTL_WR;

	return AT91C_COMMSVC_SUCCESS;
}

//*----------------------------------------------------------------------------
//* Function Name       : AT91F_SvcUdpStoptRx()
//* Object              :
//* Input Parameters    : AT91PS_SvcComm
//* Output Parameters   : none
//*----------------------------------------------------------------------------
AT91S_SvcCommStatus AT91F_SvcUdpStopRx(AT91PS_SvcComm pSvcComm)
{
	AT91PS_SvcUdp pSvcUdp = (AT91PS_SvcUdp) pSvcComm->pChild;

	AT91F_UdpEpStall(pSvcUdp->pUdp, pSvcUdp->epId);

	return AT91C_COMMSVC_SUCCESS;
}

//*----------------------------------------------------------------------------
//* Function Name       : AT91F_SvcUdpControlHandleRx()
//* Object              : Send or receive a payload with the USB, update the
//*                       linked buffer structure
//* Input Parameters    : AT91PS_SvcComm
//* Output Parameters   : none
//*----------------------------------------------------------------------------
AT91S_SvcCommStatus AT91F_SvcUdpControlHandleRx(AT91PS_SvcUdp pSvcUdp)
{
	AT91PS_SvcComm pService = (AT91PS_SvcComm) &(pSvcUdp->parent);
	AT91PS_Buffer  pBuffer  = (AT91PS_Buffer) pService->pBuffer;
	AT91S_BufferStatus status = AT91C_COMMSVC_SUCCESS;
	char *pRdData;
	char const *pWrData;
	unsigned int bufSize, bytesRcv;

	if (pSvcUdp->operation == AT91C_SVCUDP_CTL_RD) {
		// This is the STATUS OUT stage, it stops the transmition
		AT91F_UdpEpEor(pSvcUdp->pUdp, pSvcUdp->epId, UDP_RCV_DATA_BANK0);
		status = pBuffer->GetWrBuffer(pBuffer, &pWrData, &bufSize);
		if ( status )
			status = (AT91C_SVCUDP_WR_FAILED | status);

		// Free the remaining buffer
		if (bufSize) {
			status = pBuffer->EmptyWrBuffer(pBuffer, bufSize);
			status = ( status ) ? (AT91C_SVCUDP_WR_FAILED | status) : AT91C_SVCUDP_WR_ABORTED;
		}

		return status;
	}
	else {
		status = pBuffer->GetRdBuffer(pBuffer, &pRdData, &bufSize);
		if ( status )
			status = (AT91C_SVCUDP_RD_FAILED | status);

		// Determine how many bytes have been received
		bytesRcv = AT91F_UdpEpNbBytesRcv(pSvcUdp->pUdp, pSvcUdp->epId);

		// An unexpected packet length has been received, STALL it.
		if (bytesRcv > bufSize) {
			AT91F_UdpEpEor(pSvcUdp->pUdp, pSvcUdp->epId, UDP_RCV_DATA_BANK0);
			AT91F_UdpEpStall(pSvcUdp->pUdp, pSvcUdp->epId);
			status = AT91C_SVCUDP_RD_BUFFER_NOT_RDY;
		}
		// Accept the packet
		else {
			// Read the USB DPR
			AT91F_UdpEpRead(pSvcUdp->pUdp, pSvcUdp->epId, pRdData, bytesRcv);
			AT91F_UdpEpEor(pSvcUdp->pUdp, pSvcUdp->epId, UDP_RCV_DATA_BANK0);

			// Update the buffer
			status = pBuffer->FillRdBuffer(pBuffer, bytesRcv);
			if ( status )
				status = (AT91C_SVCUDP_RD_FAILED | status);
		}

		// Notify the call back if the buffer is full


	}
	return status;
}

//*----------------------------------------------------------------------------
//* Function Name       : AT91F_SvcUdpControlHandleTx()
//* Object              : Send or receive a payload with the USB, update the
//*                       linked buffer structure
//* Input Parameters    : AT91PS_SvcComm
//* Output Parameters   : none
//*----------------------------------------------------------------------------
AT91S_SvcCommStatus AT91F_SvcUdpControlHandleTx(AT91PS_SvcUdp pSvcUdp)
{
	AT91PS_SvcComm pService = (AT91PS_SvcComm) &(pSvcUdp->parent);
	AT91PS_Buffer  pBuffer  = (AT91PS_Buffer) pService->pBuffer;
	AT91S_BufferStatus status = AT91C_COMMSVC_SUCCESS;
	char const *pWrData;
	unsigned int bufSize;

	if (pSvcUdp->operation == AT91C_SVCUDP_CTL_RD) {
		// Free the buffer sent and ACKed
		status = pBuffer->EmptyWrBuffer(pBuffer, pSvcUdp->epSize);
		status = ( status ) ? (AT91C_SVCUDP_WR_FAILED | status) : AT91C_SVCUDP_WR_ABORTED;
		// Get how many bytes to send now
		status = pBuffer->GetWrBuffer(pBuffer, &pWrData, &bufSize);
		if (status )
			status = (AT91C_SVCUDP_WR_FAILED | status);
		// If required, send another packet
		if (bufSize) {
			if (pSvcUdp->epSize < bufSize)
				AT91F_UdpEpWrite(pSvcUdp->pUdp, pSvcUdp->epId, pWrData, pSvcUdp->epSize);
			else
				AT91F_UdpEpWrite(pSvcUdp->pUdp, pSvcUdp->epId, pWrData, bufSize);
			// Notify the end of write USB device peripheral
			AT91F_UdpEpEow(pSvcUdp->pUdp, pSvcUdp->epId);
		}
	}

	return status;
}



//*----------------------------------------------------------------------------
//* Function Name       : AT91F_UdpTxReady()
//* Object              : Return the status of the USB
//* Input Parameters    :
//* Output Parameters   : none
//*----------------------------------------------------------------------------
char AT91F_SvcUdpTxReady(AT91PS_SvcComm pService)
{
	AT91PS_SvcUdp pSvcUdp = (AT91PS_SvcUdp) pService->pChild;

	return (AT91F_UdpEpWok (pSvcUdp->pUdp, pSvcUdp->epId));

}

//*----------------------------------------------------------------------------
//* Function Name       : AT91F_UdpRxReady()
//* Object              : Return the status of the USB
//* Input Parameters    :
//* Output Parameters   : none
//*----------------------------------------------------------------------------
char AT91F_SvcUdpRxReady(AT91PS_SvcComm pSvcComm)
{
	AT91PS_SvcUdp pSvcUdp = (AT91PS_SvcUdp) pSvcComm->pChild;
	char status = AT91F_UdpEpRok(pSvcUdp->pUdp, pSvcUdp->epId);

	if ( status == UDP_RCV_DATA_BANK0 )
		pSvcUdp->bank = UDP_RCV_DATA_BANK0;
	else if ( status == UDP_RCV_DATA_BANK1 )
		pSvcUdp->bank = UDP_RCV_DATA_BANK1;
	return status;

}

//*----------------------------------------------------------------------------
//* Function Name       : AT91F_UdpGetError()
//* Object              : Return the read error message
//* Input Parameters    :
//* Output Parameters   :
//*----------------------------------------------------------------------------
#ifdef DBG_DRV_PERIPH
char const *AT91F_SvcUdpGetError(AT91S_SvcCommStatus errorNumber)
{

	switch (errorNumber & AT91C_SERVICE_ERROR)
	case AT91C_SVCUDP_RD_FAILED:         return (UdpErrMsg[1]);
	case AT91C_SVCUDP_RD_BUFFER_NOT_RDY: return (UdpErrMsg[2]);
	case AT91C_SVCUDP_RD_NOT_RDY:        return (UdpErrMsg[3]);
	case AT91C_SVCUDP_WR_FAILED:         return (UdpErrMsg[4]);
	case AT91C_SVCUDP_WR_NOT_RDY:        return (UdpErrMsg[5]);
	case AT91C_SVCUDP_WR_ABORTED:        return (UdpErrMsg[6]);
	default:                             return (UdpErrMsg[7]);
	}
}
#endif

⌨️ 快捷键说明

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