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