
Added initial support Xilinx Embedded Software. Signed-off-by: Jagannadha Sutradharudu Teki <jaganna@xilinx.com>
711 lines
21 KiB
C
Executable file
711 lines
21 KiB
C
Executable file
/******************************************************************************
|
|
*
|
|
* Copyright (C) 2006 Vreelin Engineering, Inc. All Rights Reserved.
|
|
* (c) Copyright 2007-2013 Xilinx, Inc. All rights reserved.
|
|
*
|
|
* This file contains confidential and proprietary information of Xilinx, Inc.
|
|
* and is protected under U.S. and international copyright and other
|
|
* intellectual property laws.
|
|
*
|
|
* DISCLAIMER
|
|
* This disclaimer is not a license and does not grant any rights to the
|
|
* materials distributed herewith. Except as otherwise provided in a valid
|
|
* license issued to you by Xilinx, and to the maximum extent permitted by
|
|
* applicable law: (1) THESE MATERIALS ARE MADE AVAILABLE "AS IS" AND WITH ALL
|
|
* FAULTS, AND XILINX HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS, EXPRESS,
|
|
* IMPLIED, OR STATUTORY, INCLUDING BUT NOT LIMITED TO WARRANTIES OF
|
|
* MERCHANTABILITY, NON-INFRINGEMENT, OR FITNESS FOR ANY PARTICULAR PURPOSE;
|
|
* and (2) Xilinx shall not be liable (whether in contract or tort, including
|
|
* negligence, or under any other theory of liability) for any loss or damage
|
|
* of any kind or nature related to, arising under or in connection with these
|
|
* materials, including for any direct, or any indirect, special, incidental,
|
|
* or consequential loss or damage (including loss of data, profits, goodwill,
|
|
* or any type of loss or damage suffered as a result of any action brought by
|
|
* a third party) even if such damage or loss was reasonably foreseeable or
|
|
* Xilinx had been advised of the possibility of the same.
|
|
*
|
|
* CRITICAL APPLICATIONS
|
|
* Xilinx products are not designed or intended to be fail-safe, or for use in
|
|
* any application requiring fail-safe performance, such as life-support or
|
|
* safety devices or systems, Class III medical devices, nuclear facilities,
|
|
* applications related to the deployment of airbags, or any other applications
|
|
* that could lead to death, personal injury, or severe property or
|
|
* environmental damage (individually and collectively, "Critical
|
|
* Applications"). Customer assumes the sole risk and liability of any use of
|
|
* Xilinx products in Critical Applications, subject only to applicable laws
|
|
* and regulations governing limitations on product liability.
|
|
*
|
|
* THIS COPYRIGHT NOTICE AND DISCLAIMER MUST BE RETAINED AS PART OF THIS FILE
|
|
* AT ALL TIMES.
|
|
*
|
|
******************************************************************************/
|
|
/*****************************************************************************/
|
|
/**
|
|
* @file xusb_keyboard.c
|
|
*
|
|
* This file contains an example for USB keyboard.
|
|
*
|
|
* @note
|
|
* - The example is tested on ML403 and ML507 evaluation boards.
|
|
* The push buttons SW3,SW4,SW5 and SW7 on the ML403 evaluation
|
|
* board are used in the example for the key action of the USB
|
|
* keyboard.The push buttons SW10, SW11, SW12, SW13 and SW14
|
|
* are used on the ML507 board.
|
|
* The example sends a character from a fixed sequence of
|
|
* characters from the device as and when any of the SW3 or SW4
|
|
* or SW5 and SW7 push button is pressed. The fixed sequence of
|
|
* characters is XILINX USB KEYBOARD DEMO. The SW6 push button
|
|
* switch is used to complete the test. SW14 is used on ML507
|
|
* board to complete the test.
|
|
* - The GPIO device has to be added to the hardware design so that
|
|
* the push buttons on the evaluation board could be used. If we
|
|
* enable the debug statements in the xusb_cp9.c file, we must
|
|
* add the UARTLite core to the hardware design. Debug messages
|
|
* can be enabled by defining the constant XUSB_DEBUG,
|
|
* - To run this example, the evaluation board is to be connected
|
|
* to a windows Host PC over the USB port.
|
|
* - The example configures the USB device for endpoint 0 and
|
|
* endpoint 1. Endpoint 0 is the control endpoint and is
|
|
* configured for a maximum packet length of 64 bytes. End point
|
|
* 1 is configured for INTERRUPT IN transactions and the maximum
|
|
* packet size is configured as 16 bytes.
|
|
* - The USB keyboard example code has to be compiled along with
|
|
* the xusb_cp9.c file. The xusb_cp9.c file contains all the USB
|
|
* enumeration related functions. To compile the code for USB
|
|
* keyboard example, the constant definitions HID_DEVICES
|
|
* and USB_KEYBOARD are to be defined and the definitions the
|
|
* constants USB_MOUSE and MASS_STORAGE_DEVICE are to be
|
|
* undefined. These definitions can be found in the xusb_types.h
|
|
* file.
|
|
*
|
|
* <pre>
|
|
* MODIFICATION HISTORY:
|
|
*
|
|
* Ver Who Date Changes
|
|
* ----- ---- -----------------------------------------------------------------
|
|
* 1.00a hvm 5/31/07 First release
|
|
* 3.00a hvm 11/18/09 Updated to use HAL processor APIs.
|
|
* XUsb_mReadReg is renamed to XUsb_ReadReg and
|
|
* XUsb_mWriteReg is renamed to XUsb_WriteReg.
|
|
* 4.00a hvm 08/11/11 Updated the code in gpio isr to increment the index by 4 as
|
|
* a dummy byte is added in the Message variable in keyboard.h
|
|
* file to handle the address alignment issue.
|
|
* 4.02a bss 11/01/11 Modified UsbIfIntrHandler function to unconditionally
|
|
* reset when USB reset is asserted (CR 627574).
|
|
*
|
|
* </pre>
|
|
*****************************************************************************/
|
|
/***************************** Include Files *********************************/
|
|
|
|
#include "xusb.h"
|
|
#include "xintc.h"
|
|
#include "xusb_keyboard.h"
|
|
#include "stdio.h"
|
|
#include "xgpio.h"
|
|
#include "xil_exception.h"
|
|
|
|
/************************** Constant Definitions *****************************/
|
|
|
|
#define USB_DEVICE_ID XPAR_USB_0_DEVICE_ID
|
|
#define INTC_DEVICE_ID XPAR_INTC_0_DEVICE_ID
|
|
#define USB_INTR XPAR_INTC_0_USB_0_VEC_ID
|
|
|
|
|
|
/*
|
|
* The GPIO_DEVICE_ID is to be modified as per the name provided during the
|
|
* system design. Default name for default system built for ML403 board is
|
|
* XPAR_PUSH_BUTTONS_POSITION_DEVICE_ID and the one for ML507 board is
|
|
* XPAR_PUSH_BUTTONS_5BIT_DEVICE_ID.
|
|
*
|
|
*/
|
|
#define GPIO_DEVICE_ID XPAR_PUSH_BUTTONS_4BITS_DEVICE_ID
|
|
#define INTC_GPIO_INTERRUPT_ID XPAR_INTC_0_GPIO_0_VEC_ID
|
|
|
|
#define GPIO_ALL_BUTTONS 0x1F /* The GPIO bits 0 to 4. */
|
|
#define EXIT_BUTTON 0x0010 /* The GPIO_SW_C on the ML403 board */
|
|
#define BUTTON_CHANNEL 1 /* Channel 1 of the GPIO Device */
|
|
#define BUTTON_INTERRUPT XGPIO_IR_CH1_MASK /* Channel 1 Interrupt Mask */
|
|
|
|
|
|
/************************** Function Prototypes ******************************/
|
|
|
|
int UsbKbdExample(u16 UsbId, u16 GpioId);
|
|
static int SetupInterruptSystem(XUsb *UsbPtr, XGpio *GpioPtr);
|
|
|
|
/************************** Variable Definitions *****************************/
|
|
|
|
static XUsb UsbInstance; /* The instance of the USB device */
|
|
static XGpio Gpio; /* The Instance of the GPIO Driver */
|
|
|
|
XUsb_Config *UsbConfigPtr; /* Pointer to the USB config structure */
|
|
XGpio_Config *GpioConfigPtr; /* Pointer to the GPIO config structure */
|
|
|
|
XIntc InterruptController; /* Instance of the Interrupt Controller */
|
|
volatile int StopTest = FALSE;
|
|
|
|
int MaxMsgLength;
|
|
|
|
/****************************************************************************/
|
|
/**
|
|
* This function is the main function of the USB Keyboard example.
|
|
*
|
|
* @param None.
|
|
*
|
|
* @return
|
|
* - XST_SUCCESS if successful,
|
|
* - XST_FAILURE if unsuccessful.
|
|
*
|
|
* @note None.
|
|
*
|
|
*
|
|
*****************************************************************************/
|
|
int main(void)
|
|
{
|
|
int Status;
|
|
|
|
Status = UsbKbdExample(USB_DEVICE_ID, GPIO_DEVICE_ID);
|
|
|
|
if (Status != XST_SUCCESS) {
|
|
return XST_FAILURE;
|
|
}
|
|
|
|
return XST_SUCCESS;
|
|
|
|
}
|
|
|
|
/*****************************************************************************/
|
|
/**
|
|
* This function implements the USB Keyboard example.
|
|
* The Key board action can be seen on the PC as and when any of the push
|
|
* buttons SW3 or SW4 or SW5 or SW7 on the ML403 evaluation board is pressed.
|
|
*
|
|
* @param UsbId is the USB device id.
|
|
* @param GpioId is the GPIO device id.
|
|
*
|
|
* @return
|
|
* - XST_SUCCESS if successful.
|
|
* - XST_FAILURE if test fails.
|
|
* @note None.
|
|
*
|
|
*****************************************************************************/
|
|
int UsbKbdExample(u16 UsbId, u16 GpioId)
|
|
{
|
|
int Status;
|
|
|
|
|
|
|
|
/*
|
|
* Initialize the GPIO driver.
|
|
*/
|
|
GpioConfigPtr = XGpio_LookupConfig(GpioId);
|
|
if (GpioConfigPtr == NULL) {
|
|
return XST_FAILURE;
|
|
}
|
|
|
|
/*
|
|
* 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 = XGpio_CfgInitialize(&Gpio,
|
|
GpioConfigPtr,
|
|
GpioConfigPtr->BaseAddress);
|
|
|
|
if (Status != XST_SUCCESS) {
|
|
return XST_FAILURE;
|
|
}
|
|
|
|
|
|
/*
|
|
* Initialize the USB driver.
|
|
*/
|
|
UsbConfigPtr = XUsb_LookupConfig(UsbId);
|
|
if (UsbConfigPtr == NULL) {
|
|
return XST_FAILURE;
|
|
}
|
|
|
|
Status = XUsb_CfgInitialize(&UsbInstance,
|
|
UsbConfigPtr,
|
|
UsbConfigPtr->BaseAddress);
|
|
if (XST_SUCCESS != Status) {
|
|
return XST_FAILURE;
|
|
}
|
|
|
|
/*
|
|
* Initialize the USB instance as required for the keyboard
|
|
* example.
|
|
*/
|
|
InitUsbInterface(&UsbInstance);
|
|
|
|
XGpio_SetDataDirection(&Gpio, BUTTON_CHANNEL, GPIO_ALL_BUTTONS);
|
|
MaxMsgLength = sizeof(Message);
|
|
|
|
/*
|
|
* Set our function address to 0 which is the unenumerated state.
|
|
*/
|
|
Status = XUsb_SetDeviceAddress(&UsbInstance, 0);
|
|
if (XST_SUCCESS != Status) {
|
|
return XST_FAILURE;
|
|
}
|
|
|
|
/*
|
|
* Setup the interrupt handlers.
|
|
*/
|
|
XUsb_IntrSetHandler(&UsbInstance, (void *) UsbIfIntrHandler,
|
|
&UsbInstance);
|
|
|
|
XUsb_EpSetHandler(&UsbInstance, 0,
|
|
(XUsb_EpHandlerFunc *) Ep0IntrHandler, &UsbInstance);
|
|
|
|
XUsb_EpSetHandler(&UsbInstance, 1,
|
|
(XUsb_EpHandlerFunc *) Ep1IntrHandler, &UsbInstance);
|
|
|
|
/*
|
|
* Setup the interrupt system.
|
|
*/
|
|
Status = SetupInterruptSystem(&UsbInstance, &Gpio);
|
|
if (Status != XST_SUCCESS) {
|
|
return XST_FAILURE;
|
|
}
|
|
|
|
/*
|
|
* Enable the interrupts.
|
|
*/
|
|
XUsb_IntrEnable(&UsbInstance, XUSB_STATUS_GLOBAL_INTR_MASK |
|
|
XUSB_STATUS_RESET_MASK |
|
|
XUSB_STATUS_SUSPEND_MASK |
|
|
XUSB_STATUS_DISCONNECT_MASK |
|
|
XUSB_STATUS_FIFO_BUFF_RDY_MASK |
|
|
XUSB_STATUS_FIFO_BUFF_FREE_MASK |
|
|
XUSB_STATUS_EP0_BUFF1_COMP_MASK |
|
|
XUSB_STATUS_EP1_BUFF1_COMP_MASK |
|
|
XUSB_STATUS_EP1_BUFF2_COMP_MASK );
|
|
|
|
XUsb_Start(&UsbInstance);
|
|
|
|
/*
|
|
* Set the device configuration to unenumerated state.
|
|
*/
|
|
UsbInstance.DeviceConfig.CurrentConfiguration = 0;
|
|
|
|
|
|
while (StopTest == FALSE){
|
|
/*
|
|
* Stop the test if the Stop key is pressed
|
|
*/
|
|
}
|
|
|
|
return XST_SUCCESS;
|
|
}
|
|
|
|
/*****************************************************************************/
|
|
/**
|
|
* This function initializes the USB device for Keyboard example. The following
|
|
* is the configuration.
|
|
* - EP0 : CONTROL end point, Bidirectional, Packet size 64 bytes.
|
|
* - EP1 : NON_ISOCHRONOUS, INTERRUPT_IN, packet size of 16 bytes.
|
|
*
|
|
* @param InstancePtr is a pointer to the XUsb instance.
|
|
*
|
|
* @return None.
|
|
*
|
|
* @note None.
|
|
*
|
|
******************************************************************************/
|
|
void InitUsbInterface(XUsb * InstancePtr)
|
|
{
|
|
|
|
XUsb_DeviceConfig DeviceConfig;
|
|
|
|
/*
|
|
* Setup Endpoint 0.
|
|
*/
|
|
DeviceConfig.Ep[0].RamBase = 0x22;
|
|
DeviceConfig.Ep[0].Size = 0x40;
|
|
DeviceConfig.Ep[0].EpType = 0;
|
|
DeviceConfig.Ep[0].OutIn = XUSB_EP_DIRECTION_OUT;
|
|
|
|
|
|
/*
|
|
* Setup Endpoint 1.
|
|
*/
|
|
DeviceConfig.Ep[1].RamBase = 0x1000;
|
|
DeviceConfig.Ep[1].Size = 0x10;
|
|
DeviceConfig.Ep[1].EpType = 0;
|
|
DeviceConfig.Ep[1].OutIn = XUSB_EP_DIRECTION_IN;
|
|
|
|
DeviceConfig.NumEndpoints = 2;
|
|
|
|
/*
|
|
* Initialize the device configuration.
|
|
*/
|
|
XUsb_ConfigureDevice(InstancePtr, &DeviceConfig);
|
|
|
|
XUsb_EpEnable(InstancePtr, 0);
|
|
XUsb_EpEnable(InstancePtr, 1);
|
|
|
|
|
|
MaxControlSize = 64;
|
|
|
|
/*
|
|
* Store the actual RAM address offset in the device structure, so as to
|
|
* avoid the multiplication during processing.
|
|
*/
|
|
InstancePtr->DeviceConfig.Ep[1].RamBase <<= 2;
|
|
|
|
}
|
|
|
|
/*****************************************************************************/
|
|
/**
|
|
* This function is the interrupt handler for the USB keyboard example
|
|
*
|
|
* @param CallBackRef is the callback reference passed from the interrupt
|
|
* handler, which in our case is a pointer to the driver instance.
|
|
* @param IntrStatus is a bit mask indicating pending interrupts.
|
|
*
|
|
* @return None.
|
|
*
|
|
* @note Each interrupt source is disabled upon reception. This is to
|
|
* avoid the repetitive occurrence of the same event. This is done
|
|
* because these event conditions exist for few milliseconds.
|
|
*
|
|
******************************************************************************/
|
|
void UsbIfIntrHandler(void *CallBackRef, u32 IntrStatus)
|
|
{
|
|
|
|
XUsb *InstancePtr;
|
|
u8 Index;
|
|
|
|
InstancePtr = (XUsb *) CallBackRef;
|
|
|
|
if (IntrStatus & XUSB_STATUS_RESET_MASK) {
|
|
|
|
XUsb_Stop(InstancePtr);
|
|
InstancePtr->DeviceConfig.CurrentConfiguration = 0;
|
|
InstancePtr->DeviceConfig.Status = XUSB_RESET;
|
|
for (Index = 0; Index < 3; Index++) {
|
|
XUsb_WriteReg(InstancePtr->Config.BaseAddress,
|
|
InstancePtr->
|
|
EndPointOffset[Index], 0);
|
|
}
|
|
/*
|
|
* Re-initialize the device and set the device address
|
|
* to 0 and re-start the device.
|
|
*/
|
|
InitUsbInterface(InstancePtr);
|
|
XUsb_SetDeviceAddress(InstancePtr, 0);
|
|
XUsb_Start(InstancePtr);
|
|
|
|
XUsb_IntrDisable(InstancePtr, XUSB_STATUS_RESET_MASK);
|
|
XUsb_IntrEnable(InstancePtr, (XUSB_STATUS_DISCONNECT_MASK |
|
|
XUSB_STATUS_SUSPEND_MASK));
|
|
}
|
|
if (IntrStatus & XUSB_STATUS_SUSPEND_MASK) {
|
|
/*
|
|
* Process the suspend event.
|
|
*/
|
|
XUsb_IntrDisable(InstancePtr, XUSB_STATUS_SUSPEND_MASK);
|
|
XUsb_IntrEnable(InstancePtr, (XUSB_STATUS_RESET_MASK |
|
|
XUSB_STATUS_DISCONNECT_MASK));
|
|
}
|
|
|
|
}
|
|
|
|
/*****************************************************************************/
|
|
/**
|
|
* This function is the interrupt handler for the USB End point Zero events.
|
|
*
|
|
*
|
|
* @param CallBackRef is the callback reference passed from the interrupt.
|
|
* handler, which in our case is a pointer to the driver instance.
|
|
* @param EpNum is the end point number.
|
|
* @param IntrStatus is a bit mask indicating pending interrupts.
|
|
*
|
|
* @return None.
|
|
*
|
|
* @note EpNum is not used in this function as the handler is attached
|
|
* specific to end point zero. This parameter is useful when a
|
|
* single handler is used for processing all end point interrupts.
|
|
*
|
|
******************************************************************************/
|
|
void Ep0IntrHandler(void *CallBackRef, u8 EpNum, u32 IntrStatus)
|
|
{
|
|
|
|
XUsb *InstancePtr;
|
|
int SetupRequest;
|
|
|
|
InstancePtr = (XUsb *) CallBackRef;
|
|
|
|
/*
|
|
* Process the end point zero buffer interrupt.
|
|
*/
|
|
if (IntrStatus & XUSB_BUFFREADY_EP0_BUFF_MASK) {
|
|
if (IntrStatus & XUSB_STATUS_SETUP_PACKET_MASK) {
|
|
/*
|
|
* Received a setup packet. Execute the chapter 9
|
|
* command.
|
|
*/
|
|
XUsb_IntrEnable(InstancePtr,
|
|
(XUSB_STATUS_DISCONNECT_MASK |
|
|
XUSB_STATUS_SUSPEND_MASK |
|
|
XUSB_STATUS_RESET_MASK));
|
|
SetupRequest = Chapter9(InstancePtr);
|
|
if (SetupRequest != XST_SUCCESS) {
|
|
switch(SetupRequest){
|
|
case 0x9:
|
|
break;
|
|
case 0x10:
|
|
break;
|
|
/*
|
|
* Unsupported command. Stall
|
|
* the end point.
|
|
*/
|
|
default:
|
|
XUsb_EpStall(InstancePtr, 0);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
else if (IntrStatus & XUSB_STATUS_FIFO_BUFF_RDY_MASK) {
|
|
EP0ProcessOutToken(InstancePtr);
|
|
}
|
|
else if (IntrStatus & XUSB_STATUS_FIFO_BUFF_FREE_MASK) {
|
|
EP0ProcessInToken(InstancePtr);
|
|
}
|
|
}
|
|
}
|
|
|
|
/*****************************************************************************/
|
|
/**
|
|
* This function is the interrupt handler for the USB End point one events.
|
|
*
|
|
* @param CallBackRef is the callback reference passed from the interrupt
|
|
* handler, which in our case is a pointer to the driver instance.
|
|
* @param EpNum is the end point number.
|
|
* @param IntrStatus is a bit mask indicating pending interrupts.
|
|
*
|
|
* @return None.
|
|
*
|
|
* @note EpNum is not used in this function as the handler is attached
|
|
* specific to end point one. This parameter is useful when a
|
|
* single handler is used for processing all end point interrupts.
|
|
*
|
|
******************************************************************************/
|
|
void Ep1IntrHandler(void *CallBackRef, u8 EpNum, u32 IntrStatus)
|
|
{
|
|
|
|
XUsb *InstancePtr;
|
|
|
|
InstancePtr = (XUsb *) CallBackRef;
|
|
|
|
/*
|
|
* Process the End point 1 interrupts.
|
|
*/
|
|
if (IntrStatus & XUSB_BUFFREADY_EP1_BUFF1_MASK) {
|
|
InstancePtr->DeviceConfig.Ep[1].Buffer0Ready = 0;
|
|
}
|
|
|
|
if (IntrStatus & XUSB_BUFFREADY_EP1_BUFF2_MASK) {
|
|
InstancePtr->DeviceConfig.Ep[1].Buffer1Ready = 0;
|
|
}
|
|
|
|
}
|
|
|
|
/****************************************************************************/
|
|
/**
|
|
* This function is the Interrupt Service Routine for the GPIO device.
|
|
*
|
|
* This function will detect the push button on the board has changed state
|
|
* and then prepare data to be sent to the host.
|
|
*
|
|
* @param InstancePtr is the GPIO component to operate on. It is a void
|
|
* pointer and in this case will be a pointer to the GPIO
|
|
* instance.
|
|
*
|
|
* @return None.
|
|
*
|
|
* @note None.
|
|
*
|
|
*****************************************************************************/
|
|
void GpioIsr(void *InstancePtr)
|
|
{
|
|
XGpio *GpioPtr = (XGpio *)InstancePtr;
|
|
u32 Buttons;
|
|
u32 ButtonsChanged = 0;
|
|
static u32 PreviousButtons;
|
|
int Status;
|
|
static int Index = 0;
|
|
u8 NoKeyData[3]= {0,0,0};
|
|
|
|
|
|
/*
|
|
* Disable the GPIO interrupt.
|
|
*/
|
|
XGpio_InterruptDisable(GpioPtr, BUTTON_INTERRUPT);
|
|
|
|
|
|
/*
|
|
* There should not be any other GPIO interrupts occurring other than
|
|
* the the button changes.
|
|
*/
|
|
if ((XGpio_InterruptGetStatus(GpioPtr) & BUTTON_INTERRUPT) !=
|
|
BUTTON_INTERRUPT) {
|
|
return;
|
|
}
|
|
|
|
/*
|
|
* Read state of push buttons and determine which ones changed
|
|
* states from the previous interrupt. Save a copy of the buttons
|
|
* for the next interrupt.
|
|
*/
|
|
Buttons = (XGpio_DiscreteRead(GpioPtr, BUTTON_CHANNEL) & 0x1F) ;
|
|
ButtonsChanged = Buttons ^ PreviousButtons;
|
|
PreviousButtons = Buttons;
|
|
|
|
/*
|
|
* Handle all button state changes that occurred since the last
|
|
* interrupt.
|
|
*/
|
|
while (ButtonsChanged != 0) {
|
|
/*
|
|
* Determine which button changed state and then get
|
|
* the current state of the associated LED.
|
|
*/
|
|
if (ButtonsChanged & 0x1F){
|
|
|
|
if (ButtonsChanged & EXIT_BUTTON){
|
|
StopTest = TRUE;
|
|
break;
|
|
}
|
|
|
|
if (Index >= MaxMsgLength){
|
|
Index = 0;
|
|
}
|
|
XUsb_EpDataSend(&UsbInstance, 1,
|
|
(unsigned char *)&Message[Index], 3);
|
|
|
|
/*
|
|
* Send no key status to PC.
|
|
*/
|
|
Status = XUsb_EpDataSend(&UsbInstance, 1,
|
|
(unsigned char *)&NoKeyData[0], 3);
|
|
if (Status == XST_SUCCESS) {
|
|
Index += 4;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
|
|
/*
|
|
* Clear the interrupt such that it is no longer pending in the GPIO.
|
|
*/
|
|
(void)XGpio_InterruptClear(GpioPtr, BUTTON_INTERRUPT);
|
|
|
|
/*
|
|
* Enable the GPIO interrupt.
|
|
*/
|
|
XGpio_InterruptEnable(GpioPtr, BUTTON_INTERRUPT);
|
|
|
|
}
|
|
|
|
/******************************************************************************/
|
|
/**
|
|
*
|
|
* This function sets up the interrupt system such that interrupts can occur
|
|
* for the USB and GPIO. This function is application specific since the actual
|
|
* system may or may not have an interrupt controller. The USB and GPIO could be
|
|
* directly connected to a processor without an interrupt controller. The
|
|
* user should modify this function to fit the application.
|
|
*
|
|
* @param UsbPtr is a pointer to the instance of the USB device.
|
|
* @param GpioPtr is a pointer to the instance of the GPIO device.
|
|
*
|
|
* @return
|
|
* - XST_SUCCESS if successful.
|
|
* - XST_FAILURE. if it fails.
|
|
*
|
|
* @note None.
|
|
*
|
|
*******************************************************************************/
|
|
static int SetupInterruptSystem(XUsb *UsbPtr, XGpio *GpioPtr)
|
|
{
|
|
int Status;
|
|
|
|
/*
|
|
* Initialize the interrupt controller driver.
|
|
*/
|
|
Status = XIntc_Initialize(&InterruptController, INTC_DEVICE_ID);
|
|
if (Status != XST_SUCCESS) {
|
|
return XST_FAILURE;
|
|
}
|
|
|
|
|
|
/*
|
|
* Connect a device driver handler that will be called when an interrupt
|
|
* for the USB device occurs.
|
|
*/
|
|
Status = XIntc_Connect(&InterruptController, USB_INTR,
|
|
(XInterruptHandler) XUsb_IntrHandler,
|
|
(void *) UsbPtr);
|
|
if (Status != XST_SUCCESS) {
|
|
return XST_FAILURE;
|
|
}
|
|
|
|
/*
|
|
* Connect a device driver handler that will be called when an interrupt
|
|
* for the GPIO device occurs.
|
|
*/
|
|
XIntc_Connect(&InterruptController, INTC_GPIO_INTERRUPT_ID,
|
|
(XInterruptHandler)GpioIsr,(void *) GpioPtr);
|
|
|
|
|
|
/*
|
|
* Start the interrupt controller such that interrupts are enabled for
|
|
* all devices that cause interrupts, specific real mode so that
|
|
* the USB and GPIO can cause interrupts through the interrupt
|
|
* controller.
|
|
*/
|
|
Status = XIntc_Start(&InterruptController, XIN_REAL_MODE);
|
|
if (Status != XST_SUCCESS) {
|
|
return XST_FAILURE;
|
|
}
|
|
|
|
/*
|
|
* Enable the GPIO channel interrupts so that push button can be
|
|
* detected and enable interrupts for the GPIO device.
|
|
*/
|
|
XGpio_InterruptEnable(&Gpio, BUTTON_INTERRUPT);
|
|
XGpio_InterruptGlobalEnable(GpioPtr);
|
|
|
|
/*
|
|
* Enable the interrupt vector at the interrupt controller.
|
|
*/
|
|
XIntc_Enable(&InterruptController, INTC_GPIO_INTERRUPT_ID);
|
|
|
|
/*
|
|
* Enable the interrupt for the USB.
|
|
*/
|
|
XIntc_Enable(&InterruptController, USB_INTR);
|
|
|
|
/*
|
|
* Initialize the exception table.
|
|
*/
|
|
Xil_ExceptionInit();
|
|
|
|
/*
|
|
* Register the interrupt controller handler with the exception table.
|
|
*/
|
|
Xil_ExceptionRegisterHandler(XIL_EXCEPTION_ID_INT,
|
|
(Xil_ExceptionHandler)XIntc_InterruptHandler,
|
|
&InterruptController);
|
|
|
|
/*
|
|
* Enable non-critical exceptions.
|
|
*/
|
|
Xil_ExceptionEnable();
|
|
|
|
return XST_SUCCESS;
|
|
}
|
|
|
|
|