usbps_v2_2: Deprecated v2_1 added new version v2_2

Added new version of usbps driver v2_2

Signed-off-by: Shakti Bhatnagar <shaktib@xilinx.com>
Acked-by: Srikanth Vemula <svemula@xilinx.com>
This commit is contained in:
Shakti Bhatnagar 2014-07-16 15:33:59 +05:30 committed by Jagannadha Sutradharudu Teki
parent 1ecae8852c
commit 41282e2b69
20 changed files with 7246 additions and 0 deletions

View file

@ -0,0 +1,42 @@
###############################################################################
#
# Copyright (C) 2011 - 2014 Xilinx, Inc. All rights reserved.
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# Use of the Software is limited solely to applications:
# (a) running on a Xilinx device, or
# (b) that interact with a Xilinx device through a bus or interconnect.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# XILINX CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
# WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
# OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
#
# Except as contained in this notice, the name of the Xilinx shall not be used
# in advertising or otherwise to promote the sale, use or other dealings in
# this Software without prior written authorization from Xilinx.
#
###############################################################################
OPTION psf_version = 2.1;
BEGIN driver usbps
OPTION supported_peripherals = (ps7_usb);
OPTION driver_state = ACTIVE;
OPTION copyfiles = all;
OPTION VERSION = 2.2;
OPTION NAME = usbps;
END driver

View file

@ -0,0 +1,52 @@
###############################################################################
#
# Copyright (C) 2011 - 2014 Xilinx, Inc. All rights reserved.
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# Use of the Software is limited solely to applications:
# (a) running on a Xilinx device, or
# (b) that interact with a Xilinx device through a bus or interconnect.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# XILINX CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
# WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
# OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
#
# Except as contained in this notice, the name of the Xilinx shall not be used
# in advertising or otherwise to promote the sale, use or other dealings in
# this Software without prior written authorization from Xilinx.
#
###############################################################################
##############################################################################
#
# Modification History
#
# Ver Who Date Changes
# ----- ---- -------- -----------------------------------------------
# 1.00a sdm 11/22/11 Created
#
##############################################################################
#uses "xillib.tcl"
proc generate {drv_handle} {
xdefine_zynq_include_file $drv_handle "xparameters.h" "XUsbPs" "NUM_INSTANCES" "DEVICE_ID" "C_S_AXI_BASEADDR" "C_S_AXI_HIGHADDR"
xdefine_zynq_config_file $drv_handle "xusbps_g.c" "XUsbPs" "DEVICE_ID" "C_S_AXI_BASEADDR"
xdefine_zynq_canonical_xpars $drv_handle "xparameters.h" "XUsbPs" "DEVICE_ID" "C_S_AXI_BASEADDR" "C_S_AXI_HIGHADDR"
}

View file

@ -0,0 +1,20 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
<html>
<head>
<meta http-equiv="Content-Language" content="en-us">
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Driver example applications</title>
<link rel="stylesheet" type="text/css" href="../help.css">
</head>
<body bgcolor="#FFFFFF">
<h1> Example Applications for the driver usbps_v2_1 </h1>
<HR>
<ul>
<li>xusbps_ch9.c <a href="xusbps_ch9.c">(source)</a> </li>
<li>xusbps_ch9_storage.c <a href="xusbps_ch9_storage.c">(source)</a> </li>
<li>xusbps_class_storage.c <a href="xusbps_class_storage.c">(source)</a> </li>
<li>xusbps_intr_example.c <a href="xusbps_intr_example.c">(source)</a> </li>
</ul>
<p><font face="Times New Roman" color="#800000">Copyright <20> 2010-2014 Xilinx, Inc. All rights reserved.</font></p>
</body>
</html>

View file

@ -0,0 +1,641 @@
/******************************************************************************
*
* Copyright (C) 2010 - 2014 Xilinx, Inc. All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* Use of the Software is limited solely to applications:
* (a) running on a Xilinx device, or
* (b) that interact with a Xilinx device through a bus or interconnect.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* XILINX CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
* Except as contained in this notice, the name of the Xilinx shall not be used
* in advertising or otherwise to promote the sale, use or other dealings in
* this Software without prior written authorization from Xilinx.
*
******************************************************************************/
/*****************************************************************************/
/**
* @file xusbps_ch9.c
*
* This file contains the implementation of the chapter 9 code for the example.
*
*<pre>
* MODIFICATION HISTORY:
*
* Ver Who Date Changes
* ----- ---- -------- ---------------------------------------------------------
* 1.00a jz 10/10/10 First release
* 1.04a nm 02/05/13 Fixed CR# 696550.
* Added template code for Vendor request.
* 1.04a nm 03/04/13 Fixed CR# 704022. Implemented TEST_MODE Feature.
* 1.06a kpc 11/11/13 Always use global memory for dma operations
* 2.1 kpc 4/29/14 Align dma buffers to cache line boundary
*</pre>
******************************************************************************/
/***************************** Include Files *********************************/
#include "xparameters.h" /* XPAR parameters */
#include "xusbps.h" /* USB controller driver */
#include "xusbps_hw.h" /* USB controller driver */
#include "xusbps_ch9.h"
#include "xil_printf.h"
#include "xil_cache.h"
/*default class is storage class */
#include "xusbps_class_storage.h"
#include "sleep.h"
/* #define CH9_DEBUG */
#ifdef CH9_DEBUG
#include <stdio.h>
#define printf xil_printf
#endif
/************************** Constant Definitions *****************************/
/**************************** Type Definitions *******************************/
/***************** Macros (Inline Functions) Definitions *********************/
/************************** Function Prototypes ******************************/
static void XUsbPs_StdDevReq(XUsbPs *InstancePtr,
XUsbPs_SetupData *SetupData);
static int XUsbPs_HandleVendorReq(XUsbPs *InstancePtr,
XUsbPs_SetupData *SetupData);
/************************** Variable Definitions *****************************/
static u8 Response ALIGNMENT_CACHELINE;
/*****************************************************************************/
/**
* This function handles a Setup Data packet from the host.
*
* @param InstancePtr is a pointer to XUsbPs instance of the controller.
* @param SetupData is the structure containing the setup request.
*
* @return
* - XST_SUCCESS if the function is successful.
* - XST_FAILURE if an Error occured.
*
* @note None.
*
******************************************************************************/
int XUsbPs_Ch9HandleSetupPacket(XUsbPs *InstancePtr,
XUsbPs_SetupData *SetupData)
{
int Status = XST_SUCCESS;
#ifdef CH9_DEBUG
printf("Handle setup packet\n");
#endif
switch (SetupData->bmRequestType & XUSBPS_REQ_TYPE_MASK) {
case XUSBPS_CMD_STDREQ:
XUsbPs_StdDevReq(InstancePtr, SetupData);
break;
case XUSBPS_CMD_CLASSREQ:
XUsbPs_ClassReq(InstancePtr, SetupData);
break;
case XUSBPS_CMD_VENDREQ:
#ifdef CH9_DEBUG
printf("vendor request %x\n", SetupData->bRequest);
#endif
Status = XUsbPs_HandleVendorReq(InstancePtr, SetupData);
break;
default:
/* Stall on Endpoint 0 */
#ifdef CH9_DEBUG
printf("unknown class req, stall 0 in out\n");
#endif
XUsbPs_EpStall(InstancePtr, 0, XUSBPS_EP_DIRECTION_IN |
XUSBPS_EP_DIRECTION_OUT);
break;
}
return Status;
}
/*****************************************************************************/
/**
* This function handles a standard device request.
*
* @param InstancePtr is a pointer to XUsbPs instance of the controller.
* @param SetupData is a pointer to the data structure containing the
* setup request.
*
* @return None.
*
* @note None.
*
******************************************************************************/
static void XUsbPs_StdDevReq(XUsbPs *InstancePtr,
XUsbPs_SetupData *SetupData)
{
int Status;
int Error = 0;
XUsbPs_Local *UsbLocalPtr;
int ReplyLen;
static u8 Reply[XUSBPS_REQ_REPLY_LEN] ALIGNMENT_CACHELINE;
/* Check that the requested reply length is not bigger than our reply
* buffer. This should never happen...
*/
if (SetupData->wLength > XUSBPS_REQ_REPLY_LEN) {
return;
}
UsbLocalPtr = (XUsbPs_Local *) InstancePtr->UserDataPtr;
#ifdef CH9_DEBUG
printf("std dev req %d\n", SetupData->bRequest);
#endif
switch (SetupData->bRequest) {
case XUSBPS_REQ_GET_STATUS:
switch(SetupData->bmRequestType & XUSBPS_STATUS_MASK) {
case XUSBPS_STATUS_DEVICE:
/* It seems we do not have to worry about zeroing out the rest
* of the reply buffer even though we are only using the first
* two bytes.
*/
*((u16 *) &Reply[0]) = 0x0100; /* Self powered */
break;
case XUSBPS_STATUS_INTERFACE:
*((u16 *) &Reply[0]) = 0x0;
break;
case XUSBPS_STATUS_ENDPOINT:
{
u32 Status;
int EpNum = SetupData->wIndex;
Status = XUsbPs_ReadReg(InstancePtr->Config.BaseAddress,
XUSBPS_EPCRn_OFFSET(EpNum & 0xF));
if(EpNum & 0x80) { /* In EP */
if(Status & XUSBPS_EPCR_TXS_MASK) {
*((u16 *) &Reply[0]) = 0x0100;
}else {
*((u16 *) &Reply[0]) = 0x0000;
}
} else { /* Out EP */
if(Status & XUSBPS_EPCR_RXS_MASK) {
*((u16 *) &Reply[0]) = 0x0100;
}else {
*((u16 *) &Reply[0]) = 0x0000;
}
}
break;
}
default:
;
#ifdef CH9_DEBUG
printf("unknown request for status %x\n", SetupData->bmRequestType);
#endif
}
XUsbPs_EpBufferSend(InstancePtr, 0, Reply, SetupData->wLength);
break;
case XUSBPS_REQ_SET_ADDRESS:
/* With bit 24 set the address value is held in a shadow
* register until the status phase is acked. At which point it
* address value is written into the address register.
*/
XUsbPs_SetDeviceAddress(InstancePtr, SetupData->wValue);
#ifdef CH9_DEBUG
printf("Set address %d\n", SetupData->wValue);
#endif
/* There is no data phase so ack the transaction by sending a
* zero length packet.
*/
XUsbPs_EpBufferSend(InstancePtr, 0, NULL, 0);
break;
case XUSBPS_REQ_GET_INTERFACE:
#ifdef CH9_DEBUG
printf("Get interface %d/%d/%d\n",
SetupData->wIndex, SetupData->wLength,
InstancePtr->CurrentAltSetting);
#endif
Response = (u8)InstancePtr->CurrentAltSetting;
/* Ack the host */
XUsbPs_EpBufferSend(InstancePtr, 0, &Response, 1);
break;
case XUSBPS_REQ_GET_DESCRIPTOR:
#ifdef CH9_DEBUG
printf("Get desc %x/%d\n", (SetupData->wValue >> 8) & 0xff,
SetupData->wLength);
#endif
/* Get descriptor type. */
switch ((SetupData->wValue >> 8) & 0xff) {
case XUSBPS_TYPE_DEVICE_DESC:
case XUSBPS_TYPE_DEVICE_QUALIFIER:
/* Set up the reply buffer with the device descriptor
* data.
*/
ReplyLen = XUsbPs_Ch9SetupDevDescReply(
Reply, XUSBPS_REQ_REPLY_LEN);
ReplyLen = ReplyLen > SetupData->wLength ?
SetupData->wLength : ReplyLen;
if(((SetupData->wValue >> 8) & 0xff) ==
XUSBPS_TYPE_DEVICE_QUALIFIER) {
Reply[0] = (u8)ReplyLen;
Reply[1] = (u8)0x6;
Reply[2] = (u8)0x0;
Reply[3] = (u8)0x2;
Reply[4] = (u8)0xFF;
Reply[5] = (u8)0x00;
Reply[6] = (u8)0x0;
Reply[7] = (u8)0x10;
Reply[8] = (u8)0;
Reply[9] = (u8)0x0;
}
Status = XUsbPs_EpBufferSend(InstancePtr, 0,
Reply, ReplyLen);
if (XST_SUCCESS != Status) {
/* Failure case needs to be handled */
for (;;);
}
break;
case XUSBPS_TYPE_CONFIG_DESC:
/* Set up the reply buffer with the configuration
* descriptor data.
*/
ReplyLen = XUsbPs_Ch9SetupCfgDescReply(
Reply, XUSBPS_REQ_REPLY_LEN);
#ifdef CH9_DEBUG
printf("get config %d/%d\n", ReplyLen, SetupData->wLength);
#endif
ReplyLen = ReplyLen > SetupData->wLength ?
SetupData->wLength : ReplyLen;
Status = XUsbPs_EpBufferSend(InstancePtr, 0,
Reply, ReplyLen);
if (XST_SUCCESS != Status) {
/* Failure case needs to be handled */
for (;;);
}
break;
case XUSBPS_TYPE_STRING_DESC:
/* Set up the reply buffer with the string descriptor
* data.
*/
ReplyLen = XUsbPs_Ch9SetupStrDescReply(
Reply, XUSBPS_REQ_REPLY_LEN,
SetupData->wValue & 0xFF);
ReplyLen = ReplyLen > SetupData->wLength ?
SetupData->wLength : ReplyLen;
Status = XUsbPs_EpBufferSend(InstancePtr, 0,
Reply, ReplyLen);
if (XST_SUCCESS != Status) {
/* Failure case needs to be handled */
for (;;);
}
break;
#ifdef MOUSE_SIMULATION
case XUSBPS_TYPE_HID_DESC:
/* Set up the reply buffer with the HID descriptor
* data.
*/
ReplyLen = XUsbPs_Ch9SetupHidDescReply(
Reply, XUSBPS_REQ_REPLY_LEN);
ReplyLen = ReplyLen > SetupData->wLength ?
SetupData->wLength : ReplyLen;
Status = XUsbPs_EpBufferSend(InstancePtr, 0,
Reply, ReplyLen);
if (XST_SUCCESS != Status) {
/* Failure case needs to be handled */
for (;;);
}
break;
case XUSBPS_TYPE_REPORT_DESC:
/* Set up the reply buffer with the report descriptor
* data.
*/
ReplyLen = XUsbPs_Ch9SetupReportDescReply(
Reply, XUSBPS_REQ_REPLY_LEN);
#ifdef CH9_DEBUG
printf("report desc len %d\n", ReplyLen);
#endif
ReplyLen = ReplyLen > SetupData->wLength ?
SetupData->wLength : ReplyLen;
Status = XUsbPs_EpBufferSend(InstancePtr, 0,
Reply, ReplyLen);
if (XST_SUCCESS != Status) {
/* Failure case needs to be handled */
for (;;);
}
break;
#endif /* MOUSE_SIMULATION */
default:
Error = 1;
break;
}
break;
case XUSBPS_REQ_SET_CONFIGURATION:
/*
* Only allow configuration index 1 as this is the only one we
* have.
*/
if ((SetupData->wValue & 0xff) != 1) {
Error = 1;
break;
}
UsbLocalPtr->CurrentConfig = SetupData->wValue & 0xff;
/* Call the application specific configuration function to
* apply the configuration with the given configuration index.
*/
XUsbPs_SetConfiguration(InstancePtr,
UsbLocalPtr->CurrentConfig);
/* There is no data phase so ack the transaction by sending a
* zero length packet.
*/
XUsbPs_EpBufferSend(InstancePtr, 0, NULL, 0);
break;
case XUSBPS_REQ_GET_CONFIGURATION:
Response = (u8)InstancePtr->CurrentAltSetting;
XUsbPs_EpBufferSend(InstancePtr, 0,
&Response, 1);
break;
case XUSBPS_REQ_CLEAR_FEATURE:
switch(SetupData->bmRequestType & XUSBPS_STATUS_MASK) {
case XUSBPS_STATUS_ENDPOINT:
if(SetupData->wValue == XUSBPS_ENDPOINT_HALT) {
int EpNum = SetupData->wIndex;
if(EpNum & 0x80) { /* In ep */
XUsbPs_ClrBits(InstancePtr,
XUSBPS_EPCRn_OFFSET(EpNum & 0xF),
XUSBPS_EPCR_TXS_MASK);
}else { /* Out ep */
XUsbPs_ClrBits(InstancePtr,
XUSBPS_EPCRn_OFFSET(EpNum),
XUSBPS_EPCR_RXS_MASK);
}
}
/* Ack the host ? */
XUsbPs_EpBufferSend(InstancePtr, 0, NULL, 0);
break;
default:
Error = 1;
break;
}
break;
case XUSBPS_REQ_SET_FEATURE:
switch(SetupData->bmRequestType & XUSBPS_STATUS_MASK) {
case XUSBPS_STATUS_ENDPOINT:
if(SetupData->wValue == XUSBPS_ENDPOINT_HALT) {
int EpNum = SetupData->wIndex;
if(EpNum & 0x80) { /* In ep */
XUsbPs_SetBits(InstancePtr,
XUSBPS_EPCRn_OFFSET(EpNum & 0xF),
XUSBPS_EPCR_TXS_MASK);
}else { /* Out ep */
XUsbPs_SetBits(InstancePtr,
XUSBPS_EPCRn_OFFSET(EpNum),
XUSBPS_EPCR_RXS_MASK);
}
}
/* Ack the host ? */
XUsbPs_EpBufferSend(InstancePtr, 0, NULL, 0);
break;
case XUSBPS_STATUS_DEVICE:
if (SetupData->wValue == XUSBPS_TEST_MODE) {
int TestSel = (SetupData->wIndex >> 8) & 0xFF;
/* Ack the host, the transition must happen
after status stage and < 3ms */
XUsbPs_EpBufferSend(InstancePtr, 0, NULL, 0);
usleep(1000);
switch (TestSel) {
case XUSBPS_TEST_J:
case XUSBPS_TEST_K:
case XUSBPS_TEST_SE0_NAK:
case XUSBPS_TEST_PACKET:
case XUSBPS_TEST_FORCE_ENABLE:
XUsbPs_SetBits(InstancePtr, \
XUSBPS_PORTSCR1_OFFSET, \
TestSel << 16);
break;
default:
/* Unsupported test selector */
break;
}
break;
}
default:
Error = 1;
break;
}
break;
/* For set interface, check the alt setting host wants */
case XUSBPS_REQ_SET_INTERFACE:
#ifdef CH9_DEBUG
printf("set interface %d/%d\n", SetupData->wValue, SetupData->wIndex);
#endif
/* Not supported */
/* XUsbPs_SetInterface(InstancePtr, SetupData->wValue, SetupData->wIndex); */
/* Ack the host after device finishes the operation */
Error = XUsbPs_EpBufferSend(InstancePtr, 0, NULL, 0);
if(Error) {
#ifdef CH9_DEBUG
printf("EpBufferSend failed %d\n", Error);
#endif
}
break;
default:
Error = 1;
break;
}
/* Set the send stall bit if there was an error */
if (Error) {
#ifdef CH9_DEBUG
printf("std dev req %d/%d error, stall 0 in out\n",
SetupData->bRequest, (SetupData->wValue >> 8) & 0xff);
#endif
XUsbPs_EpStall(InstancePtr, 0, XUSBPS_EP_DIRECTION_IN |
XUSBPS_EP_DIRECTION_OUT);
}
}
/*****************************************************************************/
/**
* This function handles a vendor request.
*
* @param InstancePtr is a pointer to XUsbPs instance of the controller.
* @param SetupData is a pointer to the data structure containing the
* setup request.
*
* @return
* - XST_SUCCESS if successful.
* - XST_FAILURE if an Error occured.
*
* @note
* This function is a template to handle vendor request for control
* IN and control OUT endpoints. The control OUT endpoint can
* receive only 64 bytes of data per dTD. For receiving more than
* 64 bytes of vendor data on control OUT endpoint, change the
* buffer size of the control OUT endpoint. Otherwise the results
* are unexpected.
*
******************************************************************************/
static int XUsbPs_HandleVendorReq(XUsbPs *InstancePtr,
XUsbPs_SetupData *SetupData)
{
u8 *BufferPtr;
u32 BufferLen;
u32 Handle;
u32 Reg;
const static u8 Reply[8] ALIGNMENT_CACHELINE =
{0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17};
u8 EpNum = 0;
int Status;
int Direction;
int Timeout;
/* Check the direction, USB 2.0 section 9.3 */
Direction = SetupData->bmRequestType & (1 << 7);
if (!Direction) {
/* Control OUT vendor request */
if (SetupData->wLength > 0) {
/* Re-Prime the endpoint to receive Setup DATA */
XUsbPs_EpPrime(InstancePtr, 0, XUSBPS_EP_DIRECTION_OUT);
/* Check whether EP prime is successful or not */
Timeout = XUSBPS_TIMEOUT_COUNTER;
do {
Reg = XUsbPs_ReadReg(InstancePtr->Config.BaseAddress,
XUSBPS_EPPRIME_OFFSET);
} while(((Reg & (1 << EpNum)) == 1) && --Timeout);
if (!Timeout) {
return XST_FAILURE;
}
/* Get the Setup DATA, don't wait for the interrupt */
Timeout = XUSBPS_TIMEOUT_COUNTER;
do {
Status = XUsbPs_EpBufferReceive(InstancePtr,
EpNum, &BufferPtr, &BufferLen, &Handle);
} while((Status != XST_SUCCESS) && --Timeout);
if (!Timeout) {
return XST_FAILURE;
}
Xil_DCacheInvalidateRange((unsigned int)BufferPtr,
BufferLen);
#ifdef CH9_DEBUG
int Len;
xil_printf("Vendor data:\r\n");
for(Len = 0;Len < BufferLen;Len++)
xil_printf("%02x ",BufferPtr[Len]);
#endif
if (Status == XST_SUCCESS) {
/* Zero length ACK */
Status = XUsbPs_EpBufferSend(InstancePtr, EpNum,
NULL, 0);
if (Status != XST_SUCCESS) {
return XST_FAILURE;
}
}
}
} else {
if (SetupData->wLength > 0) {
/* Control IN vendor request */
Status = XUsbPs_EpBufferSend(InstancePtr, EpNum, Reply,
SetupData->wLength);
if (Status != XST_SUCCESS) {
return XST_FAILURE;
}
}
}
return XST_SUCCESS;
}

View file

@ -0,0 +1,199 @@
/******************************************************************************
*
* Copyright (C) 2010 - 2014 Xilinx, Inc. All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* Use of the Software is limited solely to applications:
* (a) running on a Xilinx device, or
* (b) that interact with a Xilinx device through a bus or interconnect.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* XILINX CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
* Except as contained in this notice, the name of the Xilinx shall not be used
* in advertising or otherwise to promote the sale, use or other dealings in
* this Software without prior written authorization from Xilinx.
*
******************************************************************************/
/*****************************************************************************/
/**
*
* @file xusbps_ch9.h
*
* This file contains definitions used in the chapter 9 code.
*
*
* <pre>
* MODIFICATION HISTORY:
*
* Ver Who Date Changes
* ----- ---- -------- -------------------------------------------------------
* 1.00a wgr 10/10/10 First release
* 1.04a nm 03/04/13 Fixed CR# 704022. Implemented TEST_MODE Feature.
* 2.1 kpc 04/28/14 Added macros secific to cache operations
* </pre>
*
******************************************************************************/
#ifndef XUSBPS_CH9_H
#define XUSBPS_CH9_H
#ifdef __cplusplus
extern "C" {
#endif
/***************************** Include Files *********************************/
#include "xusbps_hw.h"
#include "xil_types.h"
#include "xstatus.h"
/************************** Constant Definitions *****************************/
/*
* Simulation type switch, default type is storage.
*/
/**
* @name Request types
* @{
*/
#define XUSBPS_REQ_TYPE_MASK 0x60 /**< Mask for request opcode */
#define XUSBPS_CMD_STDREQ 0x00 /**< */
#define XUSBPS_CMD_CLASSREQ 0x20 /**< */
#define XUSBPS_CMD_VENDREQ 0x40 /**< */
#define XUSBPS_REQ_REPLY_LEN 1024 /**< Max size of reply buffer. */
/* @} */
/**
* @name Request Values
* @{
*/
#define XUSBPS_REQ_GET_STATUS 0x00
#define XUSBPS_REQ_CLEAR_FEATURE 0x01
#define XUSBPS_REQ_SET_FEATURE 0x03
#define XUSBPS_REQ_SET_ADDRESS 0x05
#define XUSBPS_REQ_GET_DESCRIPTOR 0x06
#define XUSBPS_REQ_SET_DESCRIPTOR 0x07
#define XUSBPS_REQ_GET_CONFIGURATION 0x08
#define XUSBPS_REQ_SET_CONFIGURATION 0x09
#define XUSBPS_REQ_GET_INTERFACE 0x0a
#define XUSBPS_REQ_SET_INTERFACE 0x0b
#define XUSBPS_REQ_SYNC_FRAME 0x0c
/* @} */
/**
* @name Feature Selectors
* @{
*/
#define XUSBPS_ENDPOINT_HALT 0x00
#define XUSBPS_DEVICE_REMOTE_WAKEUP 0x01
#define XUSBPS_TEST_MODE 0x02
/* @} */
/**
* @name Descriptor Types
* @{
*/
#define XUSBPS_TYPE_DEVICE_DESC 0x01
#define XUSBPS_TYPE_CONFIG_DESC 0x02
#define XUSBPS_TYPE_STRING_DESC 0x03
#define XUSBPS_TYPE_IF_CFG_DESC 0x04
#define XUSBPS_TYPE_ENDPOINT_CFG_DESC 0x05
#define XUSBPS_TYPE_DEVICE_QUALIFIER 0x06
#define XUSBPS_TYPE_HID_DESC 0x21
#define XUSBPS_TYPE_REPORT_DESC 0x22
/* @} */
/**
* @name USB Device States
* @{
*/
#define XUSBPS_DEVICE_ATTACHED 0x00
#define XUSBPS_DEVICE_POWERED 0x01
#define XUSBPS_DEVICE_DEFAULT 0x02
#define XUSBPS_DEVICE_ADDRESSED 0x03
#define XUSBPS_DEVICE_CONFIGURED 0x04
#define XUSBPS_DEVICE_SUSPENDED 0x05
/* @} */
/**
* @name Status type
* @{
*/
#define XUSBPS_STATUS_MASK 0x3
#define XUSBPS_STATUS_DEVICE 0x0
#define XUSBPS_STATUS_INTERFACE 0x1
#define XUSBPS_STATUS_ENDPOINT 0x2
/* @} */
/**
* @name EP Types
* @{
*/
#define XUSBPS_EP_CONTROL 0
#define XUSBPS_EP_ISOCHRONOUS 1
#define XUSBPS_EP_BULK 2
#define XUSBPS_EP_INTERRUPT 3
/* @} */
/**
* @name Device Classes
* @{
*/
#define XUSBPS_CLASS_HID 0x03
#define XUSBPS_CLASS_STORAGE 0x08
#define XUSBPS_CLASS_VENDOR 0xFF
/* @} */
/**
* @name Test Mode Selectors
* @{
*/
#define XUSBPS_TEST_J 0x01
#define XUSBPS_TEST_K 0x02
#define XUSBPS_TEST_SE0_NAK 0x03
#define XUSBPS_TEST_PACKET 0x04
#define XUSBPS_TEST_FORCE_ENABLE 0x05
/* @} */
/**************************** Type Definitions *******************************/
typedef struct {
u8 CurrentConfig; /* Configuration used by Ch9 code. */
} XUsbPs_Local;
/***************** Macros (Inline Functions) Definitions *********************/
#define ALIGNMENT_CACHELINE __attribute__ ((aligned (32)))
#define DCACHE_INVALIDATE_SIZE(a) ((a) % 32) ? ((((a) / 32) * 32) + 32) : (a)
/************************** Function Prototypes ******************************/
int XUsbPs_Ch9HandleSetupPacket(XUsbPs *InstancePtr,
XUsbPs_SetupData *SetupData);
#ifdef __cplusplus
}
#endif
#endif /* XUSBPS_CH9_H */

View file

@ -0,0 +1,368 @@
/******************************************************************************
*
* Copyright (C) 2010 - 2014 Xilinx, Inc. All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* Use of the Software is limited solely to applications:
* (a) running on a Xilinx device, or
* (b) that interact with a Xilinx device through a bus or interconnect.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* XILINX CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
* Except as contained in this notice, the name of the Xilinx shall not be used
* in advertising or otherwise to promote the sale, use or other dealings in
* this Software without prior written authorization from Xilinx.
*
******************************************************************************/
/*****************************************************************************/
/**
* @file xusbps_ch9_storage.c
*
* This file contains the implementation of the storage specific chapter 9 code
* for the example.
*
*<pre>
* MODIFICATION HISTORY:
*
* Ver Who Date Changes
* ----- ---- -------- ---------------------------------------------------------
* 1.00a wgr 10/10/10 First release
*</pre>
******************************************************************************/
/***************************** Include Files *********************************/
#include <string.h>
#include "xparameters.h" /* XPAR parameters */
#include "xusbps.h" /* USB controller driver */
#include "xusbps_ch9.h"
#include "xusbps_ch9_storage.h"
/************************** Constant Definitions *****************************/
/***************** Macros (Inline Functions) Definitions *********************/
/**************************** Type Definitions *******************************/
typedef struct {
u8 bLength;
u8 bDescriptorType;
u16 bcdUSB;
u8 bDeviceClass;
u8 bDeviceSubClass;
u8 bDeviceProtocol;
u8 bMaxPacketSize0;
u16 idVendor;
u16 idProduct;
u16 bcdDevice;
u8 iManufacturer;
u8 iProduct;
u8 iSerialNumber;
u8 bNumConfigurations;
}__attribute__((__packed__))USB_STD_DEV_DESC;
typedef struct {
u8 bLength;
u8 bDescriptorType;
u16 wTotalLength;
u8 bNumInterfaces;
u8 bConfigurationValue;
u8 iConfiguration;
u8 bmAttributes;
u8 bMaxPower;
}__attribute__((__packed__))USB_STD_CFG_DESC;
typedef struct {
u8 bLength;
u8 bDescriptorType;
u8 bInterfaceNumber;
u8 bAlternateSetting;
u8 bNumEndPoints;
u8 bInterfaceClass;
u8 bInterfaceSubClass;
u8 bInterfaceProtocol;
u8 iInterface;
}__attribute__((__packed__))USB_STD_IF_DESC;
typedef struct {
u8 bLength;
u8 bDescriptorType;
u8 bEndpointAddress;
u8 bmAttributes;
u16 wMaxPacketSize;
u8 bInterval;
}__attribute__((__packed__))USB_STD_EP_DESC;
typedef struct {
u8 bLength;
u8 bDescriptorType;
u16 wLANGID[1];
}__attribute__((__packed__))USB_STD_STRING_DESC;
typedef struct {
USB_STD_CFG_DESC stdCfg;
USB_STD_IF_DESC ifCfg;
USB_STD_EP_DESC epCfg1;
USB_STD_EP_DESC epCfg2;
}__attribute__((__packed__))USB_CONFIG;
/************************** Function Prototypes ******************************/
/************************** Variable Definitions *****************************/
#define USB_ENDPOINT0_MAXP 0x40
#define USB_BULKIN_EP 1
#define USB_BULKOUT_EP 1
#define USB_DEVICE_DESC 0x01
#define USB_CONFIG_DESC 0x02
#define USB_STRING_DESC 0x03
#define USB_INTERFACE_CFG_DESC 0x04
#define USB_ENDPOINT_CFG_DESC 0x05
/*****************************************************************************/
/**
*
* This function returns the device descriptor for the device.
*
* @param BufPtr is pointer to the buffer that is to be filled
* with the descriptor.
* @param BufLen is the size of the provided buffer.
*
* @return Length of the descriptor in the buffer on success.
* 0 on error.
*
******************************************************************************/
u32 XUsbPs_Ch9SetupDevDescReply(u8 *BufPtr, u32 BufLen)
{
USB_STD_DEV_DESC deviceDesc = {
sizeof(USB_STD_DEV_DESC), /* bLength */
USB_DEVICE_DESC, /* bDescriptorType */
be2les(0x0200), /* bcdUSB 2.0 */
0x00, /* bDeviceClass */
0x00, /* bDeviceSubClass */
0x00, /* bDeviceProtocol */
USB_ENDPOINT0_MAXP, /* bMaxPackedSize0 */
be2les(0x0d7d), /* idVendor */
be2les(0x0100), /* idProduct */
be2les(0x0100), /* bcdDevice */
0x01, /* iManufacturer */
0x02, /* iProduct */
0x03, /* iSerialNumber */
0x01 /* bNumConfigurations */
};
/* Check buffer pointer is there and buffer is big enough. */
if (!BufPtr) {
return 0;
}
if (BufLen < sizeof(USB_STD_DEV_DESC)) {
return 0;
}
memcpy(BufPtr, &deviceDesc, sizeof(USB_STD_DEV_DESC));
return sizeof(USB_STD_DEV_DESC);
}
/*****************************************************************************/
/**
*
* This function returns the configuration descriptor for the device.
*
* @param BufPtr is the pointer to the buffer that is to be filled with
* the descriptor.
* @param BufLen is the size of the provided buffer.
*
* @return Length of the descriptor in the buffer on success.
* 0 on error.
*
******************************************************************************/
u32 XUsbPs_Ch9SetupCfgDescReply(u8 *BufPtr, u32 BufLen)
{
USB_CONFIG config = {
/* Std Config */
{sizeof(USB_STD_CFG_DESC), /* bLength */
USB_CONFIG_DESC, /* bDescriptorType */
be2les(sizeof(USB_CONFIG)), /* wTotalLength */
0x01, /* bNumInterfaces */
0x01, /* bConfigurationValue */
0x04, /* iConfiguration */
0xc0, /* bmAttribute */
0x00}, /* bMaxPower */
/* Interface Config */
{sizeof(USB_STD_IF_DESC), /* bLength */
USB_INTERFACE_CFG_DESC, /* bDescriptorType */
0x00, /* bInterfaceNumber */
0x00, /* bAlternateSetting */
0x02, /* bNumEndPoints */
0x08, /* bInterfaceClass */
0x06, /* bInterfaceSubClass */
0x50, /* bInterfaceProtocol */
0x05}, /* iInterface */
/* Bulk Out Endpoint Config */
{sizeof(USB_STD_EP_DESC), /* bLength */
USB_ENDPOINT_CFG_DESC, /* bDescriptorType */
0x00 | USB_BULKOUT_EP, /* bEndpointAddress */
0x02, /* bmAttribute */
be2les(0x200), /* wMaxPacketSize */
0x00}, /* bInterval */
/* Bulk In Endpoint Config */
{sizeof(USB_STD_EP_DESC), /* bLength */
USB_ENDPOINT_CFG_DESC, /* bDescriptorType */
0x80 | USB_BULKIN_EP, /* bEndpointAddress */
0x02, /* bmAttribute */
be2les(0x200), /* wMaxPacketSize */
0x00} /* bInterval */
};
/* Check buffer pointer is OK and buffer is big enough. */
if (!BufPtr) {
return 0;
}
if (BufLen < sizeof(USB_STD_DEV_DESC)) {
return 0;
}
memcpy(BufPtr, &config, sizeof(USB_CONFIG));
return sizeof(USB_CONFIG);
}
/*****************************************************************************/
/**
*
* This function returns a string descriptor for the given index.
*
* @param BufPtr is a pointer to the buffer that is to be filled with
* the descriptor.
* @param BufLen is the size of the provided buffer.
* @param Index is the index of the string for which the descriptor
* is requested.
*
* @return Length of the descriptor in the buffer on success.
* 0 on error.
*
******************************************************************************/
u32 XUsbPs_Ch9SetupStrDescReply(u8 *BufPtr, u32 BufLen, u8 Index)
{
int i;
static char *StringList[] = {
"UNUSED",
"Xilinx",
"EPB USB Flash Drive Disk Emulation",
"2A49876D9CC1AA4",
"Default Configuration",
"Default Interface",
};
char *String;
u32 StringLen;
u32 DescLen;
u8 TmpBuf[128];
USB_STD_STRING_DESC *StringDesc;
if (!BufPtr) {
return 0;
}
if (Index >= sizeof(StringList) / sizeof(char *)) {
return 0;
}
String = StringList[Index];
StringLen = strlen(String);
StringDesc = (USB_STD_STRING_DESC *) TmpBuf;
/* Index 0 is special as we can not represent the string required in
* the table above. Therefore we handle index 0 as a special case.
*/
if (0 == Index) {
StringDesc->bLength = 4;
StringDesc->bDescriptorType = USB_STRING_DESC;
StringDesc->wLANGID[0] = be2les(0x0409);
}
/* All other strings can be pulled from the table above. */
else {
StringDesc->bLength = StringLen * 2 + 2;
StringDesc->bDescriptorType = USB_STRING_DESC;
for (i = 0; i < StringLen; i++) {
StringDesc->wLANGID[i] = be2les((u16) String[i]);
}
}
DescLen = StringDesc->bLength;
/* Check if the provided buffer is big enough to hold the descriptor. */
if (DescLen > BufLen) {
return 0;
}
memcpy(BufPtr, StringDesc, DescLen);
return DescLen;
}
/*****************************************************************************/
/**
* This function handles a "set configuration" request.
*
* @param InstancePtr is a pointer to XUsbPs instance of the controller.
* @param ConfigIdx is the Index of the desired configuration.
*
* @return None
*
******************************************************************************/
void XUsbPs_SetConfiguration(XUsbPs *InstancePtr, int ConfigIdx)
{
Xil_AssertVoid(InstancePtr != NULL);
/* We only have one configuration. Its index is 1. Ignore anything
* else.
*/
if (1 != ConfigIdx) {
return;
}
XUsbPs_EpEnable(InstancePtr, 1, XUSBPS_EP_DIRECTION_OUT);
XUsbPs_EpEnable(InstancePtr, 1, XUSBPS_EP_DIRECTION_IN);
/* Set BULK mode for both directions. */
XUsbPs_SetBits(InstancePtr, XUSBPS_EPCR1_OFFSET,
XUSBPS_EPCR_TXT_BULK_MASK |
XUSBPS_EPCR_RXT_BULK_MASK |
XUSBPS_EPCR_TXR_MASK |
XUSBPS_EPCR_RXR_MASK);
/* Prime the OUT endpoint. */
XUsbPs_EpPrime(InstancePtr, 1, XUSBPS_EP_DIRECTION_OUT);
}

View file

@ -0,0 +1,90 @@
/******************************************************************************
*
* Copyright (C) 2010 - 2014 Xilinx, Inc. All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* Use of the Software is limited solely to applications:
* (a) running on a Xilinx device, or
* (b) that interact with a Xilinx device through a bus or interconnect.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* XILINX CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
* Except as contained in this notice, the name of the Xilinx shall not be used
* in advertising or otherwise to promote the sale, use or other dealings in
* this Software without prior written authorization from Xilinx.
*
******************************************************************************/
/*****************************************************************************/
/**
*
* @file xusbps_ch9_storage.h
*
* This file contains definitions used in the chapter 9 code.
*
*
* <pre>
* MODIFICATION HISTORY:
*
* Ver Who Date Changes
* ----- ---- -------- -------------------------------------------------------
* 1.00a wgr 10/10/10 First release
* </pre>
*
******************************************************************************/
#ifndef XUSBPS_CH9_STORAGE_H
#define XUSBPS_CH9_STORAGE_H
#ifdef __cplusplus
extern "C" {
#endif
/***************************** Include Files *********************************/
#include "xusbps_hw.h"
#include "xil_types.h"
#include "xstatus.h"
/************************** Constant Definitions *****************************/
/**************************** Type Definitions *******************************/
/***************** Macros (Inline Functions) Definitions *********************/
/* Check where these defines need to go */
#define be2le(val) (u32)(val)
#define be2les(x) (u16) (x)
#define htonl(val) ((((u32)(val) & 0x000000FF)<<24) | \
(((u32)(val) & 0x0000FF00)<<8) | \
(((u32)(val) & 0x00FF0000)>>8) | \
(((u32)(val) & 0xFF000000)>>24))
#define htons(x) (u16) ((((u16)(x))<<8) | (((u16)(x))>>8))
/************************** Function Prototypes ******************************/
u32 XUsbPs_Ch9SetupDevDescReply(u8 *BufPtr, u32 BufLen);
u32 XUsbPs_Ch9SetupCfgDescReply(u8 *BufPtr, u32 BufLen);
u32 XUsbPs_Ch9SetupStrDescReply(u8 *BufPtr, u32 BufLen, u8 Index);
void XUsbPs_SetConfiguration(XUsbPs *InstancePtr, int ConfigIdx);
#ifdef __cplusplus
}
#endif
#endif /* XUSBPS_CH9_STORAGE_H */

View file

@ -0,0 +1,362 @@
/******************************************************************************
*
* Copyright (C) 2010 - 2014 Xilinx, Inc. All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* Use of the Software is limited solely to applications:
* (a) running on a Xilinx device, or
* (b) that interact with a Xilinx device through a bus or interconnect.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* XILINX CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
* Except as contained in this notice, the name of the Xilinx shall not be used
* in advertising or otherwise to promote the sale, use or other dealings in
* this Software without prior written authorization from Xilinx.
*
******************************************************************************/
/*****************************************************************************/
/**
* @file xusbps_class_storage.c
*
* This file contains the implementation of the storage class code for the
* example.
*
*<pre>
* MODIFICATION HISTORY:
*
* Ver Who Date Changes
* ----- ---- -------- ---------------------------------------------------------
* 1.00a wgr 10/10/10 First release
* 2.1 kpc 4/28/14 Align DMA buffers to cache line boundary
*</pre>
******************************************************************************/
/***************************** Include Files *********************************/
#include <string.h>
#include "xusbps.h" /* USB controller driver */
#include "xusbps_ch9_storage.h"
#include "xusbps_ch9.h"
#include "xusbps_class_storage.h"
#include "xil_printf.h"
/* #define CLASS_STORAGE_DEBUG */
#ifdef CLASS_STORAGE_DEBUG
#define printf xil_printf
#endif
/************************** Constant Definitions *****************************/
/************************** Function Prototypes ******************************/
/************************** Variable Definitions *****************************/
/* Pre-manufactured response to the SCSI Inquirey command.
*/
const static SCSI_INQUIRY scsiInquiry ALIGNMENT_CACHELINE = {
0x00,
0x80,
0x00,
0x01,
0x1f,
0x00,
0x00,
0x00,
{"Xilinx "}, /* Vendor ID: must be 8 characters long. */
{"PS USB VirtDisk"}, /* Product ID: must be 16 characters long. */
{"1.00"} /* Revision: must be 4 characters long. */
};
static u8 MaxLUN ALIGNMENT_CACHELINE = 0;
/* Buffer for virtual flash disk space. */
static u8 VirtFlash[VFLASH_SIZE] ALIGNMENT_CACHELINE;
static USB_CBW lastCBW ALIGNMENT_CACHELINE;
/* Local transmit buffer for simple replies. */
static u8 txBuffer[128] ALIGNMENT_CACHELINE;
/*****************************************************************************/
/**
* This function handles Reduced Block Command (RBC) requests from the host.
*
* @param InstancePtr is a pointer to XUsbPs instance of the controller.
* @param EpNum is the number of the endpoint on which the RBC was received.
* @param BufferPtr is the data buffer containing the RBC or data.
* @param BufferLen is the length of the data buffer.
*
* @return None.
*
* @note None.
*
******************************************************************************/
void XUsbPs_HandleStorageReq(XUsbPs *InstancePtr, u8 EpNum,
u8 *BufferPtr, u32 BufferLen)
{
USB_CBW *CBW;
u32 Offset;
static u8 *VirtFlashWritePointer = VirtFlash;
/* Static variables used for data transfers.*/
static int rxBytesLeft;
/* Current SCSI machine state. */
static int phase = USB_EP_STATE_COMMAND;
/* COMMAND phase. */
if (USB_EP_STATE_COMMAND == phase) {
CBW = (USB_CBW *) BufferPtr;
switch (CBW->CBWCB[0]) {
case USB_RBC_INQUIRY:
#ifdef CLASS_STORAGE_DEBUG
printf("SCSI: INQUIRY\n");
#endif
XUsbPs_EpBufferSend(InstancePtr, 1,
(void *) &scsiInquiry,
sizeof(scsiInquiry));
/* Send Success Status */
CBW->dCBWSignature = 0x55534253;
CBW->dCBWDataTransferLength = 0;
CBW->bmCBWFlags = 0;
XUsbPs_EpBufferSend(InstancePtr, 1, (void *) CBW, 13);
break;
case USB_UFI_GET_CAP_LIST:
{
SCSI_CAP_LIST *CapList;
CapList = (SCSI_CAP_LIST *) txBuffer;
#ifdef CLASS_STORAGE_DEBUG
printf("SCSI: CAPLIST\n");
#endif
CapList->listLength = 8;
CapList->descCode = 3;
CapList->numBlocks = htonl(VFLASH_NUM_BLOCKS);
CapList->blockLength = htons(VFLASH_BLOCK_SIZE);
XUsbPs_EpBufferSend(InstancePtr, 1, txBuffer,
sizeof(SCSI_CAP_LIST));
/* Send Success Status
*/
CBW->dCBWSignature = 0x55534253;
CBW->dCBWDataTransferLength =
be2le(be2le(CBW->dCBWDataTransferLength) -
sizeof(SCSI_CAP_LIST));
CBW->bmCBWFlags = 0;
XUsbPs_EpBufferSend(InstancePtr, 1, (u8 *) CBW, 13);
break;
}
case USB_RBC_READ_CAP:
{
SCSI_READ_CAPACITY *Cap;
Cap = (SCSI_READ_CAPACITY *) txBuffer;
#ifdef CLASS_STORAGE_DEBUG
printf("SCSI: READCAP\n");
#endif
Cap->numBlocks = htonl(VFLASH_NUM_BLOCKS - 1);
Cap->blockSize = htonl(VFLASH_BLOCK_SIZE);
XUsbPs_EpBufferSend(InstancePtr, 1, txBuffer,
sizeof(SCSI_READ_CAPACITY));
/* Send Success Status */
CBW->dCBWSignature = 0x55534253;
CBW->dCBWDataTransferLength = 0;
CBW->bmCBWFlags = 0;
XUsbPs_EpBufferSend(InstancePtr, 1, (u8 *) CBW, 13);
break;
}
case USB_RBC_READ:
Offset = htonl(((SCSI_READ_WRITE *) CBW->CBWCB)->
block) * VFLASH_BLOCK_SIZE;
#ifdef CLASS_STORAGE_DEBUG
printf("SCSI: READ Offset 0x%08x\n", (int) Offset);
#endif
XUsbPs_EpBufferSend(InstancePtr, 1, &VirtFlash[Offset],
htons(((SCSI_READ_WRITE *) CBW->CBWCB)->
length) * VFLASH_BLOCK_SIZE);
/* Send Success Status */
CBW->dCBWSignature = 0x55534253;
CBW->dCBWDataTransferLength = 0;
CBW->bmCBWFlags = 0;
XUsbPs_EpBufferSend(InstancePtr, 1, (u8 *) CBW, 13);
break;
case USB_RBC_MODE_SENSE:
#ifdef CLASS_STORAGE_DEBUG
printf("SCSI: MODE SENSE\n");
#endif
XUsbPs_EpBufferSend(InstancePtr, 1,
(u8 *) "\003\000\000\000", 4);
/* Send Success Status */
CBW->dCBWSignature = 0x55534253;
CBW->dCBWDataTransferLength =
be2le(be2le(CBW->dCBWDataTransferLength) - 4);
CBW->bmCBWFlags = 0;
XUsbPs_EpBufferSend(InstancePtr, 1, (u8 *) CBW, 13);
break;
case USB_RBC_TEST_UNIT_READY:
case USB_RBC_MEDIUM_REMOVAL:
case USB_RBC_VERIFY:
#ifdef CLASS_STORAGE_DEBUG
printf("SCSI: TEST UNIT READY\n");
#endif
/* Send Success Status */
CBW->dCBWSignature = 0x55534253;
CBW->dCBWDataTransferLength = 0;
CBW->bmCBWFlags = 0;
XUsbPs_EpBufferSend(InstancePtr, 1, (u8 *) CBW, 13);
break;
case USB_RBC_WRITE:
Offset = htonl(((SCSI_READ_WRITE *) CBW->CBWCB)->
block) * VFLASH_BLOCK_SIZE;
#ifdef CLASS_STORAGE_DEBUG
printf("SCSI: WRITE Offset 0x%08x\n", (int) Offset);
#endif
VirtFlashWritePointer = &VirtFlash[Offset];
/* Save the CBW for the DATA and STATUS phases. */
lastCBW = *CBW;
rxBytesLeft =
htons(((SCSI_READ_WRITE *) CBW->CBWCB)->length)
* VFLASH_BLOCK_SIZE;
phase = USB_EP_STATE_DATA;
break;
case USB_RBC_STARTSTOP_UNIT:
{
u8 immed;
immed = ((SCSI_START_STOP *) CBW->CBWCB)->immed;
#ifdef CLASS_STORAGE_DEBUG
printf("SCSI: START/STOP unit: immed %02x\n", immed);
#endif
/* If the immediate bit is 0 we are supposed to send
* a success status.
*/
if (0 == (immed & 0x01)) {
/* Send Success Status */
CBW->dCBWSignature = 0x55534253;
CBW->dCBWDataTransferLength = 0;
CBW->bmCBWFlags = 0;
XUsbPs_EpBufferSend(InstancePtr, 1,
(u8 *) CBW, 13);
}
break;
}
/* Commands that we do not support for this example. */
case 0x04: /* Format Unit */
case 0x15: /* Mode Select */
case 0x5e: /* Persistent Reserve In */
case 0x5f: /* Persistent Reserve Out */
case 0x17: /* Release */
case 0x03: /* Request Sense */
case 0x16: /* Reserve */
case 0x35: /* Sync Cache */
case 0x3b: /* Write Buffer */
#ifdef CLASS_STORAGE_DEBUG
printf("SCSI: Got unhandled command %02x\n", CBW->CBWCB[0]);
#endif
default:
break;
}
}
/* DATA phase.
*/
else if (USB_EP_STATE_DATA == phase) {
switch (lastCBW.CBWCB[0]) {
case USB_RBC_WRITE:
/* Copy the data we just read into the VirtFlash buffer. */
memcpy(VirtFlashWritePointer, BufferPtr, BufferLen);
VirtFlashWritePointer += BufferLen;
rxBytesLeft -= BufferLen;
if (rxBytesLeft <= 0) {
/* Send Success Status */
lastCBW.dCBWSignature = 0x55534253;
lastCBW.dCBWDataTransferLength = 0;
lastCBW.bmCBWFlags = 0;
XUsbPs_EpBufferSend(InstancePtr, 1,
(void *) &lastCBW, 13);
phase = USB_EP_STATE_COMMAND;
}
break;
}
}
}
/*****************************************************************************/
/**
* This function handles a Storage Class Setup request from the host.
*
* @param InstancePtr is a pointer to XUsbPs instance of the controller.
* @param SetupData is the setup data structure containing the setup
* request.
*
* @return None.
*
* @note None.
*
******************************************************************************/
void XUsbPs_ClassReq(XUsbPs *InstancePtr, XUsbPs_SetupData *SetupData)
{
Xil_AssertVoid(InstancePtr != NULL);
Xil_AssertVoid(SetupData != NULL);
switch (SetupData->bRequest) {
case XUSBPS_CLASSREQ_MASS_STORAGE_RESET:
XUsbPs_EpBufferSend(InstancePtr, 0, NULL, 0);
break;
case XUSBPS_CLASSREQ_GET_MAX_LUN:
XUsbPs_EpBufferSend(InstancePtr, 0, &MaxLUN, 1);
break;
default:
XUsbPs_EpStall(InstancePtr, 0, XUSBPS_EP_DIRECTION_IN);
break;
}
}

View file

@ -0,0 +1,174 @@
/******************************************************************************
*
* Copyright (C) 2010 - 2014 Xilinx, Inc. All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* Use of the Software is limited solely to applications:
* (a) running on a Xilinx device, or
* (b) that interact with a Xilinx device through a bus or interconnect.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* XILINX CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
* Except as contained in this notice, the name of the Xilinx shall not be used
* in advertising or otherwise to promote the sale, use or other dealings in
* this Software without prior written authorization from Xilinx.
*
******************************************************************************/
/*****************************************************************************/
/**
*
* @file xusbps_ch9_storage.h
*
* This file contains definitions used in the chapter 9 code.
*
*
* <pre>
* MODIFICATION HISTORY:
*
* Ver Who Date Changes
* ----- ---- -------- -------------------------------------------------------
* 1.00a wgr 10/10/10 First release
* </pre>
*
******************************************************************************/
#ifndef XUSBPS_CLASS_STORAGE_H
#define XUSBPS_CLASS_STORAGE_H
#ifdef __cplusplus
extern "C" {
#endif
/***************************** Include Files *********************************/
#include "xil_types.h"
#include "xusbps_ch9_storage.h"
/************************** Constant Definitions *****************************/
/* Mass storage opcodes.
*/
#define USB_RBC_FORMAT 0x04
#define USB_RBC_INQUIRY 0x12
#define USB_RBC_MODE_SEL 0x15
#define USB_RBC_MODE_SENSE 0x1a
#define USB_RBC_READ 0x28
#define USB_RBC_READ_CAP 0x25
#define USB_RBC_VERIFY 0x2f
#define USB_RBC_WRITE 0x2a
#define USB_RBC_STARTSTOP_UNIT 0x1b
#define USB_RBC_TEST_UNIT_READY 0x00
#define USB_RBC_MEDIUM_REMOVAL 0x1e
#define USB_UFI_GET_CAP_LIST 0x23
/* Virtual Flash memory related definitions.
*/
#define VFLASH_SIZE 0x100000 /* 1MB space */
#define VFLASH_BLOCK_SIZE 0x200
#define VFLASH_NUM_BLOCKS (VFLASH_SIZE/VFLASH_BLOCK_SIZE)
/* Class request opcodes.
*/
#define XUSBPS_CLASSREQ_MASS_STORAGE_RESET 0xFF
#define XUSBPS_CLASSREQ_GET_MAX_LUN 0xFE
/* SCSI machine states
*/
#define USB_EP_STATE_COMMAND 0
#define USB_EP_STATE_DATA 1
#define USB_EP_STATE_STATUS 2
/**************************** Type Definitions *******************************/
/* The following structures define USB storage class requests. The details of
* the contents of those structures are not important in the context of this
* example.
*/
typedef struct {
u32 dCBWSignature;
u32 dCBWTag;
u32 dCBWDataTransferLength;
u8 bmCBWFlags;
u8 cCBWLUN;
u8 bCBWCBLength;
u8 CBWCB[16];
} __attribute__((__packed__))USB_CBW;
typedef struct {
u8 deviceType;
u8 rmb;
u8 version;
u8 blah;
u8 additionalLength;
u8 sccs;
u8 info0;
u8 info1;
u8 vendorID[8];
u8 productID[16];
u8 revision[4];
} __attribute__((__packed__))SCSI_INQUIRY;
typedef struct {
u8 reserved[3];
u8 listLength;
u32 numBlocks;
u8 descCode;
u8 blockLengthMSB;
u16 blockLength;
} __attribute__((__packed__))SCSI_CAP_LIST;
typedef struct {
u32 numBlocks;
u32 blockSize;
} __attribute__((__packed__))SCSI_READ_CAPACITY;
typedef struct {
u8 opCode;
u8 reserved1;
u32 block;
u8 reserved2;
u16 length;
u8 control;
} __attribute__((__packed__))SCSI_READ_WRITE;
typedef struct {
u8 opCode;
u8 immed;
u8 reserved1;
u8 reserved2;
u8 start;
u8 control;
} __attribute__((__packed__))SCSI_START_STOP;
/***************** Macros (Inline Functions) Definitions *********************/
/************************** Function Prototypes ******************************/
void XUsbPs_HandleStorageReq(XUsbPs *InstancePtr, u8 EpNum,
u8 *BufferPtr, u32 BufferLen);
void XUsbPs_ClassReq(XUsbPs *InstancePtr, XUsbPs_SetupData *SetupData);
#ifdef __cplusplus
}
#endif
#endif /* XUSBPS_CLASS_STORAGE_H */

View file

@ -0,0 +1,574 @@
/******************************************************************************
*
* Copyright (C) 2010 - 2014 Xilinx, Inc. All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* Use of the Software is limited solely to applications:
* (a) running on a Xilinx device, or
* (b) that interact with a Xilinx device through a bus or interconnect.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* XILINX CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
* Except as contained in this notice, the name of the Xilinx shall not be used
* in advertising or otherwise to promote the sale, use or other dealings in
* this Software without prior written authorization from Xilinx.
*
******************************************************************************/
/*****************************************************************************/
/**
* @file xusbps_intr_example.c
*
* This file contains an example of how to use the USB driver with the USB
* controller in DEVICE mode.
*
*
*<pre>
* MODIFICATION HISTORY:
*
* Ver Who Date Changes
* ----- ------ -------- ----------------------------------------------------
* 1.00a wgr/nm 10/09/10 First release
* 1.01a nm 03/05/10 Included xpseudo_asm.h instead of xpseudo_asm_gcc.h
* 1.04a nm 02/05/13 Fixed CR# 696550.
* Added template code for Vendor request.
* 1.06a kpc 11/11/13 Fixed CR#759458, cacheInvalidate size should be
* ailgned to ccahe line size.
* 2.1 kpc 04/28/14 Cleanup and removed unused functions
*</pre>
******************************************************************************/
/***************************** Include Files *********************************/
#include "xparameters.h" /* XPAR parameters */
#include "xusbps.h" /* USB controller driver */
#include "xscugic.h"
#include "xusbps_ch9.h" /* Generic Chapter 9 handling code */
#include "xusbps_class_storage.h" /* Storage class handling code */
#include "xil_exception.h"
#include "xpseudo_asm.h"
#include "xreg_cortexa9.h"
#include "xil_cache.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
/************************** Constant Definitions *****************************/
#define MEMORY_SIZE (64 * 1024)
u8 Buffer[MEMORY_SIZE] ALIGNMENT_CACHELINE;
/**************************** Type Definitions *******************************/
/***************** Macros (Inline Functions) Definitions *********************/
/************************** Function Prototypes ******************************/
static int UsbIntrExample(XScuGic *IntcInstancePtr, XUsbPs *UsbInstancePtr,
u16 UsbDeviceId, u16 UsbIntrId);
static void UsbIntrHandler(void *CallBackRef, u32 Mask);
static void XUsbPs_Ep0EventHandler(void *CallBackRef, u8 EpNum,
u8 EventType, void *Data);
static void XUsbPs_Ep1EventHandler(void *CallBackRef, u8 EpNum,
u8 EventType, void *Data);
static int UsbSetupIntrSystem(XScuGic *IntcInstancePtr,
XUsbPs *UsbInstancePtr, u16 UsbIntrId);
static void UsbDisableIntrSystem(XScuGic *IntcInstancePtr, u16 UsbIntrId);
/************************** Variable Definitions *****************************/
/* The instances to support the device drivers are global such that the
* are initialized to zero each time the program runs.
*/
static XScuGic IntcInstance; /* The instance of the IRQ Controller */
static XUsbPs UsbInstance; /* The instance of the USB Controller */
static volatile int NumIrqs = 0;
static volatile int NumReceivedFrames = 0;
/*****************************************************************************/
/**
*
* Main function to call the USB interrupt example.
*
* @param None
*
* @return
* - XST_SUCCESS if successful
* - XST_FAILURE on error
*
******************************************************************************/
int main(void)
{
int Status;
/* Run the USB Interrupt example.*/
Status = UsbIntrExample(&IntcInstance, &UsbInstance,
XPAR_XUSBPS_0_DEVICE_ID, XPAR_XUSBPS_0_INTR);
if (Status != XST_SUCCESS) {
return XST_FAILURE;
}
return XST_SUCCESS;
}
/*****************************************************************************/
/**
*
* This function does a minimal DEVICE mode setup on the USB device and driver
* as a design example. The purpose of this function is to illustrate how to
* set up a USB flash disk emulation system.
*
*
* @param IntcInstancePtr is a pointer to the instance of the INTC driver.
* @param UsbInstancePtr is a pointer to the instance of USB driver.
* @param UsbDeviceId is the Device ID of the USB Controller and is the
* XPAR_<USB_instance>_DEVICE_ID value from xparameters.h.
* @param UsbIntrId is the Interrupt Id and is typically
* XPAR_<INTC_instance>_<USB_instance>_IP2INTC_IRPT_INTR value
* from xparameters.h.
*
* @return
* - XST_SUCCESS if successful
* - XST_FAILURE on error
*
******************************************************************************/
static int UsbIntrExample(XScuGic *IntcInstancePtr, XUsbPs *UsbInstancePtr,
u16 UsbDeviceId, u16 UsbIntrId)
{
int Status;
u8 *MemPtr = NULL;
int ReturnStatus = XST_FAILURE;
/* For this example we only configure 2 endpoints:
* Endpoint 0 (default control endpoint)
* Endpoint 1 (BULK data endpoint)
*/
const u8 NumEndpoints = 2;
XUsbPs_Config *UsbConfigPtr;
XUsbPs_DeviceConfig DeviceConfig;
/* Initialize the USB driver so that it's ready to use,
* specify the controller ID that is generated in xparameters.h
*/
UsbConfigPtr = XUsbPs_LookupConfig(UsbDeviceId);
if (NULL == UsbConfigPtr) {
goto out;
}
/* We are passing the physical base address as the third argument
* because the physical and virtual base address are the same in our
* example. For systems that support virtual memory, the third
* argument needs to be the virtual base address.
*/
Status = XUsbPs_CfgInitialize(UsbInstancePtr,
UsbConfigPtr,
UsbConfigPtr->BaseAddress);
if (XST_SUCCESS != Status) {
goto out;
}
/* Set up the interrupt subsystem.
*/
Status = UsbSetupIntrSystem(IntcInstancePtr,
UsbInstancePtr,
UsbIntrId);
if (XST_SUCCESS != Status)
{
goto out;
}
/* Configuration of the DEVICE side of the controller happens in
* multiple stages.
*
* 1) The user configures the desired endpoint configuration using the
* XUsbPs_DeviceConfig data structure. This includes the number of
* endpoints, the number of Transfer Descriptors for each endpoint
* (each endpoint can have a different number of Transfer Descriptors)
* and the buffer size for the OUT (receive) endpoints. Each endpoint
* can have different buffer sizes.
*
* 2) Request the required size of DMAable memory from the driver using
* the XUsbPs_DeviceMemRequired() call.
*
* 3) Allocate the DMAable memory and set up the DMAMemVirt and
* DMAMemPhys members in the XUsbPs_DeviceConfig data structure.
*
* 4) Configure the DEVICE side of the controller by calling the
* XUsbPs_ConfigureDevice() function.
*/
/*
* For this example we only configure Endpoint 0 and Endpoint 1.
*
* Bufsize = 0 indicates that there is no buffer allocated for OUT
* (receive) endpoint 0. Endpoint 0 is a control endpoint and we only
* receive control packets on that endpoint. Control packets are 8
* bytes in size and are received into the Queue Head's Setup Buffer.
* Therefore, no additional buffer space is needed.
*/
DeviceConfig.EpCfg[0].Out.Type = XUSBPS_EP_TYPE_CONTROL;
DeviceConfig.EpCfg[0].Out.NumBufs = 2;
DeviceConfig.EpCfg[0].Out.BufSize = 64;
DeviceConfig.EpCfg[0].Out.MaxPacketSize = 64;
DeviceConfig.EpCfg[0].In.Type = XUSBPS_EP_TYPE_CONTROL;
DeviceConfig.EpCfg[0].In.NumBufs = 2;
DeviceConfig.EpCfg[0].In.MaxPacketSize = 64;
DeviceConfig.EpCfg[1].Out.Type = XUSBPS_EP_TYPE_BULK;
DeviceConfig.EpCfg[1].Out.NumBufs = 16;
DeviceConfig.EpCfg[1].Out.BufSize = 512;
DeviceConfig.EpCfg[1].Out.MaxPacketSize = 512;
DeviceConfig.EpCfg[1].In.Type = XUSBPS_EP_TYPE_BULK;
DeviceConfig.EpCfg[1].In.NumBufs = 16;
DeviceConfig.EpCfg[1].In.MaxPacketSize = 512;
DeviceConfig.NumEndpoints = NumEndpoints;
MemPtr = (u8 *)&Buffer[0];
memset(MemPtr,0,MEMORY_SIZE);
Xil_DCacheFlushRange((unsigned int)MemPtr, MEMORY_SIZE);
/* Finish the configuration of the DeviceConfig structure and configure
* the DEVICE side of the controller.
*/
DeviceConfig.DMAMemPhys = (u32) MemPtr;
Status = XUsbPs_ConfigureDevice(UsbInstancePtr, &DeviceConfig);
if (XST_SUCCESS != Status) {
goto out;
}
/* Set the handler for receiving frames. */
Status = XUsbPs_IntrSetHandler(UsbInstancePtr, UsbIntrHandler, NULL,
XUSBPS_IXR_UE_MASK);
if (XST_SUCCESS != Status) {
goto out;
}
/* Set the handler for handling endpoint 0 events. This is where we
* will receive and handle the Setup packet from the host.
*/
Status = XUsbPs_EpSetHandler(UsbInstancePtr, 0,
XUSBPS_EP_DIRECTION_OUT,
XUsbPs_Ep0EventHandler, UsbInstancePtr);
/* Set the handler for handling endpoint 1 events.
*
* Note that for this example we do not need to register a handler for
* TX complete events as we only send data using static data buffers
* that do not need to be free()d or returned to the OS after they have
* been sent.
*/
Status = XUsbPs_EpSetHandler(UsbInstancePtr, 1,
XUSBPS_EP_DIRECTION_OUT,
XUsbPs_Ep1EventHandler, UsbInstancePtr);
/* Enable the interrupts. */
XUsbPs_IntrEnable(UsbInstancePtr, XUSBPS_IXR_UR_MASK |
XUSBPS_IXR_UI_MASK);
/* Start the USB engine */
XUsbPs_Start(UsbInstancePtr);
/* At this point we wait for the user to plug in the usb plug. This
* will cause the host to send USB packets. Once we received something,
* we clean up and stop the controller.
*
* This will not really work if we want to use the USB storage
* example. What can we do instead?
*/
while (NumReceivedFrames < 1) {
/* NOP */
}
/* Set return code to indicate success and fall through to clean-up
* code.
*/
ReturnStatus = XST_SUCCESS;
out:
/* Clean up. It's always safe to disable interrupts and clear the
* handlers, even if they have not been enabled/set. The same is true
* for disabling the interrupt subsystem.
*/
XUsbPs_Stop(UsbInstancePtr);
XUsbPs_IntrDisable(UsbInstancePtr, XUSBPS_IXR_ALL);
(int) XUsbPs_IntrSetHandler(UsbInstancePtr, NULL, NULL, 0);
UsbDisableIntrSystem(IntcInstancePtr, UsbIntrId);
/* Free allocated memory.
*/
if (NULL != UsbInstancePtr->UserDataPtr) {
free(UsbInstancePtr->UserDataPtr);
}
return ReturnStatus;
}
/*****************************************************************************/
/**
*
* This function is the handler which performs processing for the USB driver.
* It is called from an interrupt context such that the amount of processing
* performed should be minimized.
*
* This handler provides an example of how to handle USB interrupts and
* is application specific.
*
* @param CallBackRef is the Upper layer callback reference passed back
* when the callback function is invoked.
* @param Mask is the Interrupt Mask.
* @param CallBackRef is the User data reference.
*
* @return
* - XST_SUCCESS if successful
* - XST_FAILURE on error
*
* @note None.
*
******************************************************************************/
static void UsbIntrHandler(void *CallBackRef, u32 Mask)
{
NumIrqs++;
}
/*****************************************************************************/
/**
* This funtion is registered to handle callbacks for endpoint 0 (Control).
*
* It is called from an interrupt context such that the amount of processing
* performed should be minimized.
*
*
* @param CallBackRef is the reference passed in when the function
* was registered.
* @param EpNum is the Number of the endpoint on which the event occured.
* @param EventType is type of the event that occured.
*
* @return None.
*
******************************************************************************/
static void XUsbPs_Ep0EventHandler(void *CallBackRef, u8 EpNum,
u8 EventType, void *Data)
{
XUsbPs *InstancePtr;
int Status;
XUsbPs_SetupData SetupData;
u8 *BufferPtr;
u32 BufferLen;
u32 Handle;
Xil_AssertVoid(NULL != CallBackRef);
InstancePtr = (XUsbPs *) CallBackRef;
switch (EventType) {
/* Handle the Setup Packets received on Endpoint 0. */
case XUSBPS_EP_EVENT_SETUP_DATA_RECEIVED:
Status = XUsbPs_EpGetSetupData(InstancePtr, EpNum, &SetupData);
if (XST_SUCCESS == Status) {
/* Handle the setup packet. */
(int) XUsbPs_Ch9HandleSetupPacket(InstancePtr,
&SetupData);
}
break;
/* We get data RX events for 0 length packets on endpoint 0. We receive
* and immediately release them again here, but there's no action to be
* taken.
*/
case XUSBPS_EP_EVENT_DATA_RX:
/* Get the data buffer. */
Status = XUsbPs_EpBufferReceive(InstancePtr, EpNum,
&BufferPtr, &BufferLen, &Handle);
if (XST_SUCCESS == Status) {
/* Return the buffer. */
XUsbPs_EpBufferRelease(Handle);
}
break;
default:
/* Unhandled event. Ignore. */
break;
}
}
/*****************************************************************************/
/**
* This funtion is registered to handle callbacks for endpoint 1 (Bulk data).
*
* It is called from an interrupt context such that the amount of processing
* performed should be minimized.
*
*
* @param CallBackRef is the reference passed in when the function was
* registered.
* @param EpNum is the Number of the endpoint on which the event occured.
* @param EventType is type of the event that occured.
*
* @return None.
*
* @note None.
*
******************************************************************************/
static void XUsbPs_Ep1EventHandler(void *CallBackRef, u8 EpNum,
u8 EventType, void *Data)
{
XUsbPs *InstancePtr;
int Status;
u8 *BufferPtr;
u32 BufferLen;
u32 InavalidateLen;
u32 Handle;
Xil_AssertVoid(NULL != CallBackRef);
InstancePtr = (XUsbPs *) CallBackRef;
switch (EventType) {
case XUSBPS_EP_EVENT_DATA_RX:
/* Get the data buffer.*/
Status = XUsbPs_EpBufferReceive(InstancePtr, EpNum,
&BufferPtr, &BufferLen, &Handle);
/* Invalidate the Buffer Pointer */
InavalidateLen = BufferLen;
if (BufferLen % 32) {
InavalidateLen = (BufferLen/32) * 32 + 32;
}
Xil_DCacheInvalidateRange((unsigned int)BufferPtr,
InavalidateLen);
if (XST_SUCCESS == Status) {
/* Handle the storage class request. */
XUsbPs_HandleStorageReq(InstancePtr, EpNum,
BufferPtr, BufferLen);
/* Release the buffer. */
XUsbPs_EpBufferRelease(Handle);
}
break;
default:
/* Unhandled event. Ignore. */
break;
}
}
/*****************************************************************************/
/**
*
* This function setups the interrupt system such that interrupts can occur for
* the USB controller. This function is application specific since the actual
* system may or may not have an interrupt controller. The USB controller could
* be directly connected to a processor without an interrupt controller. The
* user should modify this function to fit the application.
*
* @param IntcInstancePtr is a pointer to instance of the Intc controller.
* @param UsbInstancePtr is a pointer to instance of the USB controller.
* @param UsbIntrId is the Interrupt Id and is typically
* XPAR_<INTC_instance>_<USB_instance>_VEC_ID value
* from xparameters.h
*
* @return
* - XST_SUCCESS if successful
* - XST_FAILURE on error
*
******************************************************************************/
static int UsbSetupIntrSystem(XScuGic *IntcInstancePtr,
XUsbPs *UsbInstancePtr, u16 UsbIntrId)
{
int Status;
XScuGic_Config *IntcConfig;
/*
* Initialize the interrupt controller driver so that it is ready to
* use.
*/
IntcConfig = XScuGic_LookupConfig(XPAR_SCUGIC_SINGLE_DEVICE_ID);
if (NULL == IntcConfig) {
return XST_FAILURE;
}
Status = XScuGic_CfgInitialize(IntcInstancePtr, IntcConfig,
IntcConfig->CpuBaseAddress);
if (Status != XST_SUCCESS) {
return XST_FAILURE;
}
Xil_ExceptionInit();
/*
* Connect the interrupt controller interrupt handler to the hardware
* interrupt handling logic in the processor.
*/
Xil_ExceptionRegisterHandler(XIL_EXCEPTION_ID_IRQ_INT,
(Xil_ExceptionHandler)XScuGic_InterruptHandler,
IntcInstancePtr);
/*
* Connect the device driver handler that will be called when an
* interrupt for the device occurs, the handler defined above performs
* the specific interrupt processing for the device.
*/
Status = XScuGic_Connect(IntcInstancePtr, UsbIntrId,
(Xil_ExceptionHandler)XUsbPs_IntrHandler,
(void *)UsbInstancePtr);
if (Status != XST_SUCCESS) {
return Status;
}
/*
* Enable the interrupt for the device.
*/
XScuGic_Enable(IntcInstancePtr, UsbIntrId);
/*
* Enable interrupts in the Processor.
*/
Xil_ExceptionEnableMask(XIL_EXCEPTION_IRQ);
return XST_SUCCESS;
}
/*****************************************************************************/
/**
*
* This function disables the interrupts that occur for the USB controller.
*
* @param IntcInstancePtr is a pointer to instance of the INTC driver.
* @param UsbIntrId is the Interrupt Id and is typically
* XPAR_<INTC_instance>_<USB_instance>_VEC_ID value
* from xparameters.h
*
* @return None
*
* @note None.
*
******************************************************************************/
static void UsbDisableIntrSystem(XScuGic *IntcInstancePtr, u16 UsbIntrId)
{
/* Disconnect and disable the interrupt for the USB controller. */
XScuGic_Disconnect(IntcInstancePtr, UsbIntrId);
}

View file

@ -0,0 +1,41 @@
COMPILER=
ARCHIVER=
CP=cp
COMPILER_FLAGS=
EXTRA_COMPILER_FLAGS=
LIB=libxil.a
CC_FLAGS = $(COMPILER_FLAGS)
ECC_FLAGS = $(EXTRA_COMPILER_FLAGS)
RELEASEDIR=../../../lib
INCLUDEDIR=../../../include
INCLUDES=-I./. -I${INCLUDEDIR}
OUTS = *.o
LIBSOURCES:=*.c
INCLUDEFILES:=*.h
OBJECTS = $(addsuffix .o, $(basename $(wildcard *.c)))
libs: banner xusbps_libs clean
%.o: %.c
${COMPILER} $(CC_FLAGS) $(ECC_FLAGS) $(INCLUDES) -o $@ $<
banner:
echo "Compiling usbps"
xusbps_libs: ${OBJECTS}
$(ARCHIVER) -r ${RELEASEDIR}/${LIB} ${OBJECTS}
.PHONY: include
include: xusbps_includes
xusbps_includes:
${CP} ${INCLUDEFILES} ${INCLUDEDIR}
clean:
rm -rf ${OBJECTS}

View file

@ -0,0 +1,361 @@
/******************************************************************************
*
* Copyright (C) 2010 - 2014 Xilinx, Inc. All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* Use of the Software is limited solely to applications:
* (a) running on a Xilinx device, or
* (b) that interact with a Xilinx device through a bus or interconnect.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* XILINX CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
* Except as contained in this notice, the name of the Xilinx shall not be used
* in advertising or otherwise to promote the sale, use or other dealings in
* this Software without prior written authorization from Xilinx.
*
******************************************************************************/
/******************************************************************************/
/**
* @file xusbps.c
*
* The XUsbPs driver. Functions in this file are the minimum required
* functions for this driver. See xusbps.h for a detailed description of the
* driver.
*
* @note None.
*
* <pre>
* MODIFICATION HISTORY:
*
* Ver Who Date Changes
* ----- ---- -------- --------------------------------------------------------
* 1.00a jz 10/10/10 First release
* 2.1 kpc 04/28/14 Removed ununsed functions
* </pre>
******************************************************************************/
/***************************** Include Files **********************************/
#include <stdio.h>
#include "xusbps.h"
/************************** Constant Definitions ******************************/
/**************************** Type Definitions ********************************/
/***************** Macros (Inline Functions) Definitions **********************/
/************************** Variable Definitions ******************************/
/************************** Function Prototypes *******************************/
/*****************************************************************************/
/**
*
* This function initializes a XUsbPs instance/driver.
*
* The initialization entails:
* - Initialize all members of the XUsbPs structure.
*
* @param InstancePtr is a pointer to XUsbPs instance of the controller.
* @param ConfigPtr is a pointer to a XUsbPs_Config configuration
* structure. This structure will contain the requested
* configuration for the device. Typically, this is a local
* structure and the content of which will be copied into the
* configuration structure within XUsbPs.
* @param VirtBaseAddress is the base address of the device. For systems
* with virtual memory, this address must be the virtual address
* of the device.
* For systems that do not support virtual memory this address
* should be the physical address of the device. For backwards
* compatibilty NULL may be passed in systems that do not support
* virtual memory (deprecated).
*
* @return
* - XST_SUCCESS no errors occured.
* - XST_FAILURE an error occured during initialization.
*
* @note
* After calling XUsbPs_CfgInitialize() the controller
* IS NOT READY for use. Before the controller can be used its
* DEVICE parameters must be configured. See xusbps.h
* for details.
*
******************************************************************************/
int XUsbPs_CfgInitialize(XUsbPs *InstancePtr,
const XUsbPs_Config *ConfigPtr, u32 VirtBaseAddress)
{
Xil_AssertNonvoid(InstancePtr != NULL);
Xil_AssertNonvoid(ConfigPtr != NULL);
/* Copy the config structure. */
InstancePtr->Config = *ConfigPtr;
/* Check if the user provided a non-NULL base address. If so, we have
* to overwrite the base address in the configuration structure.
*/
if (0 != VirtBaseAddress) {
InstancePtr->Config.BaseAddress = VirtBaseAddress;
}
/* Initialize the XUsbPs structure to default values. */
InstancePtr->CurrentAltSetting = XUSBPS_DEFAULT_ALT_SETTING;
InstancePtr->HandlerFunc = NULL;
return XST_SUCCESS;
}
/*****************************************************************************/
/**
*
* This function performs device reset, device is stopped at the end.
*
* @param InstancePtr is a pointer to XUsbPs instance of the controller.
*
* @return None.
*
* @note None.
*
******************************************************************************/
void XUsbPs_DeviceReset(XUsbPs *InstancePtr)
{
int Timeout;
/* Clear all setup token semaphores by reading the
* XUSBPS_EPSTAT_OFFSET register and writing its value back to
* itself.
*/
XUsbPs_WriteReg(InstancePtr->Config.BaseAddress, XUSBPS_EPSTAT_OFFSET,
XUsbPs_ReadReg(InstancePtr->Config.BaseAddress,
XUSBPS_EPSTAT_OFFSET));
/* Clear all the endpoint complete status bits by reading the
* XUSBPS_EPCOMPL_OFFSET register and writings its value back
* to itself.
*/
XUsbPs_WriteReg(InstancePtr->Config.BaseAddress, XUSBPS_EPCOMPL_OFFSET,
XUsbPs_ReadReg(InstancePtr->Config.BaseAddress,
XUSBPS_EPCOMPL_OFFSET));
/* Cancel all endpoint prime status by waiting until all bits
* in XUSBPS_EPPRIME_OFFSET are 0 and then writing 0xFFFFFFFF
* to XUSBPS_EPFLUSH_OFFSET.
*
* Avoid hanging here by using a Timeout counter...
*/
Timeout = XUSBPS_TIMEOUT_COUNTER;
while ((XUsbPs_ReadReg(InstancePtr->Config.BaseAddress,
XUSBPS_EPPRIME_OFFSET) &
XUSBPS_EP_ALL_MASK) && --Timeout) {
/* NOP */
}
XUsbPs_WriteReg(InstancePtr->Config.BaseAddress,
XUSBPS_EPFLUSH_OFFSET, 0xFFFFFFFF);
XUsbPs_Stop(InstancePtr);
/* Write to CR register for controller reset */
XUsbPs_WriteReg(InstancePtr->Config.BaseAddress, XUSBPS_CMD_OFFSET,
XUsbPs_ReadReg(InstancePtr->Config.BaseAddress,
XUSBPS_CMD_OFFSET) | XUSBPS_CMD_RST_MASK);
/* Wait for reset to finish, hardware clears the reset bit once done */
Timeout = 1000000;
while((XUsbPs_ReadReg(InstancePtr->Config.BaseAddress,
XUSBPS_CMD_OFFSET) &
XUSBPS_CMD_RST_MASK) && --Timeout) {
/* NOP */
}
}
/*****************************************************************************/
/**
*
* This function resets the USB device. All the configuration registers are
* reset to their default values. The function waits until the reset operation
* is complete or for a certain duration within which the reset operation is
* expected to be completed.
*
* @param InstancePtr is a pointer to XUsbPs instance of the controller.
*
* @return
* - XST_SUCCESS Reset operation completed successfully.
* - XST_FAILURE Reset operation timed out.
*
* @note None.
*
******************************************************************************/
int XUsbPs_Reset(XUsbPs *InstancePtr)
{
int Timeout;
Xil_AssertNonvoid(InstancePtr != NULL);
/* Write a 1 to the RESET bit. The RESET bit is cleared by HW once the
* RESET is complete.
*
* We are going to wait for the RESET bit to clear before we return
* from this function. Unfortunately we do not have timers available at
* this point to determine when we should report a Timeout.
*
* However, by using a large number for the poll loop we can assume
* that the polling operation will take longer than the expected time
* the HW needs to RESET. If the poll loop expires we can assume a
* Timeout. The drawback is that on a slow system (and even on a fast
* system) this can lead to _very_ long Timeout periods.
*/
XUsbPs_WriteReg(InstancePtr->Config.BaseAddress,
XUSBPS_CMD_OFFSET, XUSBPS_CMD_RST_MASK);
/* Wait for the RESET bit to be cleared by HW. */
Timeout = XUSBPS_TIMEOUT_COUNTER;
while ((XUsbPs_ReadReg(InstancePtr->Config.BaseAddress,
XUSBPS_CMD_OFFSET) &
XUSBPS_CMD_RST_MASK) && --Timeout) {
/* NOP */
}
if (0 == Timeout) {
return XST_FAILURE;
}
return XST_SUCCESS;
}
/*****************************************************************************/
/**
* USB Suspend
*
* In order to conserve power, USB devices automatically enter the suspended
* state when the device has observed no bus traffic for a specified period.
* When suspended, the USB device maintains any internal status, including its
* address and configuration. Attached devices must be prepared to suspend at
* any time they are powered, regardless of if they have been assigned a
* non-default address, are configured, or neither. Bus activity may cease due
* to the host entering a suspend mode of its own. In addition, a USB device
* shall also enter the suspended state when the hub port it is attached to is
* disabled.
*
* A USB device exits suspend mode when there is bus activity. A USB device may
* also request the host to exit suspend mode or selective suspend by using
* electrical signaling to indicate remote wakeup. The ability of a device to
* signal remote wakeup is optional. If the USB device is capable of remote
* wakeup signaling, the device must support the ability of the host to enable
* and disable this capability. When the device is reset, remote wakeup
* signaling must be disabled.
*
* @param InstancePtr is a pointer to XUsbPs instance of the controller.
*
* @return
* - XST_SUCCESS if the USB device has entered Suspend mode
* successfully
* - XST_FAILURE on any error
*
* @note None.
*
******************************************************************************/
int XUsbPs_Suspend(const XUsbPs *InstancePtr)
{
(void) InstancePtr;
return XST_SUCCESS;
}
/*****************************************************************************/
/**
* USB Resume
*
If the USB controller is suspended, its operation is resumed when any
* non-idle signaling is received on its upstream facing port.
*
* @param InstancePtr is a pointer to XUsbPs instance of the controller.
*
* @return
* - XST_SUCCESS if the USB device has Resumed successfully
* - XST_FAILURE on any error
*
* @note None.
*
******************************************************************************/
int XUsbPs_Resume(const XUsbPs *InstancePtr)
{
(void) InstancePtr;
return XST_SUCCESS;
}
/*****************************************************************************/
/**
* USB Assert Resume
*
* @param InstancePtr is a pointer to XUsbPs instance of the controller.
*
* @return
* - XST_SUCCESS if the USB device has Resumed successfully
* - XST_FAILURE on any error
*
* @note None.
*
******************************************************************************/
int XUsbPs_RequestHostResume(const XUsbPs *InstancePtr)
{
(void) InstancePtr;
return XST_SUCCESS;
}
/****************************************************************************/
/**
* This functions sets the controller's DEVICE address. It also sets the
* advance bit so the controller will wait for the next IN-ACK before the new
* address takes effect.
*
* @param InstancePtr is a pointer to XUsbPs instance of the controller.
* @param Address is the Address of the device.
*
* @return
* - XST_SUCCESS: Address set successfully.
* - XST_FAILURE: An error occured.
* - XST_INVALID_PARAM: Invalid parameter passed, e.g. address
* value too big.
*
* @note None.
*
*****************************************************************************/
int XUsbPs_SetDeviceAddress(XUsbPs *InstancePtr, u8 Address)
{
Xil_AssertNonvoid(InstancePtr != NULL);
/* Check address range validity. */
if (Address > XUSBPS_DEVICEADDR_MAX) {
return XST_INVALID_PARAM;
}
/* Set the address register with the Address value provided. Also set
* the Address Advance Bit. This will cause the address to be set only
* after an IN occured and has been ACKed on the endpoint.
*/
XUsbPs_WriteReg(InstancePtr->Config.BaseAddress,
XUSBPS_DEVICEADDR_OFFSET,
(Address << XUSBPS_DEVICEADDR_ADDR_SHIFT) |
XUSBPS_DEVICEADDR_DEVICEAADV_MASK);
return XST_SUCCESS;
}

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,512 @@
/******************************************************************************
*
* Copyright (C) 2010 - 2014 Xilinx, Inc. All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* Use of the Software is limited solely to applications:
* (a) running on a Xilinx device, or
* (b) that interact with a Xilinx device through a bus or interconnect.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* XILINX CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
* Except as contained in this notice, the name of the Xilinx shall not be used
* in advertising or otherwise to promote the sale, use or other dealings in
* this Software without prior written authorization from Xilinx.
*
******************************************************************************/
/*****************************************************************************/
/**
*
* @file xusbps_endpoint.h
*
* This is an internal file containung the definitions for endpoints. It is
* included by the xusbps_endpoint.c which is implementing the endpoint
* functions and by xusbps_intr.c.
*
* <pre>
* MODIFICATION HISTORY:
*
* Ver Who Date Changes
* ----- ---- -------- --------------------------------------------------------
* 1.00a wgr 10/10/10 First release
* </pre>
*
******************************************************************************/
#ifndef XUSBPS_ENDPOINT_H
#define XUSBPS_ENDPOINT_H
#ifdef __cplusplus
extern "C" {
#endif
/***************************** Include Files *********************************/
#include "xil_cache.h"
#include "xusbps.h"
#include "xil_types.h"
/**************************** Type Definitions *******************************/
/************************** Constant Definitions *****************************/
/**
* Endpoint Device Transfer Descriptor
*
* The dTD describes to the device controller the location and quantity of data
* to be sent/received for given transfer. The driver does not attempt to
* modify any field in an active dTD except the Next Link Pointer.
*/
#define XUSBPS_dTDNLP 0x00 /**< Pointer to the next descriptor */
#define XUSBPS_dTDTOKEN 0x04 /**< Descriptor Token */
#define XUSBPS_dTDBPTR0 0x08 /**< Buffer Pointer 0 */
#define XUSBPS_dTDBPTR1 0x0C /**< Buffer Pointer 1 */
#define XUSBPS_dTDBPTR2 0x10 /**< Buffer Pointer 2 */
#define XUSBPS_dTDBPTR3 0x14 /**< Buffer Pointer 3 */
#define XUSBPS_dTDBPTR4 0x18 /**< Buffer Pointer 4 */
#define XUSBPS_dTDBPTR(n) (XUSBPS_dTDBPTR0 + (n) * 0x04)
#define XUSBPS_dTDRSRVD 0x1C /**< Reserved field */
/* We use the reserved field in the dTD to store user data. */
#define XUSBPS_dTDUSERDATA XUSBPS_dTDRSRVD /**< Reserved field */
/** @name dTD Next Link Pointer (dTDNLP) bit positions.
* @{
*/
#define XUSBPS_dTDNLP_T_MASK 0x00000001
/**< USB dTD Next Link Pointer Terminate Bit */
#define XUSBPS_dTDNLP_ADDR_MASK 0xFFFFFFE0
/**< USB dTD Next Link Pointer Address [31:5] */
/* @} */
/** @name dTD Token (dTDTOKEN) bit positions.
* @{
*/
#define XUSBPS_dTDTOKEN_XERR_MASK 0x00000008 /**< dTD Transaction Error */
#define XUSBPS_dTDTOKEN_BUFERR_MASK 0x00000020 /**< dTD Data Buffer Error */
#define XUSBPS_dTDTOKEN_HALT_MASK 0x00000040 /**< dTD Halted Flag */
#define XUSBPS_dTDTOKEN_ACTIVE_MASK 0x00000080 /**< dTD Active Bit */
#define XUSBPS_dTDTOKEN_MULTO_MASK 0x00000C00 /**< Multiplier Override Field [1:0] */
#define XUSBPS_dTDTOKEN_IOC_MASK 0x00008000 /**< Interrupt on Complete Bit */
#define XUSBPS_dTDTOKEN_LEN_MASK 0x7FFF0000 /**< Transfer Length Field */
/* @} */
/***************** Macros (Inline Functions) Definitions *********************/
/*****************************************************************************/
/**
*
* IMPORTANT NOTE:
* ===============
*
* Many of the following macros modify Device Queue Head (dQH) data structures
* and Device Transfer Descriptor (dTD) data structures. Those structures can
* potentially reside in CACHED memory. Therefore, it's the callers
* responsibility to ensure cache coherency by using provided
*
* XUsbPs_dQHInvalidateCache()
* XUsbPs_dQHFlushCache()
* XUsbPs_dTDInvalidateCache()
* XUsbPs_dTDFlushCache()
*
* function calls.
*
******************************************************************************/
#define XUsbPs_dTDInvalidateCache(dTDPtr) \
Xil_DCacheInvalidateRange((unsigned int)dTDPtr, sizeof(XUsbPs_dTD))
#define XUsbPs_dTDFlushCache(dTDPtr) \
Xil_DCacheFlushRange((unsigned int)dTDPtr, sizeof(XUsbPs_dTD))
#define XUsbPs_dQHInvalidateCache(dQHPtr) \
Xil_DCacheInvalidateRange((unsigned int)dQHPtr, sizeof(XUsbPs_dQH))
#define XUsbPs_dQHFlushCache(dQHPtr) \
Xil_DCacheFlushRange((unsigned int)dQHPtr, sizeof(XUsbPs_dQH))
/*****************************************************************************/
/**
*
* This macro sets the Transfer Length for the given Transfer Descriptor.
*
* @param dTDPtr is pointer to the dTD element.
* @param Len is the length to be set. Range: 0..16384
*
* @note C-style signature:
* void XUsbPs_dTDSetTransferLen(u32 dTDPtr, u32 Len)
*
******************************************************************************/
#define XUsbPs_dTDSetTransferLen(dTDPtr, Len) \
XUsbPs_WritedTD(dTDPtr, XUSBPS_dTDTOKEN, \
(XUsbPs_ReaddTD(dTDPtr, XUSBPS_dTDTOKEN) & \
~XUSBPS_dTDTOKEN_LEN_MASK) | ((Len) << 16))
/*****************************************************************************/
/**
*
* This macro gets the Next Link pointer of the given Transfer Descriptor.
*
* @param dTDPtr is pointer to the dTD element.
*
* @return TransferLength field of the descriptor.
*
* @note C-style signature:
* u32 XUsbPs_dTDGetTransferLen(u32 dTDPtr)
*
******************************************************************************/
#define XUsbPs_dTDGetNLP(dTDPtr) \
(XUsbPs_dTD *) ((XUsbPs_ReaddTD(dTDPtr, XUSBPS_dTDNLP)\
& XUSBPS_dTDNLP_ADDR_MASK))
/*****************************************************************************/
/**
*
* This macro sets the Next Link pointer of the given Transfer Descriptor.
*
* @param dTDPtr is a pointer to the dTD element.
* @param NLP is the Next Link Pointer
*
* @note C-style signature:
* void XUsbPs_dTDSetTransferLen(u32 dTDPtr, u32 Len)
*
******************************************************************************/
#define XUsbPs_dTDSetNLP(dTDPtr, NLP) \
XUsbPs_WritedTD(dTDPtr, XUSBPS_dTDNLP, \
(XUsbPs_ReaddTD(dTDPtr, XUSBPS_dTDNLP) & \
~XUSBPS_dTDNLP_ADDR_MASK) | \
((NLP) & XUSBPS_dTDNLP_ADDR_MASK))
/*****************************************************************************/
/**
*
* This macro gets the Transfer Length for the given Transfer Descriptor.
*
* @param dTDPtr is a pointer to the dTD element.
*
* @return TransferLength field of the descriptor.
*
* @note C-style signature:
* u32 XUsbPs_dTDGetTransferLen(u32 dTDPtr)
*
******************************************************************************/
#define XUsbPs_dTDGetTransferLen(dTDPtr) \
(u32) ((XUsbPs_ReaddTD(dTDPtr, XUSBPS_dTDTOKEN) \
& XUSBPS_dTDTOKEN_LEN_MASK) >> 16)
/*****************************************************************************/
/**
*
* This macro sets the Interrupt On Complete (IOC) bit for the given Transfer
* Descriptor.
*
* @param dTDPtr is a pointer to the dTD element.
*
* @note C-style signature:
* void XUsbPs_dTDSetIOC(u32 dTDPtr)
*
******************************************************************************/
#define XUsbPs_dTDSetIOC(dTDPtr) \
XUsbPs_WritedTD(dTDPtr, XUSBPS_dTDTOKEN, \
XUsbPs_ReaddTD(dTDPtr, XUSBPS_dTDTOKEN) | \
XUSBPS_dTDTOKEN_IOC_MASK)
/*****************************************************************************/
/**
*
* This macro sets the Terminate bit for the given Transfer Descriptor.
*
* @param dTDPtr is a pointer to the dTD element.
*
* @note C-style signature:
* void XUsbPs_dTDSetTerminate(u32 dTDPtr)
*
******************************************************************************/
#define XUsbPs_dTDSetTerminate(dTDPtr) \
XUsbPs_WritedTD(dTDPtr, XUSBPS_dTDNLP, \
XUsbPs_ReaddTD(dTDPtr, XUSBPS_dTDNLP) | \
XUSBPS_dTDNLP_T_MASK)
/*****************************************************************************/
/**
*
* This macro clears the Terminate bit for the given Transfer Descriptor.
*
* @param dTDPtr is a pointer to the dTD element.
*
* @note C-style signature:
* void XUsbPs_dTDClrTerminate(u32 dTDPtr)
*
******************************************************************************/
#define XUsbPs_dTDClrTerminate(dTDPtr) \
XUsbPs_WritedTD(dTDPtr, XUSBPS_dTDNLP, \
XUsbPs_ReaddTD(dTDPtr, XUSBPS_dTDNLP) & \
~XUSBPS_dTDNLP_T_MASK)
/*****************************************************************************/
/**
*
* This macro checks if the given descriptor is active.
*
* @param dTDPtr is a pointer to the dTD element.
*
* @return
* - TRUE: The buffer is active.
* - FALSE: The buffer is not active.
*
* @note C-style signature:
* int XUsbPs_dTDIsActive(u32 dTDPtr)
*
******************************************************************************/
#define XUsbPs_dTDIsActive(dTDPtr) \
((XUsbPs_ReaddTD(dTDPtr, XUSBPS_dTDTOKEN) & \
XUSBPS_dTDTOKEN_ACTIVE_MASK) ? TRUE : FALSE)
/*****************************************************************************/
/**
*
* This macro sets the Active bit for the given Transfer Descriptor.
*
* @param dTDPtr is a pointer to the dTD element.
*
* @note C-style signature:
* void XUsbPs_dTDSetActive(u32 dTDPtr)
*
******************************************************************************/
#define XUsbPs_dTDSetActive(dTDPtr) \
XUsbPs_WritedTD(dTDPtr, XUSBPS_dTDTOKEN, \
XUsbPs_ReaddTD(dTDPtr, XUSBPS_dTDTOKEN) | \
XUSBPS_dTDTOKEN_ACTIVE_MASK)
/*****************************************************************************/
/**
*
* This macro reads the content of a field in a Transfer Descriptor.
*
* @param dTDPtr is a pointer to the dTD element.
* @param Id is the field ID inside the dTD element to read.
*
* @note C-style signature:
* u32 XUsbPs_ReaddTD(u32 dTDPtr, u32 Id)
*
******************************************************************************/
#define XUsbPs_ReaddTD(dTDPtr, Id) (*(u32 *)((u32)(dTDPtr) + (u32)(Id)))
/*****************************************************************************/
/**
*
* This macro writes a value to a field in a Transfer Descriptor.
*
* @param dTDPtr is pointer to the dTD element.
* @param Id is the field ID inside the dTD element to read.
* @param Val is the value to write to the field.
*
* @note C-style signature:
* u32 XUsbPs_WritedTD(u32 dTDPtr, u32 Id, u32 Val)
*
******************************************************************************/
#define XUsbPs_WritedTD(dTDPtr, Id, Val) \
(*(u32 *) ((u32)(dTDPtr) + (u32)(Id)) = (u32)(Val))
/******************************************************************************/
/**
* Endpoint Device Queue Head
*
* Device queue heads are arranged in an array in a continuous area of memory
* pointed to by the ENDPOINTLISTADDR pointer. The device controller will index
* into this array based upon the endpoint number received from the USB bus.
* All information necessary to respond to transactions for all primed
* transfers is contained in this list so the Device Controller can readily
* respond to incoming requests without having to traverse a linked list.
*
* The device Endpoint Queue Head (dQH) is where all transfers are managed. The
* dQH is a 48-byte data structure, but must be aligned on a 64-byte boundary.
* During priming of an endpoint, the dTD (device transfer descriptor) is
* copied into the overlay area of the dQH, which starts at the nextTD pointer
* DWord and continues through the end of the buffer pointers DWords. After a
* transfer is complete, the dTD status DWord is updated in the dTD pointed to
* by the currentTD pointer. While a packet is in progress, the overlay area of
* the dQH is used as a staging area for the dTD so that the Device Controller
* can access needed information with little minimal latency.
*
* @note
* Software must ensure that no interface data structure reachable by the
* Device Controller spans a 4K-page boundary. The first element of the
* Endpoint Queue Head List must be aligned on a 4K boundary.
*/
#define XUSBPS_dQHCFG 0x00 /**< dQH Configuration */
#define XUSBPS_dQHCPTR 0x04 /**< dQH Current dTD Pointer */
#define XUSBPS_dQHdTDNLP 0x08 /**< dTD Next Link Ptr in dQH
overlay */
#define XUSBPS_dQHdTDTOKEN 0x0C /**< dTD Token in dQH overlay */
#define XUSBPS_dQHSUB0 0x28 /**< USB dQH Setup Buffer 0 */
#define XUSBPS_dQHSUB1 0x2C /**< USB dQH Setup Buffer 1 */
/** @name dQH Configuration (dQHCFG) bit positions.
* @{
*/
#define XUSBPS_dQHCFG_IOS_MASK 0x00008000
/**< USB dQH Interrupt on Setup Bit */
#define XUSBPS_dQHCFG_MPL_MASK 0x07FF0000
/**< USB dQH Maximum Packet Length
* Field [10:0] */
#define XUSBPS_dQHCFG_MPL_SHIFT 16
#define XUSBPS_dQHCFG_ZLT_MASK 0x20000000
/**< USB dQH Zero Length Termination
* Select Bit */
#define XUSBPS_dQHCFG_MULT_MASK 0xC0000000
/* USB dQH Number of Transactions Field
* [1:0] */
#define XUSBPS_dQHCFG_MULT_SHIFT 30
/* @} */
/*****************************************************************************/
/**
*
* This macro sets the Maximum Packet Length field of the give Queue Head.
*
* @param dQHPtr is a pointer to the dQH element.
* @param Len is the length to be set.
*
* @note C-style signature:
* void XUsbPs_dQHSetMaxPacketLen(u32 dQHPtr, u32 Len)
*
******************************************************************************/
#define XUsbPs_dQHSetMaxPacketLen(dQHPtr, Len) \
XUsbPs_WritedQH(dQHPtr, XUSBPS_dQHCFG, \
(XUsbPs_ReaddQH(dQHPtr, XUSBPS_dQHCFG) & \
~XUSBPS_dQHCFG_MPL_MASK) | ((Len) << 16))
/*****************************************************************************/
/**
*
* This macro sets the Interrupt On Setup (IOS) bit for an endpoint.
*
* @param dQHPtr is a pointer to the dQH element.
*
* @note C-style signature:
* void XUsbPs_dQHSetIOS(u32 dQHPtr)
*
******************************************************************************/
#define XUsbPs_dQHSetIOS(dQHPtr) \
XUsbPs_WritedQH(dQHPtr, XUSBPS_dQHCFG, \
XUsbPs_ReaddQH(dQHPtr, XUSBPS_dQHCFG) | \
XUSBPS_dQHCFG_IOS_MASK)
/*****************************************************************************/
/**
*
* This macro clears the Interrupt On Setup (IOS) bit for an endpoint.
*
* @param dQHPtr is a pointer to the dQH element.
*
* @note C-style signature:
* void XUsbPs_dQHClrIOS(u32 dQHPtr)
*
******************************************************************************/
#define XUsbPs_dQHClrIOS(dQHPtr) \
XUsbPs_WritedQH(dQHPtr, XUSBPS_dQHCFG, \
XUsbPs_ReaddQH(dQHPtr, XUSBPS_dQHCFG) & \
~XUSBPS_dQHCFG_IOS_MASK)
/*****************************************************************************/
/**
*
* This macro enables Zero Length Termination for the endpoint.
*
* @param dQHPtr is a pointer to the dQH element.
*
* @note C-style signature:
* void XUsbPs_dQHEnableZLT(u32 dQHPtr)
*
*
******************************************************************************/
#define XUsbPs_dQHEnableZLT(dQHPtr) \
XUsbPs_WritedQH(dQHPtr, XUSBPS_dQHCFG, \
XUsbPs_ReaddQH(dQHPtr, XUSBPS_dQHCFG) & \
~XUSBPS_dQHCFG_ZLT_MASK)
/*****************************************************************************/
/**
*
* This macro disables Zero Length Termination for the endpoint.
*
* @param dQHPtr is a pointer to the dQH element.
*
* @note C-style signature:
* void XUsbPs_dQHDisableZLT(u32 dQHPtr)
*
*
******************************************************************************/
#define XUsbPs_dQHDisableZLT(dQHPtr) \
XUsbPs_WritedQH(dQHPtr, XUSBPS_dQHCFG, \
XUsbPs_ReaddQH(dQHPtr, XUSBPS_dQHCFG) | \
XUSBPS_dQHCFG_ZLT_MASK)
/*****************************************************************************/
/**
*
* This macro reads the content of a field in a Queue Head.
*
* @param dQHPtr is a pointer to the dQH element.
* @param Id is the Field ID inside the dQH element to read.
*
* @note C-style signature:
* u32 XUsbPs_ReaddQH(u32 dQHPtr, u32 Id)
*
******************************************************************************/
#define XUsbPs_ReaddQH(dQHPtr, Id) (*(u32 *)((u32)(dQHPtr) + (u32) (Id)))
/*****************************************************************************/
/**
*
* This macro writes a value to a field in a Queue Head.
*
* @param dQHPtr is a pointer to the dQH element.
* @param Id is the Field ID inside the dQH element to read.
* @param Val is the Value to write to the field.
*
* @note C-style signature:
* u32 XUsbPs_WritedQH(u32 dQHPtr, u32 Id, u32 Val)
*
******************************************************************************/
#define XUsbPs_WritedQH(dQHPtr, Id, Val) \
(*(u32 *) ((u32)(dQHPtr) + (u32)(Id)) = (u32)(Val))
#ifdef __cplusplus
}
#endif
#endif /* XUSBPS_ENDPOINT_H */

View file

@ -0,0 +1,77 @@
/******************************************************************************
*
* Copyright (C) 2010 - 2014 Xilinx, Inc. All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* Use of the Software is limited solely to applications:
* (a) running on a Xilinx device, or
* (b) that interact with a Xilinx device through a bus or interconnect.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* XILINX CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
* Except as contained in this notice, the name of the Xilinx shall not be used
* in advertising or otherwise to promote the sale, use or other dealings in
* this Software without prior written authorization from Xilinx.
*
******************************************************************************/
/****************************************************************************/
/**
*
* @file xusbps_g.c
* This file contains a configuration table where each entry is a configuration
* structure for an XUsbPs device in the system.
*
* <pre>
* MODIFICATION HISTORY:
*
* Ver Who Date Changes
* ----- ---- -------- -----------------------------------------------
* 1.00a wgr 10/10/10 First release
* 2.00 hk 22/01/14 Added check to select second instance.
* </pre>
*
*****************************************************************************/
/***************************** Include Files ********************************/
#include "xusbps.h"
#include "xparameters.h"
/************************** Constant Definitions ****************************/
/**************************** Type Definitions ******************************/
/***************** Macros (Inline Functions) Definitions ********************/
/************************** Variable Definitions ****************************/
/**
* Each XUsbPs device in the system has an entry in this table.
*/
XUsbPs_Config XUsbPs_ConfigTable[] = {
{
0,
XPAR_XUSBPS_0_BASEADDR
},
#ifdef XPAR_XUSBPS_1_BASEADDR
{
1,
XPAR_XUSBPS_1_BASEADDR
}
#endif
};

View file

@ -0,0 +1,119 @@
/******************************************************************************
*
* Copyright (C) 2010 - 2014 Xilinx, Inc. All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* Use of the Software is limited solely to applications:
* (a) running on a Xilinx device, or
* (b) that interact with a Xilinx device through a bus or interconnect.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* XILINX CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
* Except as contained in this notice, the name of the Xilinx shall not be used
* in advertising or otherwise to promote the sale, use or other dealings in
* this Software without prior written authorization from Xilinx.
*
******************************************************************************/
/****************************************************************************/
/**
*
* @file xusbps_hw.c
*
* The implementation of the XUsbPs interface reset functionality
*
* <pre>
* MODIFICATION HISTORY:
*
* Ver Who Date Changes
* ----- ---- -------- -----------------------------------------------
* 1.05a kpc 10/10/10 first version
* </pre>
*
*****************************************************************************/
/***************************** Include Files ********************************/
#include "xstatus.h"
#include "xusbps.h"
#include "xparameters.h"
/************************** Constant Definitions ****************************/
#define XUSBPS_RESET_TIMEOUT 0xFFFFF
/**************************** Type Definitions ******************************/
/***************** Macros (Inline Functions) Definitions ********************/
/************************** Variable Definitions ****************************/
/************************** Function Prototypes *****************************/
/*****************************************************************************/
/**
* This function perform the reset sequence to the given usbps interface by
* configuring the appropriate control bits in the usbps specifc registers.
* the usbps reset sequence involves the below steps
* Disbale the interrupts
* Clear the status registers
* Apply the reset command and wait for reset complete status
* Update the relevant control registers with reset values
* @param BaseAddress of the interface
*
* @return N/A.
*
* @note None.
*
******************************************************************************/
void XUsbPs_ResetHw(u32 BaseAddress)
{
u32 RegVal;
u32 Timeout = 0;
/* Host and device mode */
/* Disable the interrupts */
XUsbPs_WriteReg(BaseAddress,XUSBPS_IER_OFFSET,0x0);
/* Clear the interuupt status */
RegVal = XUsbPs_ReadReg(BaseAddress,XUSBPS_ISR_OFFSET);
XUsbPs_WriteReg(BaseAddress,XUSBPS_ISR_OFFSET,RegVal);
/* Perform the reset operation using USB CMD register */
RegVal = XUsbPs_ReadReg(BaseAddress,XUSBPS_CMD_OFFSET);
RegVal = RegVal | XUSBPS_CMD_RST_MASK;
XUsbPs_WriteReg(BaseAddress,XUSBPS_CMD_OFFSET,RegVal);
RegVal = XUsbPs_ReadReg(BaseAddress,XUSBPS_CMD_OFFSET);
/* Wait till the reset operation returns success */
/*
* FIX ME: right now no indication to the caller or user about
* timeout overflow
*/
while ((RegVal & XUSBPS_CMD_RST_MASK) && (Timeout < XUSBPS_RESET_TIMEOUT))
{
RegVal = XUsbPs_ReadReg(BaseAddress,XUSBPS_CMD_OFFSET);
Timeout++;
}
/* Update periodic list base address register with reset value */
XUsbPs_WriteReg(BaseAddress,XUSBPS_LISTBASE_OFFSET,0x0);
/* Update async/endpoint list base address register with reset value */
XUsbPs_WriteReg(BaseAddress,XUSBPS_ASYNCLISTADDR_OFFSET,0x0);
}

View file

@ -0,0 +1,523 @@
/******************************************************************************
*
* Copyright (C) 2010 - 2014 Xilinx, Inc. All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* Use of the Software is limited solely to applications:
* (a) running on a Xilinx device, or
* (b) that interact with a Xilinx device through a bus or interconnect.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* XILINX CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
* Except as contained in this notice, the name of the Xilinx shall not be used
* in advertising or otherwise to promote the sale, use or other dealings in
* this Software without prior written authorization from Xilinx.
*
******************************************************************************/
/*****************************************************************************/
/**
*
* @file xusbps_hw.h
*
* This header file contains identifiers and low-level driver functions (or
* macros) that can be used to access the device. High-level driver functions
* are defined in xusbps.h.
*
* <pre>
* MODIFICATION HISTORY:
*
* Ver Who Date Changes
* ----- ---- -------- -----------------------------------------------
* 1.00a wgr 10/10/10 First release
* 1.04a nm 10/23/12 Fixed CR# 679106.
* 1.05a kpc 07/03/13 Added XUsbPs_ResetHw function prototype
* 2.00a kpc 04/03/14 Fixed CR#777764. Corrected max endpoint vale and masks
* </pre>
*
******************************************************************************/
#ifndef XUSBPS_HW_H
#define XUSBPS_HW_H
#ifdef __cplusplus
extern "C" {
#endif
/***************************** Include Files *********************************/
#include "xil_types.h"
#include "xil_assert.h"
#include "xil_io.h"
/************************** Constant Definitions *****************************/
#define XUSBPS_REG_SPACING 4
/** @name Timer 0 Register offsets
*
* @{
*/
#define XUSBPS_TIMER0_LD_OFFSET 0x00000080
#define XUSBPS_TIMER0_CTL_OFFSET 0x00000084
/* @} */
/** @name Timer Control Register bit mask
*
* @{
*/
#define XUSBPS_TIMER_RUN_MASK 0x80000000
#define XUSBPS_TIMER_STOP_MASK 0x80000000
#define XUSBPS_TIMER_RESET_MASK 0x40000000
#define XUSBPS_TIMER_REPEAT_MASK 0x01000000
/* @} */
/** @name Timer Control Register bit mask
*
* @{
*/
#define XUSBPS_TIMER_COUNTER_MASK 0x00FFFFFF
/* @} */
/** @name Device Hardware Parameters
*
* @{
*/
#define XUSBPS_HWDEVICE_OFFSET 0x0000000C
#define XUSBPS_EP_NUM_MASK 0x3E
#define XUSBPS_EP_NUM_SHIFT 1
/* @} */
/** @name Capability Regsiter offsets
*/
#define XUSBPS_HCSPARAMS_OFFSET 0x00000104
/** @name Operational Register offsets.
* Register comments are tagged with "H:" and "D:" for Host and Device modes,
* respectively.
* Tags are only present for registers that have a different meaning DEVICE and
* HOST modes. Most registers are only valid for either DEVICE or HOST mode.
* Those registers don't have tags.
* @{
*/
#define XUSBPS_CMD_OFFSET 0x00000140 /**< Configuration */
#define XUSBPS_ISR_OFFSET 0x00000144 /**< Interrupt Status */
#define XUSBPS_IER_OFFSET 0x00000148 /**< Interrupt Enable */
#define XUSBPS_FRAME_OFFSET 0x0000014C /**< USB Frame Index */
#define XUSBPS_LISTBASE_OFFSET 0x00000154 /**< H: Periodic List Base Address */
#define XUSBPS_DEVICEADDR_OFFSET 0x00000154 /**< D: Device Address */
#define XUSBPS_ASYNCLISTADDR_OFFSET 0x00000158 /**< H: Async List Address */
#define XUSBPS_EPLISTADDR_OFFSET 0x00000158 /**< D: Endpoint List Addr */
#define XUSBPS_TTCTRL_OFFSET 0x0000015C /**< TT Control */
#define XUSBPS_BURSTSIZE_OFFSET 0x00000160 /**< Burst Size */
#define XUSBPS_TXFILL_OFFSET 0x00000164 /**< Tx Fill Tuning */
#define XUSBPS_ULPIVIEW_OFFSET 0x00000170 /**< ULPI Viewport */
#define XUSBPS_EPNAKISR_OFFSET 0x00000178 /**< Endpoint NAK IRQ Status */
#define XUSBPS_EPNAKIER_OFFSET 0x0000017C /**< Endpoint NAK IRQ Enable */
#define XUSBPS_PORTSCR1_OFFSET 0x00000184 /**< Port Control/Status 1 */
/* NOTE: The Port Control / Status Register index is 1-based. */
#define XUSBPS_PORTSCRn_OFFSET(n) \
(XUSBPS_PORTSCR1_OFFSET + (((n)-1) * XUSBPS_REG_SPACING))
#define XUSBPS_OTGCSR_OFFSET 0x000001A4 /**< OTG Status and Control */
#define XUSBPS_MODE_OFFSET 0x000001A8 /**< USB Mode */
#define XUSBPS_EPSTAT_OFFSET 0x000001AC /**< Endpoint Setup Status */
#define XUSBPS_EPPRIME_OFFSET 0x000001B0 /**< Endpoint Prime */
#define XUSBPS_EPFLUSH_OFFSET 0x000001B4 /**< Endpoint Flush */
#define XUSBPS_EPRDY_OFFSET 0x000001B8 /**< Endpoint Ready */
#define XUSBPS_EPCOMPL_OFFSET 0x000001BC /**< Endpoint Complete */
#define XUSBPS_EPCR0_OFFSET 0x000001C0 /**< Endpoint Control 0 */
#define XUSBPS_EPCR1_OFFSET 0x000001C4 /**< Endpoint Control 1 */
#define XUSBPS_EPCR2_OFFSET 0x000001C8 /**< Endpoint Control 2 */
#define XUSBPS_EPCR3_OFFSET 0x000001CC /**< Endpoint Control 3 */
#define XUSBPS_EPCR4_OFFSET 0x000001D0 /**< Endpoint Control 4 */
#define XUSBPS_MAX_ENDPOINTS 12 /**< Number of supported Endpoints in
* this core. */
#define XUSBPS_EP_OUT_MASK 0x00000FFF /**< OUR (RX) endpoint mask */
#define XUSBPS_EP_IN_MASK 0x0FFF0000 /**< IN (TX) endpoint mask */
#define XUSBPS_EP_ALL_MASK 0x0FFF0FFF /**< Mask used for endpoint control
* registers */
#define XUSBPS_EPCRn_OFFSET(n) \
(XUSBPS_EPCR0_OFFSET + ((n) * XUSBPS_REG_SPACING))
#define XUSBPS_EPFLUSH_RX_SHIFT 0
#define XUSBPS_EPFLUSH_TX_SHIFT 16
/* @} */
/** @name Endpoint Control Register (EPCR) bit positions.
* @{
*/
/* Definitions for TX Endpoint bits */
#define XUSBPS_EPCR_TXT_CONTROL_MASK 0x00000000 /**< Control Endpoint - TX */
#define XUSBPS_EPCR_TXT_ISO_MASK 0x00040000 /**< Isochronous. Endpoint */
#define XUSBPS_EPCR_TXT_BULK_MASK 0x00080000 /**< Bulk Endpoint - TX */
#define XUSBPS_EPCR_TXT_INTR_MASK 0x000C0000 /**< Interrupt Endpoint */
#define XUSBPS_EPCR_TXS_MASK 0x00010000 /**< Stall TX endpoint */
#define XUSBPS_EPCR_TXE_MASK 0x00800000 /**< Transmit enable - TX */
#define XUSBPS_EPCR_TXR_MASK 0x00400000 /**< Data Toggle Reset Bit */
/* Definitions for RX Endpoint bits */
#define XUSBPS_EPCR_RXT_CONTROL_MASK 0x00000000 /**< Control Endpoint - RX */
#define XUSBPS_EPCR_RXT_ISO_MASK 0x00000004 /**< Isochronous Endpoint */
#define XUSBPS_EPCR_RXT_BULK_MASK 0x00000008 /**< Bulk Endpoint - RX */
#define XUSBPS_EPCR_RXT_INTR_MASK 0x0000000C /**< Interrupt Endpoint */
#define XUSBPS_EPCR_RXS_MASK 0x00000001 /**< Stall RX endpoint. */
#define XUSBPS_EPCR_RXE_MASK 0x00000080 /**< Transmit enable. - RX */
#define XUSBPS_EPCR_RXR_MASK 0x00000040 /**< Data Toggle Reset Bit */
/* @} */
/** @name USB Command Register (CR) bit positions.
* @{
*/
#define XUSBPS_CMD_RS_MASK 0x00000001 /**< Run/Stop */
#define XUSBPS_CMD_RST_MASK 0x00000002 /**< Controller RESET */
#define XUSBPS_CMD_FS01_MASK 0x0000000C /**< Frame List Size bit 0,1 */
#define XUSBPS_CMD_PSE_MASK 0x00000010 /**< Periodic Sched Enable */
#define XUSBPS_CMD_ASE_MASK 0x00000020 /**< Async Sched Enable */
#define XUSBPS_CMD_IAA_MASK 0x00000040 /**< IRQ Async Advance Doorbell */
#define XUSBPS_CMD_ASP_MASK 0x00000300 /**< Async Sched Park Mode Cnt */
#define XUSBPS_CMD_ASPE_MASK 0x00000800 /**< Async Sched Park Mode Enbl */
#define XUSBPS_CMD_SUTW_MASK 0x00002000 /**< Setup TripWire */
#define XUSBPS_CMD_ATDTW_MASK 0x00004000 /**< Add dTD TripWire */
#define XUSBPS_CMD_FS2_MASK 0x00008000 /**< Frame List Size bit 2 */
#define XUSBPS_CMD_ITC_MASK 0x00FF0000 /**< IRQ Threshold Control */
/* @} */
/**
* @name Interrupt Threshold
* These definitions are used by software to set the maximum rate at which the
* USB controller will generate interrupt requests. The interrupt interval is
* given in number of micro-frames.
*
* USB defines a full-speed 1 ms frame time indicated by a Start Of Frame (SOF)
* packet each and every 1ms. USB also defines a high-speed micro-frame with a
* 125us frame time. For each micro-frame a SOF (Start Of Frame) packet is
* generated. Data is sent in between the SOF packets. The interrupt threshold
* defines how many micro-frames the controller waits before issuing an
* interrupt after data has been received.
*
* For a threshold of 0 the controller will issue an interrupt immediately
* after the last byte of the data has been received. For a threshold n>0 the
* controller will wait for n micro-frames before issuing an interrupt.
*
* Therefore, a setting of 8 micro-frames (default) means that the controller
* will issue at most 1 interrupt per millisecond.
*
* @{
*/
#define XUSBPS_CMD_ITHRESHOLD_0 0x00 /**< Immediate interrupt. */
#define XUSBPS_CMD_ITHRESHOLD_1 0x01 /**< 1 micro-frame */
#define XUSBPS_CMD_ITHRESHOLD_2 0x02 /**< 2 micro-frames */
#define XUSBPS_CMD_ITHRESHOLD_4 0x04 /**< 4 micro-frames */
#define XUSBPS_CMD_ITHRESHOLD_8 0x08 /**< 8 micro-frames */
#define XUSBPS_CMD_ITHRESHOLD_16 0x10 /**< 16 micro-frames */
#define XUSBPS_CMD_ITHRESHOLD_32 0x20 /**< 32 micro-frames */
#define XUSBPS_CMD_ITHRESHOLD_64 0x40 /**< 64 micro-frames */
#define XUSBPS_CMD_ITHRESHOLD_MAX XUSBPS_CMD_ITHRESHOLD_64
#define XUSBPS_CMD_ITHRESHOLD_DEFAULT XUSBPS_CMD_ITHRESHOLD_8
/* @} */
/** @name USB Interrupt Status Register (ISR) / Interrupt Enable Register (IER)
* bit positions.
* @{
*/
#define XUSBPS_IXR_UI_MASK 0x00000001 /**< USB Transaction Complete */
#define XUSBPS_IXR_UE_MASK 0x00000002 /**< Transaction Error */
#define XUSBPS_IXR_PC_MASK 0x00000004 /**< Port Change Detect */
#define XUSBPS_IXR_FRE_MASK 0x00000008 /**< Frame List Rollover */
#define XUSBPS_IXR_AA_MASK 0x00000020 /**< Async Advance */
#define XUSBPS_IXR_UR_MASK 0x00000040 /**< RESET Received */
#define XUSBPS_IXR_SR_MASK 0x00000080 /**< Start of Frame */
#define XUSBPS_IXR_SLE_MASK 0x00000100 /**< Device Controller Suspend */
#define XUSBPS_IXR_ULPI_MASK 0x00000400 /**< ULPI IRQ */
#define XUSBPS_IXR_HCH_MASK 0x00001000 /**< Host Controller Halted
* Read Only */
#define XUSBPS_IXR_RCL_MASK 0x00002000 /**< USB Reclamation Read Only */
#define XUSBPS_IXR_PS_MASK 0x00004000 /**< Periodic Sched Status
* Read Only */
#define XUSBPS_IXR_AS_MASK 0x00008000 /**< Async Sched Status Read only */
#define XUSBPS_IXR_NAK_MASK 0x00010000 /**< NAK IRQ */
#define XUSBPS_IXR_UA_MASK 0x00040000 /**< USB Host Async IRQ */
#define XUSBPS_IXR_UP_MASK 0x00080000 /**< USB Host Periodic IRQ */
#define XUSBPS_IXR_TI0_MASK 0x01000000 /**< Timer 0 Interrupt */
#define XUSBPS_IXR_TI1_MASK 0x02000000 /**< Timer 1 Interrupt */
#define XUSBPS_IXR_ALL (XUSBPS_IXR_UI_MASK | \
XUSBPS_IXR_UE_MASK | \
XUSBPS_IXR_PC_MASK | \
XUSBPS_IXR_FRE_MASK | \
XUSBPS_IXR_AA_MASK | \
XUSBPS_IXR_UR_MASK | \
XUSBPS_IXR_SR_MASK | \
XUSBPS_IXR_SLE_MASK | \
XUSBPS_IXR_ULPI_MASK | \
XUSBPS_IXR_HCH_MASK | \
XUSBPS_IXR_RCL_MASK | \
XUSBPS_IXR_PS_MASK | \
XUSBPS_IXR_AS_MASK | \
XUSBPS_IXR_NAK_MASK | \
XUSBPS_IXR_UA_MASK | \
XUSBPS_IXR_UP_MASK | \
XUSBPS_IXR_TI0_MASK | \
XUSBPS_IXR_TI1_MASK)
/**< Mask for ALL IRQ types */
/* @} */
/** @name USB Mode Register (MODE) bit positions.
* @{
*/
#define XUSBPS_MODE_CM_MASK 0x00000003 /**< Controller Mode Select */
#define XUSBPS_MODE_CM_IDLE_MASK 0x00000000
#define XUSBPS_MODE_CM_DEVICE_MASK 0x00000002
#define XUSBPS_MODE_CM_HOST_MASK 0x00000003
#define XUSBPS_MODE_ES_MASK 0x00000004 /**< USB Endian Select */
#define XUSBPS_MODE_SLOM_MASK 0x00000008 /**< USB Setup Lockout Mode Disable */
#define XUSBPS_MODE_SDIS_MASK 0x00000010
#define XUSBPS_MODE_VALID_MASK 0x0000001F
/* @} */
/** @name USB Device Address Register (DEVICEADDR) bit positions.
* @{
*/
#define XUSBPS_DEVICEADDR_DEVICEAADV_MASK 0x01000000
/**< Device Addr Auto Advance */
#define XUSBPS_DEVICEADDR_ADDR_MASK 0xFE000000
/**< Device Address */
#define XUSBPS_DEVICEADDR_ADDR_SHIFT 25
/**< Address shift */
#define XUSBPS_DEVICEADDR_MAX 127
/**< Biggest allowed address */
/* @} */
/** @name USB TT Control Register (TTCTRL) bit positions.
* @{
*/
#define XUSBPS_TTCTRL_HUBADDR_MASK 0x7F000000 /**< TT Hub Address */
/* @} */
/** @name USB Burst Size Register (BURSTSIZE) bit posisions.
* @{
*/
#define XUSBPS_BURSTSIZE_RX_MASK 0x000000FF /**< RX Burst Length */
#define XUSBPS_BURSTSIZE_TX_MASK 0x0000FF00 /**< TX Burst Length */
/* @} */
/** @name USB Tx Fill Tuning Register (TXFILL) bit positions.
* @{
*/
#define XUSBPS_TXFILL_OVERHEAD_MASK 0x000000FF
/**< Scheduler Overhead */
#define XUSBPS_TXFILL_HEALTH_MASK 0x00001F00
/**< Scheduler Health Cntr */
#define XUSBPS_TXFILL_BURST_MASK 0x003F0000
/**< FIFO Burst Threshold */
/* @} */
/** @name USB ULPI Viewport Register (ULPIVIEW) bit positions.
* @{
*/
#define XUSBPS_ULPIVIEW_DATWR_MASK 0x000000FF /**< ULPI Data Write */
#define XUSBPS_ULPIVIEW_DATRD_MASK 0x0000FF00 /**< ULPI Data Read */
#define XUSBPS_ULPIVIEW_ADDR_MASK 0x00FF0000 /**< ULPI Data Address */
#define XUSBPS_ULPIVIEW_PORT_MASK 0x07000000 /**< ULPI Port Number */
#define XUSBPS_ULPIVIEW_SS_MASK 0x08000000 /**< ULPI Synchronous State */
#define XUSBPS_ULPIVIEW_RW_MASK 0x20000000 /**< ULPI Read/Write Control */
#define XUSBPS_ULPIVIEW_RUN_MASK 0x40000000 /**< ULPI Run */
#define XUSBPS_ULPIVIEW_WU_MASK 0x80000000 /**< ULPI Wakeup */
/* @} */
/** @name Port Status Control Register bit positions.
* @{
*/
#define XUSBPS_PORTSCR_CCS_MASK 0x00000001 /**< Current Connect Status */
#define XUSBPS_PORTSCR_CSC_MASK 0x00000002 /**< Connect Status Change */
#define XUSBPS_PORTSCR_PE_MASK 0x00000004 /**< Port Enable/Disable */
#define XUSBPS_PORTSCR_PEC_MASK 0x00000008 /**< Port Enable/Disable Change */
#define XUSBPS_PORTSCR_OCA_MASK 0x00000010 /**< Over-current Active */
#define XUSBPS_PORTSCR_OCC_MASK 0x00000020 /**< Over-current Change */
#define XUSBPS_PORTSCR_FPR_MASK 0x00000040 /**< Force Port Resume */
#define XUSBPS_PORTSCR_SUSP_MASK 0x00000080 /**< Suspend */
#define XUSBPS_PORTSCR_PR_MASK 0x00000100 /**< Port Reset */
#define XUSBPS_PORTSCR_HSP_MASK 0x00000200 /**< High Speed Port */
#define XUSBPS_PORTSCR_LS_MASK 0x00000C00 /**< Line Status */
#define XUSBPS_PORTSCR_PP_MASK 0x00001000 /**< Port Power */
#define XUSBPS_PORTSCR_PO_MASK 0x00002000 /**< Port Owner */
#define XUSBPS_PORTSCR_PIC_MASK 0x0000C000 /**< Port Indicator Control */
#define XUSBPS_PORTSCR_PTC_MASK 0x000F0000 /**< Port Test Control */
#define XUSBPS_PORTSCR_WKCN_MASK 0x00100000 /**< Wake on Connect Enable */
#define XUSBPS_PORTSCR_WKDS_MASK 0x00200000 /**< Wake on Disconnect Enable */
#define XUSBPS_PORTSCR_WKOC_MASK 0x00400000 /**< Wake on Over-current Enable */
#define XUSBPS_PORTSCR_PHCD_MASK 0x00800000 /**< PHY Low Power Suspend -
* Clock Disable */
#define XUSBPS_PORTSCR_PFSC_MASK 0x01000000 /**< Port Force Full Speed
* Connect */
#define XUSBPS_PORTSCR_PSPD_MASK 0x0C000000 /**< Port Speed */
/* @} */
/** @name On-The-Go Status Control Register (OTGCSR) bit positions.
* @{
*/
#define XUSBPS_OTGSC_VD_MASK 0x00000001 /**< VBus Discharge Bit */
#define XUSBPS_OTGSC_VC_MASK 0x00000002 /**< VBus Charge Bit */
#define XUSBPS_OTGSC_HAAR_MASK 0x00000004 /**< HW Assist Auto Reset
* Enable Bit */
#define XUSBPS_OTGSC_OT_MASK 0x00000008 /**< OTG Termination Bit */
#define XUSBPS_OTGSC_DP_MASK 0x00000010 /**< Data Pulsing Pull-up
* Enable Bit */
#define XUSBPS_OTGSC_IDPU_MASK 0x00000020 /**< ID Pull-up Enable Bit */
#define XUSBPS_OTGSC_HADP_MASK 0x00000040 /**< HW Assist Data Pulse
* Enable Bit */
#define XUSBPS_OTGSC_HABA_MASK 0x00000080 /**< USB Hardware Assist
* B Disconnect to A
* Connect Enable Bit */
#define XUSBPS_OTGSC_ID_MASK 0x00000100 /**< ID Status Flag */
#define XUSBPS_OTGSC_AVV_MASK 0x00000200 /**< USB A VBus Valid Interrupt Status Flag */
#define XUSBPS_OTGSC_ASV_MASK 0x00000400 /**< USB A Session Valid Interrupt Status Flag */
#define XUSBPS_OTGSC_BSV_MASK 0x00000800 /**< USB B Session Valid Status Flag */
#define XUSBPS_OTGSC_BSE_MASK 0x00001000 /**< USB B Session End Status Flag */
#define XUSBPS_OTGSC_1MST_MASK 0x00002000 /**< USB 1 Millisecond Timer Status Flag */
#define XUSBPS_OTGSC_DPS_MASK 0x00004000 /**< Data Pulse Status Flag */
#define XUSBPS_OTGSC_IDIS_MASK 0x00010000 /**< USB ID Interrupt Status Flag */
#define XUSBPS_OTGSC_AVVIS_MASK 0x00020000 /**< USB A VBus Valid Interrupt Status Flag */
#define XUSBPS_OTGSC_ASVIS_MASK 0x00040000 /**< USB A Session Valid Interrupt Status Flag */
#define XUSBPS_OTGSC_BSVIS_MASK 0x00080000 /**< USB B Session Valid Interrupt Status Flag */
#define XUSBPS_OTGSC_BSEIS_MASK 0x00100000 /**< USB B Session End Interrupt Status Flag */
#define XUSBPS_OTGSC_1MSS_MASK 0x00200000 /**< 1 Millisecond Timer Interrupt Status Flag */
#define XUSBPS_OTGSC_DPIS_MASK 0x00400000 /**< Data Pulse Interrupt Status Flag */
#define XUSBPS_OTGSC_IDIE_MASK 0x01000000 /**< ID Interrupt Enable Bit */
#define XUSBPS_OTGSC_AVVIE_MASK 0x02000000 /**< USB A VBus Valid Interrupt Enable Bit */
#define XUSBPS_OTGSC_ASVIE_MASK 0x04000000 /**< USB A Session Valid Interrupt Enable Bit */
#define XUSBPS_OTGSC_BSVIE_MASK 0x08000000 /**< USB B Session Valid Interrupt Enable Bit */
#define XUSBPS_OTGSC_BSEE_MASK 0x10000000 /**< USB B Session End Interrupt Enable Bit */
#define XUSBPS_OTGSC_1MSE_MASK 0x20000000 /**< 1 Millisecond Timer
* Interrupt Enable Bit */
#define XUSBPS_OTGSC_DPIE_MASK 0x40000000 /**< Data Pulse Interrupt
* Enable Bit */
#define XUSBPS_OTG_ISB_ALL (XUSBPS_OTGSC_IDIS_MASK |\
XUSBPS_OTGSC_AVVIS_MASK | \
XUSBPS_OTGSC_ASVIS_MASK | \
XUSBPS_OTGSC_BSVIS_MASK | \
XUSBPS_OTGSC_BSEIS_MASK | \
XUSBPS_OTGSC_1MSS_MASK | \
XUSBPS_OTGSC_DPIS_MASK)
/** Mask for All IRQ status masks */
#define XUSBPS_OTG_IEB_ALL (XUSBPS_OTGSC_IDIE_MASK |\
XUSBPS_OTGSC_AVVIE_MASK | \
XUSBPS_OTGSC_ASVIE_MASK | \
XUSBPS_OTGSC_BSVIE_MASK | \
XUSBPS_OTGSC_BSEE_IEB_MASK | \
XUSBPS_OTGSC_1MSE_MASK | \
XUSBPS_OTGSC_DPIE_MASK)
/** Mask for All IRQ Enable masks */
/* @} */
/**< Alignment of the Device Queue Head List BASE. */
#define XUSBPS_dQH_BASE_ALIGN 2048
/**< Alignment of a Device Queue Head structure. */
#define XUSBPS_dQH_ALIGN 64
/**< Alignment of a Device Transfer Descriptor structure. */
#define XUSBPS_dTD_ALIGN 32
/**< Size of one RX buffer for a OUT Transfer Descriptor. */
#define XUSBPS_dTD_BUF_SIZE 4096
/**< Maximum size of one RX/TX buffer. */
#define XUSBPS_dTD_BUF_MAX_SIZE 16*1024
/**< Alignment requirement for Transfer Descriptor buffers. */
#define XUSBPS_dTD_BUF_ALIGN 4096
/**************************** Type Definitions *******************************/
/***************** Macros (Inline Functions) Definitions *********************/
/****************************************************************************/
/**
*
* This macro reads the given register.
*
* @param BaseAddress is the base address for the USB registers.
* @param RegOffset is the register offset to be read.
*
* @return The 32-bit value of the register.
*
* @note C-style signature:
* u32 XUsbPs_ReadReg(u32 BaseAddress, u32 RegOffset)
*
*****************************************************************************/
#define XUsbPs_ReadReg(BaseAddress, RegOffset) \
Xil_In32(BaseAddress + (RegOffset))
/****************************************************************************/
/**
*
* This macro writes the given register.
*
* @param BaseAddress is the the base address for the USB registers.
* @param RegOffset is the register offset to be written.
* @param Data is the the 32-bit value to write to the register.
*
* @return None.
*
* @note C-style signature:
* void XUsbPs_WriteReg(u32 BaseAddress, u32 RegOffset, u32 Data)
*
*****************************************************************************/
#define XUsbPs_WriteReg(BaseAddress, RegOffset, Data) \
Xil_Out32(BaseAddress + (RegOffset), (Data))
/************************** Function Prototypes ******************************/
/*
* Perform reset operation to the USB PS interface
*/
void XUsbPs_ResetHw(u32 BaseAddress);
/************************** Variable Definitions ******************************/
#ifdef __cplusplus
}
#endif
#endif /* XUSBPS_L_H */

View file

@ -0,0 +1,467 @@
/******************************************************************************
*
* Copyright (C) 2010 - 2014 Xilinx, Inc. All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* Use of the Software is limited solely to applications:
* (a) running on a Xilinx device, or
* (b) that interact with a Xilinx device through a bus or interconnect.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* XILINX CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
* Except as contained in this notice, the name of the Xilinx shall not be used
* in advertising or otherwise to promote the sale, use or other dealings in
* this Software without prior written authorization from Xilinx.
*
******************************************************************************/
/******************************************************************************/
/**
* @file xusbps_intr.c
*
* This file contains the functions that are related to interrupt processing
* for the EPB USB driver.
*
* <pre>
* MODIFICATION HISTORY:
*
* Ver Who Date Changes
* ----- ---- -------- ----------------------------------------------------------
* 1.00a jz 10/10/10 First release
* 1.03a nm 09/21/12 Fixed CR#678977. Added proper sequence for setup packet
* handling.
* </pre>
******************************************************************************/
/***************************** Include Files **********************************/
#include "xusbps.h"
#include "xusbps_endpoint.h"
/************************** Constant Definitions ******************************/
/**************************** Type Definitions ********************************/
/***************** Macros (Inline Functions) Definitions **********************/
/************************** Variable Definitions ******************************/
/************************** Function Prototypes *******************************/
static void XUsbPs_IntrHandleTX(XUsbPs *InstancePtr, u32 EpCompl);
static void XUsbPs_IntrHandleRX(XUsbPs *InstancePtr, u32 EpCompl);
static void XUsbPs_IntrHandleReset(XUsbPs *InstancePtr, u32 IrqSts);
static void XUsbPs_IntrHandleEp0Setup(XUsbPs *InstancePtr);
/*****************************************************************************/
/**
* This function is the first-level interrupt handler for the USB core. All USB
* interrupts will be handled here. Depending on the type of the interrupt,
* second level interrupt handler may be called. Second level interrupt
* handlers will be registered by the user using the:
* XUsbPs_IntrSetHandler()
* and/or
* XUsbPs_EpSetHandler()
* functions.
*
*
* @param HandlerRef is a Reference passed to the interrupt register
* function. In our case this will be a pointer to the XUsbPs
* instance.
*
* @return None
*
* @note None
*
******************************************************************************/
void XUsbPs_IntrHandler(void *HandlerRef)
{
XUsbPs *InstancePtr;
u32 IrqSts;
Xil_AssertVoid(HandlerRef != NULL);
InstancePtr = (XUsbPs *) HandlerRef;
/* Handle controller (non-endpoint) related interrupts. */
IrqSts = XUsbPs_ReadReg(InstancePtr->Config.BaseAddress,
XUSBPS_ISR_OFFSET);
/* Clear the interrupt status register. */
XUsbPs_WriteReg(InstancePtr->Config.BaseAddress,
XUSBPS_ISR_OFFSET, IrqSts);
/* Nak interrupt, used to respond to host's IN request */
if(IrqSts & XUSBPS_IXR_NAK_MASK) {
/* Ack the hardware */
XUsbPs_WriteReg(InstancePtr->Config.BaseAddress,
XUSBPS_EPNAKISR_OFFSET,
XUsbPs_ReadReg(InstancePtr->Config.BaseAddress,
XUSBPS_EPNAKISR_OFFSET));
}
/***************************************************************
*
* Handle general interrupts. Endpoint interrupts will be handler
* later.
*
*/
/* RESET interrupt.*/
if (IrqSts & XUSBPS_IXR_UR_MASK) {
XUsbPs_IntrHandleReset(InstancePtr, IrqSts);
return;
}
/* Check if we have a user handler that needs to be called. Note that
* this is the handler for general interrupts. Endpoint interrupts will
* be handled below.
*/
if ((IrqSts & InstancePtr->HandlerMask) && InstancePtr->HandlerFunc) {
(InstancePtr->HandlerFunc)(InstancePtr->HandlerRef, IrqSts);
}
/***************************************************************
*
* Handle Endpoint interrupts.
*
*/
if (IrqSts & XUSBPS_IXR_UI_MASK) {
u32 EpStat;
u32 EpCompl;
/* ENDPOINT 0 SETUP PACKET HANDLING
*
* Check if we got a setup packet on endpoint 0. Currently we
* only check for setup packets on endpoint 0 as we would not
* expect setup packets on any other endpoint (even though it
* is possible to send setup packets on other endpoints).
*/
EpStat = XUsbPs_ReadReg(InstancePtr->Config.BaseAddress,
XUSBPS_EPSTAT_OFFSET);
if (EpStat & 0x0001) {
/* Handle the setup packet */
XUsbPs_IntrHandleEp0Setup(InstancePtr);
/* Re-Prime the endpoint.
* Endpoint is de-primed if a setup packet comes in.
*/
XUsbPs_EpPrime(InstancePtr, 0, XUSBPS_EP_DIRECTION_OUT);
}
/* Check for RX and TX complete interrupts. */
EpCompl = XUsbPs_ReadReg(InstancePtr->Config.BaseAddress,
XUSBPS_EPCOMPL_OFFSET);
/* ACK the complete interrupts. */
XUsbPs_WriteReg(InstancePtr->Config.BaseAddress,
XUSBPS_EPCOMPL_OFFSET, EpCompl);
/* Check OUT (RX) endpoints. */
if (EpCompl & XUSBPS_EP_OUT_MASK) {
XUsbPs_IntrHandleRX(InstancePtr, EpCompl);
}
/* Check IN (TX) endpoints. */
if (EpCompl & XUSBPS_EP_IN_MASK) {
XUsbPs_IntrHandleTX(InstancePtr, EpCompl);
}
}
}
/*****************************************************************************/
/**
* This function registers the user callback handler for controller
* (non-endpoint) interrupts.
*
* @param InstancePtr is a pointer to the XUsbPs instance of the
* controller.
* @param CallBackFunc is the Callback function to register.
* CallBackFunc may be NULL to clear the entry.
* @param CallBackRef is the user data reference passed to the
* callback function. CallBackRef may be NULL.
* @param Mask is the User interrupt mask. Defines which interrupts
* will cause the callback to be called.
*
* @return
* - XST_SUCCESS: Callback registered successfully.
* - XST_FAILURE: Callback could not be registered.
*
* @note None.
*
******************************************************************************/
int XUsbPs_IntrSetHandler(XUsbPs *InstancePtr,
XUsbPs_IntrHandlerFunc CallBackFunc,
void *CallBackRef, u32 Mask)
{
Xil_AssertNonvoid(InstancePtr != NULL);
InstancePtr->HandlerFunc = CallBackFunc;
InstancePtr->HandlerRef = CallBackRef;
InstancePtr->HandlerMask = Mask;
return XST_SUCCESS;
}
/*****************************************************************************/
/**
* This function handles TX buffer interrupts. It is called by the interrupt
* when a transmit complete interrupt occurs. It returns buffers of completed
* descriptors to the caller.
*
* @param InstancePtr is a pointer to the XUsbPs instance of the
* controller.
* @param EpCompl is the Bit mask of endpoints that caused a transmit
* complete interrupt.
*
* @return None
*
* @note None.
*
******************************************************************************/
static void XUsbPs_IntrHandleTX(XUsbPs *InstancePtr, u32 EpCompl)
{
int Index;
u32 Mask;
int NumEp;
/* Check all endpoints for TX complete bits.
*/
Mask = 0x00010000;
NumEp = InstancePtr->DeviceConfig.NumEndpoints;
/* Check for every endpoint if its TX complete bit is
* set.
*/
for (Index = 0; Index < NumEp; Index++, Mask <<= 1) {
XUsbPs_EpIn *Ep;
if (!(EpCompl & Mask)) {
continue;
}
/* The TX complete bit for this endpoint is
* set. Walk the list of descriptors to see
* which ones are completed.
*/
Ep = &InstancePtr->DeviceConfig.Ep[Index].In;
while (Ep->dTDTail != Ep->dTDHead) {
XUsbPs_dTDInvalidateCache(Ep->dTDTail);
/* If the descriptor is not active then the buffer has
* not been sent yet.
*/
if (XUsbPs_dTDIsActive(Ep->dTDTail)) {
break;
}
if (Ep->HandlerFunc) {
void *BufPtr;
BufPtr = (void *) XUsbPs_ReaddTD(Ep->dTDTail,
XUSBPS_dTDUSERDATA);
Ep->HandlerFunc(Ep->HandlerRef, Index,
XUSBPS_EP_EVENT_DATA_TX,
BufPtr);
}
Ep->dTDTail = XUsbPs_dTDGetNLP(Ep->dTDTail);
}
}
}
/*****************************************************************************/
/**
* This function handles RX buffer interrupts. It is called by the interrupt
* when a receive complete interrupt occurs. It notifies the callback functions
* that have been registered with the individual endpoints that data has been
* received.
*
* @param InstancePtr
* Pointer to the XUsbPs instance of the controller.
*
* @param EpCompl
* Bit mask of endpoints that caused a receive complete interrupt.
* @return
* none
*
******************************************************************************/
static void XUsbPs_IntrHandleRX(XUsbPs *InstancePtr, u32 EpCompl)
{
XUsbPs_EpOut *Ep;
int Index;
u32 Mask;
int NumEp;
/* Check all endpoints for RX complete bits. */
Mask = 0x00000001;
NumEp = InstancePtr->DeviceConfig.NumEndpoints;
/* Check for every endpoint if its RX complete bit is set.*/
for (Index = 0; Index < NumEp; Index++, Mask <<= 1) {
int numP = 0;
if (!(EpCompl & Mask)) {
continue;
}
Ep = &InstancePtr->DeviceConfig.Ep[Index].Out;
XUsbPs_dTDInvalidateCache(Ep->dTDCurr);
/* Handle all finished dTDs */
while (!XUsbPs_dTDIsActive(Ep->dTDCurr)) {
numP += 1;
if (Ep->HandlerFunc) {
Ep->HandlerFunc(Ep->HandlerRef, Index,
XUSBPS_EP_EVENT_DATA_RX, NULL);
}
Ep->dTDCurr = XUsbPs_dTDGetNLP(Ep->dTDCurr);
XUsbPs_dTDInvalidateCache(Ep->dTDCurr);
}
/* Re-Prime the endpoint.*/
XUsbPs_EpPrime(InstancePtr, Index, XUSBPS_EP_DIRECTION_OUT);
}
}
/*****************************************************************************/
/**
* This function handles a RESET interrupt. It will notify the interrupt
* handler callback of the RESET condition.
*
* @param InstancePtr is pointer to the XUsbPs instance of the controller
* @param IrqSts is the Interrupt status register content.
* To be passed on to the user.
*
* @return None
*
* @Note None.
*
******************************************************************************/
static void XUsbPs_IntrHandleReset(XUsbPs *InstancePtr, u32 IrqSts)
{
int Timeout;
/* Clear all setup token semaphores by reading the
* XUSBPS_EPSTAT_OFFSET register and writing its value back to
* itself.
*/
XUsbPs_WriteReg(InstancePtr->Config.BaseAddress, XUSBPS_EPSTAT_OFFSET,
XUsbPs_ReadReg(InstancePtr->Config.BaseAddress,
XUSBPS_EPSTAT_OFFSET));
/* Clear all the endpoint complete status bits by reading the
* XUSBPS_EPCOMPL_OFFSET register and writings its value back
* to itself.
*/
XUsbPs_WriteReg(InstancePtr->Config.BaseAddress,
XUSBPS_EPCOMPL_OFFSET,
XUsbPs_ReadReg(InstancePtr->Config.BaseAddress,
XUSBPS_EPCOMPL_OFFSET));
/* Cancel all endpoint prime status by waiting until all bits
* in XUSBPS_EPPRIME_OFFSET are 0 and then writing 0xFFFFFFFF
* to XUSBPS_EPFLUSH_OFFSET.
*
* Avoid hanging here by using a Timeout counter...
*/
Timeout = XUSBPS_TIMEOUT_COUNTER;
while ((XUsbPs_ReadReg(InstancePtr->Config.BaseAddress,
XUSBPS_EPPRIME_OFFSET) &
XUSBPS_EP_ALL_MASK) && --Timeout) {
/* NOP */
}
XUsbPs_WriteReg(InstancePtr->Config.BaseAddress,
XUSBPS_EPFLUSH_OFFSET, 0xFFFFFFFF);
/* Make sure that the reset bit in XUSBPS_PORTSCR1_OFFSET is
* still set at this point. If the code gets to this point and
* the reset bit has already been cleared we are in trouble and
* hardware reset is necessary.
*/
if (!(XUsbPs_ReadReg(InstancePtr->Config.BaseAddress,
XUSBPS_PORTSCR1_OFFSET) &
XUSBPS_PORTSCR_PR_MASK)) {
/* Send a notification to the user that a hardware
* RESET is required. At this point we can only hope
* that the user registered an interrupt handler and
* will issue a hardware RESET.
*/
if (InstancePtr->HandlerFunc) {
(InstancePtr->HandlerFunc)(InstancePtr->HandlerRef,
IrqSts);
}
else {
for (;;);
}
/* If we get here there is nothing more to do. The user
* should have reset the core.
*/
return;
}
/* Check if we have a user handler that needs to be called.
*/
if (InstancePtr->HandlerFunc) {
(InstancePtr->HandlerFunc)(InstancePtr->HandlerRef, IrqSts);
}
/* We are done. After RESET we don't proceed in the interrupt
* handler.
*/
}
/*****************************************************************************/
/**
* This function handles a Setup Packet interrupt. It will notify the interrupt
* handler callback of the RESET condition.
*
* @param InstancePtr is a pointer to the XUsbPs instance of the
* controller.
*
* @return None
*
* @Note None
*
******************************************************************************/
static void XUsbPs_IntrHandleEp0Setup(XUsbPs *InstancePtr)
{
XUsbPs_EpOut *Ep;
/* Notifiy the user. */
Ep = &InstancePtr->DeviceConfig.Ep[0].Out;
if (Ep->HandlerFunc) {
Ep->HandlerFunc(Ep->HandlerRef, 0,
XUSBPS_EP_EVENT_SETUP_DATA_RECEIVED, NULL);
}
}

View file

@ -0,0 +1,96 @@
/******************************************************************************
*
* Copyright (C) 2010 - 2014 Xilinx, Inc. All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* Use of the Software is limited solely to applications:
* (a) running on a Xilinx device, or
* (b) that interact with a Xilinx device through a bus or interconnect.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* XILINX CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
* Except as contained in this notice, the name of the Xilinx shall not be used
* in advertising or otherwise to promote the sale, use or other dealings in
* this Software without prior written authorization from Xilinx.
*
******************************************************************************/
/****************************************************************************/
/**
*
* @file xusbps_sinit.c
*
* The implementation of the XUsbPs driver's static initialzation
* functionality.
*
* <pre>
* MODIFICATION HISTORY:
*
* Ver Who Date Changes
* ----- ---- -------- -----------------------------------------------
* 1.00a wgr 10/10/10 First release
* </pre>
*
*****************************************************************************/
/***************************** Include Files ********************************/
#include "xstatus.h"
#include "xusbps.h"
#include "xparameters.h"
/************************** Constant Definitions ****************************/
/**************************** Type Definitions ******************************/
/***************** Macros (Inline Functions) Definitions ********************/
/************************** Variable Definitions ****************************/
extern XUsbPs_Config XUsbPs_ConfigTable[];
/************************** Function Prototypes *****************************/
/****************************************************************************/
/**
*
* Looks up the controller configuration based on the unique controller ID. A
* table contains the configuration info for each controller in the system.
*
* @param DeviceID is the ID of the controller to look up the
* configuration for.
*
* @return
* A pointer to the configuration found or NULL if the specified
* controller ID was not found.
*
******************************************************************************/
XUsbPs_Config *XUsbPs_LookupConfig(u16 DeviceID)
{
XUsbPs_Config *CfgPtr = NULL;
int Index;
for (Index = 0; Index < XPAR_XUSBPS_NUM_INSTANCES; Index++) {
if (XUsbPs_ConfigTable[Index].DeviceID == DeviceID) {
CfgPtr = &XUsbPs_ConfigTable[Index];
break;
}
}
return CfgPtr;
}