📄 usb.c
字号:
//
if(ulFlags & USB_EP_AUTO_SET)
{
ulRegister |= USB_TXCSRH1_AUTOSET;
}
//
// Configure the DMA mode.
//
if(ulFlags & USB_EP_DMA_MODE_1)
{
ulRegister |= USB_TXCSRH1_DMAEN | USB_TXCSRH1_DMAMOD;
}
else if(ulFlags & USB_EP_DMA_MODE_0)
{
ulRegister |= USB_TXCSRH1_DMAEN;
}
//
// Enable isochronous mode if requested.
//
if((ulFlags & USB_EP_MODE_MASK) == USB_EP_MODE_ISOC)
{
ulRegister |= USB_TXCSRH1_ISO;
}
//
// Write the transmit control value.
//
HWREGB(ulBase + EP_OFFSET(ulEndpoint) + USB_O_TXCSRH1) =
(unsigned char)ulRegister;
//
// Reset the Data toggle to zero.
//
HWREGB(ulBase + EP_OFFSET(ulEndpoint) + USB_O_TXCSRL1) =
USB_TXCSRL1_CLRDT;
}
else
{
//
// Set the MaxPacketSize.
//
HWREGB(ulBase + EP_OFFSET(ulEndpoint) + USB_O_RXMAXP1) =
ulMaxPacketSize;
//
// The receive control value is zero unless options are enabled.
//
ulRegister = 0;
//
// Allow auto clearing of RxPktRdy when packet of size max packet
// has been unloaded from the FIFO.
//
if(ulFlags & USB_EP_AUTO_CLEAR)
{
ulRegister = USB_RXCSRH1_AUTOCL;
}
//
// Configure the DMA mode.
//
if(ulFlags & USB_EP_DMA_MODE_1)
{
ulRegister |= USB_RXCSRH1_DMAEN | USB_RXCSRH1_DMAMOD;
}
else if(ulFlags & USB_EP_DMA_MODE_0)
{
ulRegister |= USB_RXCSRH1_DMAEN;
}
//
// Enable isochronous mode if requested.
//
if(USB_EP_MODE_ISOC & (ulFlags & USB_EP_MODE_MASK))
{
ulRegister |= USB_RXCSRH1_ISO;
}
//
// Write the receive control value.
//
HWREGB(ulBase + EP_OFFSET(ulEndpoint) + USB_O_RXCSRH1) =
(unsigned char)ulRegister;
//
// Reset the Data toggle to zero.
//
HWREGB(ulBase + EP_OFFSET(ulEndpoint) + USB_O_RXCSRL1) =
USB_RXCSRL1_CLRDT;
}
}
//*****************************************************************************
//
//! Sets the FIFO configuration for an endpoint.
//!
//! \param ulBase specifies the USB module base address.
//! \param ulEndpoint is the endpoint to access.
//! \param ulFIFOAddress is the starting address for the FIFO.
//! \param ulFIFOSize is the size of the FIFO in bytes.
//! \param ulFlags specifies what information to set in the FIFO configuration.
//!
//! This function will set the starting FIFO RAM address and size of the FIFO
//! for a given endpoint. Endpoint zero does not have a dynamically
//! configurable FIFO so this function should not be called for endpoint zero.
//! The \e ulFIFOSize parameter should be one of the values in the
//! \b USB_FIFO_SZ_ values. If the endpoint is going to use double buffering
//! it should use the values with the \b _DB at the end of the value. For
//! example, use \b USB_FIFO_SZ_16_DB to configure an endpoint to have a 16
//! byte double buffered FIFO. If a double buffered FIFO is used, then the
//! actual size of the FIFO will be twice the size indicated by the
//! \e ulFIFOSize parameter. This means that the \b USB_FIFO_SZ_16_DB value
//! will use 32 bytes of the USB controller's FIFO memory.
//!
//! The \e ulFIFOAddress value should be a multiple of 8 bytes and directly
//! indicates the starting address in the USB controller's FIFO RAM. For
//! example, a value of 64 indicates that the FIFO should start 64 bytes into
//! the USB controller's FIFO memory. The \e ulFlags value specifies whether
//! the endpoint's OUT or IN FIFO should be configured. If in host mode, use
//! \b USB_EP_HOST_OUT or \b USB_EP_HOST_IN, and if in device mode use
//! \b USB_EP_DEV_OUT or \b USB_EP_DEV_IN.
//!
//! \return None.
//
//*****************************************************************************
void
USBFIFOConfigSet(unsigned long ulBase, unsigned long ulEndpoint,
unsigned long ulFIFOAddress, unsigned long ulFIFOSize,
unsigned long ulFlags)
{
//
// Check the arguments.
//
ASSERT(ulBase == USB0_BASE);
ASSERT((ulEndpoint == USB_EP_1) || (ulEndpoint == USB_EP_2) ||
(ulEndpoint == USB_EP_3));
//
// See if the transmit or receive FIFO is being configured.
//
if(ulFlags & (USB_EP_HOST_OUT | USB_EP_DEV_IN))
{
//
// Set the transmit FIFO location and size for this endpoint.
//
USBIndexWrite(ulBase, ulEndpoint >> 4, USB_O_TXFIFOSZ, ulFIFOSize, 1);
USBIndexWrite(ulBase, ulEndpoint >> 4, USB_O_TXFIFOADD,
ulFIFOAddress >> 3, 2);
}
else
{
//
// Set the receive FIFO location and size for this endpoint.
//
USBIndexWrite(ulBase, ulEndpoint >> 4, USB_O_RXFIFOSZ, ulFIFOSize, 1);
USBIndexWrite(ulBase, ulEndpoint >> 4, USB_O_RXFIFOADD,
ulFIFOAddress >> 3, 2);
}
}
//*****************************************************************************
//
//! Returns the FIFO configuration for an endpoint.
//!
//! \param ulBase specifies the USB module base address.
//! \param ulEndpoint is the endpoint to access.
//! \param pulFIFOAddress is the starting address for the FIFO.
//! \param pulFIFOSize is the size of the FIFO in bytes.
//! \param ulFlags specifies what information to retrieve from the FIFO
//! configuration.
//!
//! This function will return the starting address and size of the FIFO for a
//! given endpoint. Endpoint zero does not have a dynamically configurable
//! FIFO so this function should not be called for endpoint zero. The
//! \e ulFlags parameter specifies whether the endpoint's OUT or IN FIFO should
//! be read. If in host mode, the \e ulFlags parameter should be
//! \b USB_EP_HOST_OUT or \b USB_EP_HOST_IN, and if in device mode the
//! \e ulFlags parameter should be either \b USB_EP_DEV_OUT or
//! \b USB_EP_DEV_IN.
//!
//! \return None.
//
//*****************************************************************************
void
USBFIFOConfigGet(unsigned long ulBase, unsigned long ulEndpoint,
unsigned long *pulFIFOAddress, unsigned long *pulFIFOSize,
unsigned long ulFlags)
{
//
// Check the arguments.
//
ASSERT(ulBase == USB0_BASE);
ASSERT((ulEndpoint == USB_EP_1) || (ulEndpoint == USB_EP_2) ||
(ulEndpoint == USB_EP_3));
//
// See if the transmit or receive FIFO is being configured.
//
if(ulFlags & (USB_EP_HOST_OUT | USB_EP_DEV_IN))
{
//
// Get the transmit FIFO location and size for this endpoint.
//
*pulFIFOAddress = (USBIndexRead(ulBase, ulEndpoint >> 4,
(unsigned long)USB_O_TXFIFOADD,
2)) << 3;
*pulFIFOSize = USBIndexRead(ulBase, ulEndpoint >> 4,
(unsigned long)USB_O_TXFIFOSZ, 1);
}
else
{
//
// Get the receive FIFO location and size for this endpoint.
//
*pulFIFOAddress = (USBIndexRead(ulBase, ulEndpoint >> 4,
(unsigned long)USB_O_RXFIFOADD,
2)) << 3;
*pulFIFOSize = USBIndexRead(ulBase, ulEndpoint >> 4,
(unsigned long)USB_O_RXFIFOSZ, 1);
}
}
//*****************************************************************************
//
//! Retrieves data from the given endpoint's FIFO.
//!
//! \param ulBase specifies the USB module base address.
//! \param ulEndpoint is the endpoint to access.
//! \param pucData is a pointer to the data area used to return the data from
//! the FIFO.
//! \param pulSize is initially the size of the buffer passed into this call
//! via the \e pucData parameter. It will be set to the amount of data
//! returned in the buffer.
//!
//! This function will return the data from the FIFO for the given endpoint.
//! The \e pulSize parameter should indicate the size of the buffer passed in
//! the \e pulData parameter. The data in the \e pulSize parameter will be
//! changed to match the amount of data returned in the \e pucData parameter.
//! If a zero byte packet was received this call will not return a error but
//! will instead just return a zero in the \e pulSize parameter. The only
//! error case occurs when there is no data packet available.
//!
//! \return This call will return 0, or -1 if no packet was received.
//
//*****************************************************************************
long
USBEndpointDataGet(unsigned long ulBase, unsigned long ulEndpoint,
unsigned char *pucData, unsigned long *pulSize)
{
unsigned long ulRegister, ulByteCount, ulFIFO;
//
// Check the arguments.
//
ASSERT(ulBase == USB0_BASE);
ASSERT((ulEndpoint == USB_EP_0) || (ulEndpoint == USB_EP_1) ||
(ulEndpoint == USB_EP_2) || (ulEndpoint == USB_EP_3));
//
// Get the address of the receive status register to use, based on the
// endpoint.
//
if(ulEndpoint == USB_EP_0)
{
ulRegister = USB_O_CSRL0;
}
else
{
ulRegister = USB_O_RXCSRL1 + EP_OFFSET(ulEndpoint);
}
//
// Don't allow reading of data if the RxPktRdy bit is not set.
//
if((HWREGH(ulBase + ulRegister) & USB_CSRL0_RXRDY) == 0)
{
//
// Can't read the data because none is available.
//
*pulSize = 0;
//
// Return a failure since there is no data to read.
//
return(-1);
}
//
// Get the byte count in the FIFO.
//
ulByteCount = HWREGH(ulBase + USB_O_COUNT0 + ulEndpoint);
//
// Make sure that the buffer is large enough.
//
ASSERT(ulByteCount <= *pulSize);
//
// Return the number of bytes loaded into the buffer.
//
*pulSize = ulByteCount;
//
// Calculate the FIFO address.
//
ulFIFO = ulBase + USB_O_FIFO0 + (ulEndpoint >> 2);
//
// Read the data out of the FIFO.
//
for(; ulByteCount > 0; ulByteCount--)
{
//
// Write out a word at a time while we can.
//
*pucData++ = HWREGB(ulFIFO);
}
//
// Success.
//
return(0);
}
//*****************************************************************************
//
//! Acknowledge that data was read from the given endpoint's FIFO in device
//! mode.
//!
//! \param ulBase specifies the USB module base address.
//! \param ulEndpoint is the endpoint to access.
//! \param bIsLastPacket indicates if this is the last packet.
//!
//! This function acknowledges that the data was read from the endpoint's FIFO.
//! The \e bIsLastPacket parameter is set to a \b true value if this is the
//! last in a series of data packets on endpoint zero. The \e bIsLastPacket
//! parameter is not used for endpoints other than endpoint zero. This call
//! can be used if processing is required between reading the data and
//! acknowledging that the data has been read.
//!
//! \note This function should only be called in device mode.
//!
//! \return None.
//
//*****************************************************************************
void
USBDevEndpointDataAck(unsigned long ulBase, unsigned long ulEndpoint,
tBoolean bIsLastPacket)
{
//
// Check the arguments.
//
ASSERT(ulBase == USB0_BASE);
ASSERT((ulEndpoint == USB_EP_0) || (ulEndpoint == USB_EP_1) ||
(ulEndpoint == USB_EP_2) || (ulEndpoint == USB_EP_3));
//
// Determine which endpoint is being acked.
//
if(ulEndpoint == USB_EP_0)
{
//
// Clear RxPktRdy, and optionally DataEnd, on endpoint zero.
//
HWREGB(ulBase + USB_O_CSRL0) =
USB_CSRL0_RXRDYC | (bIsLastPacket ? USB_CSRL0_DATAEND : 0);
}
else
{
//
// Clear RxPktRdy on all other endpoints.
//
HWREGB(ulBase + USB_O_RXCSRL1 + EP_OFFSET(ulEndpoint)) &=
~(USB_RXCSRL1_RXRDY);
}
}
//*****************************************************************************
//
//! Acknowledge that data was read from the given endpoint's FIFO in host
//! mode.
//!
//! \param ulBase specifies the USB module base address.
//! \param ulEndpoint is the endpoint to access.
//!
//! This function acknowledges that the data was read from the e
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -