//############################################################################# // FILE: usbhostenum.c // TITLE: Device enumeration code for the USB host library //############################################################################# // $TI Release: F2837xD Support Library v190 $ // $Release Date: Mon Feb 1 16:51:57 CST 2016 $ // $Copyright: // Copyright (C) 2013-2016 Texas Instruments Incorporated - http://www.ti.com/ // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions // are met: // // Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. // // Redistributions in binary form must reproduce the above copyright // notice, this list of conditions and the following disclaimer in the // documentation and/or other materials provided with the // distribution. // // Neither the name of Texas Instruments Incorporated nor the names of // its contributors may be used to endorse or promote products derived // from this software without specific prior written permission. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // $ //############################################################################# /* * Copyright (c) 2000 Jeroen Ruigrok van der Werven * All rights reserved. * * Copyright (c) 2014-2014 Texas Instruments Incorporated * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * * $FreeBSD: release/10.0.0/include/stdbool.h 228878 2011-12-25 20:15:41Z ed $ */ /*****************************************************************************/ /* STDINT.H */ /* */ /* Copyright (c) 2002 Texas Instruments Incorporated */ /* http://www.ti.com/ */ /* */ /* Redistribution and use in source and binary forms, with or without */ /* modification, are permitted provided that the following conditions */ /* are met: */ /* */ /* Redistributions of source code must retain the above copyright */ /* notice, this list of conditions and the following disclaimer. */ /* */ /* Redistributions in binary form must reproduce the above copyright */ /* notice, this list of conditions and the following disclaimer in */ /* the documentation and/or other materials provided with the */ /* distribution. */ /* */ /* Neither the name of Texas Instruments Incorporated nor the names */ /* of its contributors may be used to endorse or promote products */ /* derived from this software without specific prior written */ /* permission. */ /* */ /* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS */ /* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT */ /* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR */ /* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT */ /* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, */ /* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT */ /* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, */ /* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY */ /* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT */ /* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE */ /* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /* */ /*****************************************************************************/ /*****************************************************************************/ /* _STDINT40.H */ /* */ /* Copyright (c) 2018 Texas Instruments Incorporated */ /* http://www.ti.com/ */ /* */ /* Redistribution and use in source and binary forms, with or without */ /* modification, are permitted provided that the following conditions */ /* are met: */ /* */ /* Redistributions of source code must retain the above copyright */ /* notice, this list of conditions and the following disclaimer. */ /* */ /* Redistributions in binary form must reproduce the above copyright */ /* notice, this list of conditions and the following disclaimer in */ /* the documentation and/or other materials provided with the */ /* distribution. */ /* */ /* Neither the name of Texas Instruments Incorporated nor the names */ /* of its contributors may be used to endorse or promote products */ /* derived from this software without specific prior written */ /* permission. */ /* */ /* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS */ /* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT */ /* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR */ /* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT */ /* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, */ /* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT */ /* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, */ /* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY */ /* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT */ /* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE */ /* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /* */ /*****************************************************************************/ /* According to footnotes in the 1999 C standard, "C++ implementations should define these macros only when __STDC_LIMIT_MACROS is defined before is included." */ /* 7.18.1.1 Exact-width integer types */ typedef int int16_t; typedef unsigned int uint16_t; typedef long int32_t; typedef unsigned long uint32_t; typedef long long int64_t; typedef unsigned long long uint64_t; /* 7.18.1.2 Minimum-width integer types */ typedef int16_t int_least8_t; typedef uint16_t uint_least8_t; typedef int16_t int_least16_t; typedef uint16_t uint_least16_t; typedef int32_t int_least32_t; typedef uint32_t uint_least32_t; typedef int64_t int_least64_t; typedef uint64_t uint_least64_t; /* 7.18.1.3 Fastest minimum-width integer types */ typedef int16_t int_fast8_t; typedef uint16_t uint_fast8_t; typedef int16_t int_fast16_t; typedef uint16_t uint_fast16_t; typedef int32_t int_fast32_t; typedef uint32_t uint_fast32_t; typedef int64_t int_fast64_t; typedef uint64_t uint_fast64_t; /* 7.18.1.4 Integer types capable of holding object pointers */ typedef long intptr_t; typedef unsigned long uintptr_t; /* 7.18.1.5 Greatest-width integer types */ typedef long long intmax_t; typedef unsigned long long uintmax_t; /* According to footnotes in the 1999 C standard, "C++ implementations should define these macros only when __STDC_LIMIT_MACROS is defined before is included." */ /* 7.18.2 Limits of specified width integer types */ /* 7.18.3 Limits of other integer types */ /* 7.18.4.1 Macros for minimum-width integer constants */ /* There is a defect report filed against the C99 standard concerning how the (U)INTN_C macros should be implemented. Please refer to -- http://wwwold.dkuug.dk/JTC1/SC22/WG14/www/docs/dr_209.htm for more information. These macros are implemented according to the suggestion given at this web site. */ /* 7.18.4.2 Macros for greatest-width integer constants */ //########################################################################### // // FILE: hw_ints.h // // TITLE: Definitions of interrupt numbers for use with interrupt.c. // //########################################################################### // $TI Release: F2837xD Support Library v190 $ // $Release Date: Mon Feb 1 16:51:57 CST 2016 $ // $Copyright: Copyright (C) 2013-2016 Texas Instruments Incorporated - // http://www.ti.com/ ALL RIGHTS RESERVED $ //########################################################################### //***************************************************************************** // // PIE Interrupt Numbers // // 0x00FF = PIE Table Row # // 0xFF00 = PIE Table Column # // 0xFFFF0000 = PIE Vector ID // //***************************************************************************** // Lower PIE Group 1 // Lower PIE Group 2 // Lower PIE Group 3 // Lower PIE Group 4 // Lower PIE Group 5 // Lower PIE Group 6 // Lower PIE Group 7 // Lower PIE Group 8 // Lower PIE Group 9 // Lower PIE Group 10 // Lower PIE Group 11 // Lower PIE Group 12 // Upper PIE Group 1 // Upper PIE Group 2 // Upper PIE Group 3 // Upper PIE Group 4 // Upper PIE Group 5 // Upper PIE Group 6 // Upper PIE Group 8 // Upper PIE Group 9 // Upper PIE Group 10 // Upper PIE Group 11 // Upper PIE Group 12 //Workaround for Stellaris code //Workaround for other interrupts //########################################################################### // // FILE: hw_memmap.h // // TITLE: Macros defining the memory map of the C28x. // //########################################################################### // $TI Release: F2837xD Support Library v190 $ // $Release Date: Mon Feb 1 16:51:57 CST 2016 $ // $Copyright: Copyright (C) 2013-2016 Texas Instruments Incorporated - // http://www.ti.com/ ALL RIGHTS RESERVED $ //########################################################################### //***************************************************************************** // // The following are defines for the base address of the memories and // peripherals. // //***************************************************************************** //########################################################################### // // FILE: hw_types.h // // TITLE: Type definitions used in ALL driverlib functions. // //########################################################################### // $TI Release: F2837xD Support Library v190 $ // $Release Date: Mon Feb 1 16:51:57 CST 2016 $ // $Copyright: Copyright (C) 2013-2016 Texas Instruments Incorporated - // http://www.ti.com/ ALL RIGHTS RESERVED $ //########################################################################### //***************************************************************************** // // Define fake 8 bit types for USB related code. // //***************************************************************************** typedef uint16_t uint8_t; typedef int16_t int8_t; //***************************************************************************** // // Macros for hardware access, both direct and via the bit-band region. // //***************************************************************************** //Emulated Bitbanded write //Emulated Bitbanded read //Emulated Bitbanded write //Emulated Bitbanded read //***************************************************************************** // // rom.h - Macros to facilitate calling functions in the ROM. // // Copyright (c) 2007-2012 Texas Instruments Incorporated. All rights reserved. // Software License Agreement // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions // are met: // // Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. // // Redistributions in binary form must reproduce the above copyright // notice, this list of conditions and the following disclaimer in the // documentation and/or other materials provided with the // distribution. // // Neither the name of Texas Instruments Incorporated nor the names of // its contributors may be used to endorse or promote products derived // from this software without specific prior written permission. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // // This is part of revision 9453 of the Stellaris Peripheral Driver Library. // //***************************************************************************** //***************************************************************************** // // rom_map.h - Macros to facilitate calling functions in the ROM when they are // available and in flash otherwise. // // Copyright (c) 2008-2012 Texas Instruments Incorporated. All rights reserved. // Software License Agreement // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions // are met: // // Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. // // Redistributions in binary form must reproduce the above copyright // notice, this list of conditions and the following disclaimer in the // documentation and/or other materials provided with the // distribution. // // Neither the name of Texas Instruments Incorporated nor the names of // its contributors may be used to endorse or promote products derived // from this software without specific prior written permission. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // // This is part of revision 9453 of the Stellaris Peripheral Driver Library. // //***************************************************************************** //***************************************************************************** // // Macros for the ADC API. // //***************************************************************************** //***************************************************************************** // // Macros for the CAN API. // //***************************************************************************** //***************************************************************************** // // Macros for the Comparator API. // //***************************************************************************** //***************************************************************************** // // Macros for the EEPROM API. // //***************************************************************************** //***************************************************************************** // // Macros for the EPI API. // //***************************************************************************** //***************************************************************************** // // Macros for the Ethernet API. // //***************************************************************************** //***************************************************************************** // // Macros for the Fan API. // //***************************************************************************** //***************************************************************************** // // Macros for the Flash API. // //***************************************************************************** //***************************************************************************** // // Macros for the FPU API. // //***************************************************************************** //***************************************************************************** // // Macros for the GPIO API. // //***************************************************************************** //***************************************************************************** // // Macros for the Hibernate API. // //***************************************************************************** //***************************************************************************** // // Macros for the I2C API. // //***************************************************************************** //***************************************************************************** // // Macros for the I2S API. // //***************************************************************************** //***************************************************************************** // // Macros for the Interrupt API. // //***************************************************************************** //***************************************************************************** // // Macros for the LPC API. // //***************************************************************************** //***************************************************************************** // // Macros for the MPU API. // //***************************************************************************** //***************************************************************************** // // Macros for the PECI API. // //***************************************************************************** //***************************************************************************** // // Macros for the PWM API. // //***************************************************************************** //***************************************************************************** // // Macros for the QEI API. // //***************************************************************************** //***************************************************************************** // // Macros for the SMBus API. // //***************************************************************************** //***************************************************************************** // // Macros for the SSI API. // //***************************************************************************** //***************************************************************************** // // Macros for the SysCtl API. // //***************************************************************************** //***************************************************************************** // // Macros for the SysExc API. // //***************************************************************************** //***************************************************************************** // // Macros for the SysTick API. // //***************************************************************************** //***************************************************************************** // // Macros for the Timer API. // //***************************************************************************** //***************************************************************************** // // Macros for the UART API. // //***************************************************************************** //***************************************************************************** // // Macros for the uDMA API. // //***************************************************************************** //***************************************************************************** // // Macros for the USB API. // //***************************************************************************** //***************************************************************************** // // Macros for the Watchdog API. // //***************************************************************************** //***************************************************************************** // // Macros for the Software API. // //***************************************************************************** //########################################################################### // // FILE: debug.h // // TITLE: Stellaris style debug header. Included for compatability. // //########################################################################### // $TI Release: F2837xD Support Library v190 $ // $Release Date: Mon Feb 1 16:51:57 CST 2016 $ // $Copyright: Copyright (C) 2013-2016 Texas Instruments Incorporated - // http://www.ti.com/ ALL RIGHTS RESERVED $ //########################################################################### //***************************************************************************** // // Prototype for the function that is called when an invalid argument is passed // to an API. This is only used when doing a DEBUG build. // //***************************************************************************** extern void __error__(char *pcFilename, unsigned long ulLine); //***************************************************************************** // // The ASSERT macro, which does the actual assertion checking. Typically, this // will be for procedure arguments. // //***************************************************************************** //########################################################################### // // FILE: interrupt.h // // TITLE: Stellaris style wrapper driver for C28x PIE Interrupt Controller. // //########################################################################### // $TI Release: F2837xD Support Library v190 $ // $Release Date: Mon Feb 1 16:51:57 CST 2016 $ // $Copyright: Copyright (C) 2013-2016 Texas Instruments Incorporated - // http://www.ti.com/ ALL RIGHTS RESERVED $ //########################################################################### //***************************************************************************** // // If building with a C++ compiler, make all of the definitions in this header // have a C binding. // //***************************************************************************** //***************************************************************************** // // Prototypes for the APIs. // //***************************************************************************** extern _Bool IntMasterEnable(void); extern _Bool IntMasterDisable(void); extern void IntRegister(uint32_t ui32Interrupt, void (*pfnHandler)(void)); extern void IntUnregister(uint32_t ui32Interrupt); extern void IntEnable(uint32_t ui32Interrupt); extern void IntDisable(uint32_t ui32Interrupt); extern void IntIFRClear(uint16_t ui16Interrupts); //***************************************************************************** // // Mark the end of the C bindings section for C++ compilers. // //***************************************************************************** //########################################################################### // // FILE: sysctl.h // // TITLE: Stellaris style wrapper driver for F2837x system control. // //########################################################################### // $TI Release: F2837xD Support Library v190 $ // $Release Date: Mon Feb 1 16:51:57 CST 2016 $ // $Copyright: Copyright (C) 2013-2016 Texas Instruments Incorporated - // http://www.ti.com/ ALL RIGHTS RESERVED $ //########################################################################### //***************************************************************************** // // If building with a C++ compiler, make all of the definitions in this header // have a C binding. // //***************************************************************************** //***************************************************************************** // //! \addtogroup sysctl_api //! @{ // //***************************************************************************** //***************************************************************************** // //! Defined System Clock Speed (CPU speed). Adjust this to reflect your //! actual clock speed. // //***************************************************************************** //***************************************************************************** // // The following are values that can be passed to the SysCtlClockSet() API as // the ui32Config parameter. // //***************************************************************************** // Only 1 or even values up to 126 are allowed // Only 1 or even values up to 14 are allowed //***************************************************************************** // // The following are values that can be passed to the // SysCtlPeripheralPresent(), SysCtlPeripheralEnable(), // SysCtlPeripheralDisable(), and SysCtlPeripheralReset() APIs as the // ui32Peripheral parameter. The peripherals in the fourth group (upper nibble // is 3) can only be used with the SysCtlPeripheralPresent() API. // //***************************************************************************** //PCLKCR0 //PCLKCR1 //PCLKCR2 //PCLKCR3 //PCLKCR4 //PCLKCR5 //Reserved //PCLKCR6 //PCLKCR7 //PCLKCR8 //PCLKCR9 //PCLKCR10 //PCLKCR11 //PCLKCR12 //PCLKCR13 //PCLKCR14 //PCLKCR15 //Reserved //PCLKCR16 //old //#define SYSCTL_PERIPH_UART_A 0x1 // SCI A //#define SYSCTL_PERIPH_UART_B 0x2 // SCI B //#define SYSCTL_PERIPH_UART_C 0x3 // SCI C //#define SYSCTL_PERIPH_UART_D 0x4 // SCI D // //#define SYSCTL_PERIPH_SPI_A 0x5 // SPI A //#define SYSCTL_PERIPH_SPI_B 0x6 // SPI B //#define SYSCTL_PERIPH_SPI_C 0x7 // SPI C // //#define SYSCTL_PERIPH_MCBSP_A 0x8 // McBSP A //#define SYSCTL_PERIPH_MCBSP_B 0x9 // McBSP B // //#define SYSCTL_PERIPH_DMA 0xA // DMA // //#define SYSCTL_PERIPH_USB0 0xB // USBA //***************************************************************************** // // Prototypes for the APIs. // //***************************************************************************** extern uint32_t SysCtlSRAMSizeGet(void); extern uint32_t SysCtlFlashSizeGet(void); extern void SysCtlPeripheralReset(uint32_t ui32Peripheral); extern void SysCtlPeripheralEnable(uint32_t ui32Peripheral); extern void SysCtlPeripheralDisable(uint32_t ui32Peripheral); extern _Bool SysCtlPeripheralPresent(uint32_t ui32Peripheral); extern void SysCtlDelay(uint32_t ulCount); extern uint32_t SysCtlClockGet(uint32_t u32ClockIn); extern void SysCtlClockSet(uint32_t ui32Config); extern void SysCtlAuxClockSet(uint32_t ui32Config); extern uint32_t SysCtlLowSpeedClockGet(uint32_t u32ClockIn); extern void SysCtlUSBPLLEnable(void); extern void SysCtlUSBPLLDisable(void); //***************************************************************************** // // Close the Doxygen group. //! @} // //**************************************************************************** //***************************************************************************** // // Mark the end of the C bindings section for C++ compilers. // //***************************************************************************** //########################################################################### // // FILE: usb.h // // TITLE: Prototypes for the USB Interface Driver. // //########################################################################### // $TI Release: F2837xD Support Library v190 $ // $Release Date: Mon Feb 1 16:51:57 CST 2016 $ // $Copyright: Copyright (C) 2013-2016 Texas Instruments Incorporated - // http://www.ti.com/ ALL RIGHTS RESERVED $ //########################################################################### //***************************************************************************** // // If building with a C++ compiler, make all of the definitions in this header // have a C binding. // //***************************************************************************** //***************************************************************************** // // The following are defines for the g_usUSBFlags variable // //***************************************************************************** //***************************************************************************** // // The following are values that can be passed to USBIntEnableControl() and // USBIntDisableControl() as the ui32Flags parameter, and are returned from // USBIntStatusControl(). // //***************************************************************************** //***************************************************************************** // // The following are values that can be passed to USBIntEnableEndpoint() and // USBIntDisableEndpoint() as the ui32Flags parameter, and are returned from // USBIntStatusEndpoint(). // //***************************************************************************** //***************************************************************************** // // The following are values that are returned from USBSpeedGet(). // //***************************************************************************** //***************************************************************************** // // The following are values that are returned from USBEndpointStatus(). The // USB_HOST_* values are used when the USB controller is in host mode and the // USB_DEV_* values are used when the USB controller is in device mode. // //***************************************************************************** // (ISOC Mode) // specified timeout period // device // specified timeout period // (ISOC mode) // device // specified timeout period // device // transfer // a full FIFO // to come // Data End seen //***************************************************************************** // // The following are values that can be passed to USBHostEndpointConfig() and // USBDevEndpointConfigSet() as the ui32Flags parameter. // //***************************************************************************** //***************************************************************************** // // The following are values that can be passed to USBHostPwrConfig() as the // ui32Flags parameter. // //***************************************************************************** //***************************************************************************** // // The following are special values that can be passed to // USBHostEndpointConfig() as the ui32NAKPollInterval parameter. // //***************************************************************************** //***************************************************************************** // // This value specifies the maximum size of transfers on endpoint 0 as 64 // bytes. This value is fixed in hardware as the FIFO size for endpoint 0. // //***************************************************************************** //***************************************************************************** // // These values are used to indicate which endpoint to access. // //***************************************************************************** //***************************************************************************** // // These macros allow conversion between 0-based endpoint indices and the // USB_EP_x values required when calling various USB APIs. // //***************************************************************************** //***************************************************************************** // // The following are values that can be passed to USBFIFOConfigSet() as the // ui32FIFOSize parameter. // //***************************************************************************** // (occupying 16 bytes) // (occupying 32 bytes) // (occupying 64 bytes) // (occupying 128 bytes) // (occupying 256 bytes) // (occupying 512 bytes) // (occupying 1024 bytes) // (occupying 2048 bytes) // (occupying 4096 bytes) //***************************************************************************** // // This macro allow conversion from a FIFO size label as defined above to // a number of bytes // //***************************************************************************** //***************************************************************************** // // The following are values that can be passed to USBEndpointDataSend() as the // ui32TransType parameter. // //***************************************************************************** // endpoint 0 in device mode) // 0) // 0) //***************************************************************************** // // The following are values are returned by the USBModeGet function. // //***************************************************************************** // mode. // Device mode. // set. // the cable. // the cable. // the cable Session Valid. // the cable A valid. // the cable. // the cable. // the cable. // the cable. //***************************************************************************** // // Prototypes for the APIs. // //***************************************************************************** extern uint32_t USBDevAddrGet(uint32_t ui32Base); extern void USBDevAddrSet(uint32_t ui32Base, uint32_t ui32Address); extern void USBDevConnect(uint32_t ui32Base); extern void USBDevDisconnect(uint32_t ui32Base); extern void USBDevEndpointConfigSet(uint32_t ui32Base, uint32_t ui32Endpoint, uint32_t ui32MaxPacketSize, uint32_t ui32Flags); extern void USBDevEndpointConfigGet(uint32_t ui32Base, uint32_t ui32Endpoint, uint32_t *pui32MaxPacketSize, uint32_t *pui32Flags); extern void USBDevEndpointDataAck(uint32_t ui32Base, uint32_t ui32Endpoint, _Bool bIsLastPacket); extern void USBDevEndpointStall(uint32_t ui32Base, uint32_t ui32Endpoint, uint32_t ui32Flags); extern void USBDevEndpointStallClear(uint32_t ui32Base, uint32_t ui32Endpoint, uint32_t ui32Flags); extern void USBDevEndpointStatusClear(uint32_t ui32Base, uint32_t ui32Endpoint, uint32_t ui32Flags); extern uint32_t USBEndpointDataAvail(uint32_t ui32Base, uint32_t ui32Endpoint); extern void USBEndpointDMAEnable(uint32_t ui32Base, uint32_t ui32Endpoint, uint32_t ui32Flags); extern void USBEndpointDMADisable(uint32_t ui32Base, uint32_t ui32Endpoint, uint32_t ui32Flags); extern void USBEndpointDMAConfigSet(uint32_t ui32Base, uint32_t ui32Endpoint, uint32_t ui32Config); extern int32_t USBEndpointDataGet(uint32_t ui32Base, uint32_t ui32Endpoint, uint8_t *pui8Data, uint32_t *pui32Size); extern int32_t USBEndpointDataPut(uint32_t ui32Base, uint32_t ui32Endpoint, uint8_t *pui8Data, uint32_t ui32Size); extern int32_t USBEndpointDataSend(uint32_t ui32Base, uint32_t ui32Endpoint, uint32_t ui32TransType); extern void USBEndpointDataToggleClear(uint32_t ui32Base, uint32_t ui32Endpoint, uint32_t ui32Flags); extern void USBEndpointPacketCountSet(uint32_t ui32Base, uint32_t ui32Endpoint, uint32_t ui32Count); extern uint32_t USBEndpointStatus(uint32_t ui32Base, uint32_t ui32Endpoint); extern uint32_t USBFIFOAddrGet(uint32_t ui32Base, uint32_t ui32Endpoint); extern void USBFIFOConfigGet(uint32_t ui32Base, uint32_t ui32Endpoint, uint32_t *pui32FIFOAddress, uint32_t *pui32FIFOSize, uint32_t ui32Flags); extern void USBFIFOConfigSet(uint32_t ui32Base, uint32_t ui32Endpoint, uint32_t ui32FIFOAddress, uint32_t ui32FIFOSize, uint32_t ui32Flags); extern void USBFIFOFlush(uint32_t ui32Base, uint32_t ui32Endpoint, uint32_t ui32Flags); extern uint32_t USBFrameNumberGet(uint32_t ui32Base); extern uint32_t USBHostAddrGet(uint32_t ui32Base, uint32_t ui32Endpoint, uint32_t ui32Flags); extern void USBHostAddrSet(uint32_t ui32Base, uint32_t ui32Endpoint, uint32_t ui32Addr, uint32_t ui32Flags); extern void USBHostEndpointConfig(uint32_t ui32Base, uint32_t ui32Endpoint, uint32_t ui32MaxPacketSize, uint32_t ui32NAKPollInterval, uint32_t ui32TargetEndpoint, uint32_t ui32Flags); extern void USBHostEndpointDataAck(uint32_t ui32Base, uint32_t ui32Endpoint); extern void USBHostEndpointDataToggle(uint32_t ui32Base, uint32_t ui32Endpoint, _Bool bDataToggle, uint32_t ui32Flags); extern void USBHostEndpointStatusClear(uint32_t ui32Base, uint32_t ui32Endpoint, uint32_t ui32Flags); extern uint32_t USBHostHubAddrGet(uint32_t ui32Base, uint32_t ui32Endpoint, uint32_t ui32Flags); extern void USBHostHubAddrSet(uint32_t ui32Base, uint32_t ui32Endpoint, uint32_t ui32Addr, uint32_t ui32Flags); extern void USBHostPwrDisable(uint32_t ui32Base); extern void USBHostPwrEnable(uint32_t ui32Base); extern void USBHostPwrConfig(uint32_t ui32Base, uint32_t ui32Flags); extern void USBHostPwrFaultDisable(uint32_t ui32Base); extern void USBHostPwrFaultEnable(uint32_t ui32Base); extern void USBHostRequestIN(uint32_t ui32Base, uint32_t ui32Endpoint); extern void USBHostRequestINClear(uint32_t ui32Base, uint32_t ui32Endpoint); extern void USBHostRequestStatus(uint32_t ui32Base); extern void USBHostReset(uint32_t ui32Base, _Bool bStart); extern void USBHostResume(uint32_t ui32Base, _Bool bStart); extern uint32_t USBHostSpeedGet(uint32_t ui32Base); extern void USBHostSuspend(uint32_t ui32Base); extern void USBIntDisableControl(uint32_t ui32Base, uint32_t ui32IntFlags); extern void USBIntEnableControl(uint32_t ui32Base, uint32_t ui32IntFlags); extern uint32_t USBIntStatus(uint32_t ui32Base, uint32_t *ui32IntStatusEP); extern uint32_t USBIntStatusControl(uint32_t ui32Base); extern void USBIntDisableEndpoint(uint32_t ui32Base, uint32_t ui32IntFlags); extern void USBIntEnableEndpoint(uint32_t ui32Base, uint32_t ui32IntFlags); extern uint32_t USBIntStatusEndpoint(uint32_t ui32Base); extern void USBIntRegister(uint32_t ui32Base, void (*pfnHandler)(void)); extern void USBIntUnregister(uint32_t ui32Base); extern void USBOTGSessionRequest(uint32_t ui32Base, _Bool bStart); extern uint32_t USBModeGet(uint32_t ui32Base); extern void USBEndpointDMAChannel(uint32_t ui32Base, uint32_t ui32Endpoint, uint32_t ui32Channel); extern void USBHostMode(uint32_t ui32Base); extern void USBDevMode(uint32_t ui32Base); extern void USBOTGMode(uint32_t ui32Base); extern void USBPHYPowerOff(uint32_t ui32Base); extern void USBPHYPowerOn(uint32_t ui32Base); extern uint32_t USBNumEndpointsGet(uint32_t ui32Base); //***************************************************************************** // The following are values that can be passed to USBIntEnable() and // USBIntDisable() as the ulIntFlags parameter, and are returned from // USBIntStatus(). //***************************************************************************** //***************************************************************************** // // Mark the end of the C bindings section for C++ compilers. // //***************************************************************************** //***************************************************************************** // // rtos_bindings.h - Macros ulIntIDended to aid porting of StellarisWare modules // for use with an RTOS. // // Copyright (c) 2012 Texas Instruments Incorporated. All rights reserved. // Software License Agreement // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions // are met: // // Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. // // Redistributions in binary form must reproduce the above copyright // notice, this list of conditions and the following disclaimer in the // documentation and/or other materials provided with the // distribution. // // Neither the name of Texas Instruments Incorporated nor the names of // its contributors may be used to endorse or promote products derived // from this software without specific prior written permission. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // // This is part of revision 9453 of the Stellaris Peripheral Driver Library. // //***************************************************************************** //***************************************************************************** // // When no RTOS is in use, the follow macros compile to either nothing or a // minimal implementation that works in a bare-metal environment. // // Each of these macros must be redefined in stellaris_rtos.h if you are using // StellarisWare under an RTOS. // //***************************************************************************** //***************************************************************************** // // A simple macro used to yield within polling loops. In the default, non-RTOS // implementation, this compiles to nothing. // //***************************************************************************** //***************************************************************************** // // A simple macro around the SysCtlDelay function. The parameter is the number // of 3 cycle loops to wait before returning (as for SysCtlDelay). In an RTOS // implementation, this could be replaced with an OS delay call with // appropriate parameter scaling. // //***************************************************************************** //***************************************************************************** // // Wrappers around low level interrupt control functions. For information // on each of these functions, please see the appropriate API documentation // for the DriverLib Interrupt driver. // // The macros defined here represent interrupt-control functions that may be // called from within StellarisWare code. It is expected that application // code will use RTOS-specific functions to control interrupt priority, to // pend interrupts and to perform runtime vector manipulation. As a result, // no macros are defined to wrap any of these functions from interrupt.c. // //***************************************************************************** //############################################################################# // FILE: usblib.h // TITLE: Main header file for the USB Library //############################################################################# // $TI Release: F2837xD Support Library v190 $ // $Release Date: Mon Feb 1 16:51:57 CST 2016 $ // $Copyright: // Copyright (C) 2013-2016 Texas Instruments Incorporated - http://www.ti.com/ // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions // are met: // // Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. // // Redistributions in binary form must reproduce the above copyright // notice, this list of conditions and the following disclaimer in the // documentation and/or other materials provided with the // distribution. // // Neither the name of Texas Instruments Incorporated nor the names of // its contributors may be used to endorse or promote products derived // from this software without specific prior written permission. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // $ //############################################################################# //***************************************************************************** // // If building with a C++ compiler, make all of the definitions in this header // have a C binding. // //***************************************************************************** //***************************************************************************** // // This is the maximum number of devices we can support when in host mode and // using a hub. By default, we support up to 4 devices (plus 1 internally for // the hub itself). // //***************************************************************************** //***************************************************************************** // // This is the maximum number of endpoints supported by the usblib. // //***************************************************************************** //***************************************************************************** // // The following macro allows compiler-independent syntax to be used to // define packed structures. A typical structure definition using these // macros will look similar to the following example: // // #ifdef ewarm // #pragma pack(1) // #endif // // typedef struct _PackedStructName // { // uint32_t ui32FirstField; // int8_t i8CharMember; // uint16_t ui16Short; // } // PACKED tPackedStructName; // // #ifdef ewarm // #pragma pack() // #endif // // The conditional blocks related to ewarm include the #pragma pack() lines // only if the IAR Embedded Workbench compiler is being used. Unfortunately, // it is not possible to emit a #pragma from within a macro definition so this // must be done explicitly. // //***************************************************************************** //***************************************************************************** // // Assorted language IDs from the document "USB_LANGIDs.pdf" provided by the // USB Implementers' Forum (Version 1.0). // //***************************************************************************** //***************************************************************************** // //! \addtogroup c2000_specific //! @{ // //***************************************************************************** //***************************************************************************** // //! This struct is used to ensure that data passed up from the driver layer //! is interpretted correctly by the protocol stack. This is a workaround //! specifically for C2000 devices. // //***************************************************************************** typedef struct { uint16_t LSB; uint16_t MSB; } usb16_t; //***************************************************************************** // //! This struct is used to ensure that data passed up from the driver layer //! is interpretted correctly by the protocol stack. This is a workaround //! specifically for C2000 devices. // //***************************************************************************** typedef struct { usb16_t LSW; usb16_t MSW; } usb32_t; //***************************************************************************** // //! This define is used to write data to a tShort variable. This is a //! is a workaround specific to C2000 devices. // //***************************************************************************** //***************************************************************************** // //! This define is used to read data from a tShort variable. This is a //! is a workaround specific to C2000 devices. // //***************************************************************************** //***************************************************************************** // //! This define is used to write data to a tLong variable. This is a //! is a workaround specific to C2000 devices. // //***************************************************************************** //***************************************************************************** // //! This define is used to read data from a tLong variable. This is a //! is a workaround specific to C2000 devices. // //***************************************************************************** //***************************************************************************** // // Close the c2000_specific group. //! @} // //***************************************************************************** //***************************************************************************** // //! \addtogroup usbchap9_src //! @{ // //***************************************************************************** //***************************************************************************** // // Note: // // Structure definitions which are derived directly from the USB specification // use field names from the specification. Since a somewhat different version // of Hungarian prefix notation is used from the standard, beware of making // assumptions about field sizes based on the field prefix when using // these structures. Of particular note is the difference in the meaning of // the 'i' prefix. In USB structures, this indicates a single byte index // whereas in other code, this is an integer or enumeration variable. // //***************************************************************************** //***************************************************************************** // // All structures defined in this section of the header require byte packing of // fields. This is usually accomplished using the PACKED macro but, for IAR // Embedded Workbench, this requires a pragma. // //***************************************************************************** //***************************************************************************** // // Definitions related to standard USB device requests (sections 9.3 & 9.4) // //***************************************************************************** //***************************************************************************** // //! The standard USB request header as defined in section 9.3 of the USB 2.0 //! specification. // //***************************************************************************** typedef struct { // //! Determines the type and direction of the request. // uint8_t bmRequestType; // //! Identifies the specific request being made. // uint8_t bRequest; // //! Word-sized field that varies according to the request. // usb16_t wValue; // //! Word-sized field that varies according to the request; typically used //! to pass an index or offset. // usb16_t wIndex; // //! The number of bytes to transfer if there is a data stage to the //! request. // usb16_t wLength; } tUSBRequest; //***************************************************************************** // // The following defines are used with the bmRequestType member of tUSBRequest. // // Request types have 3 bit fields: // 4:0 - Is the recipient type. // 6:5 - Is the request type. // 7 - Is the direction of the request. // //***************************************************************************** //***************************************************************************** // // Standard USB requests IDs used in the bRequest field of tUSBRequest. // //***************************************************************************** //***************************************************************************** // // Data returned from a USBREQ_GET_STATUS request to a device. // //***************************************************************************** //***************************************************************************** // // Feature Selectors (tUSBRequest.wValue) passed on USBREQ_CLEAR_FEATURE and // USBREQ_SET_FEATURE. // //***************************************************************************** //***************************************************************************** // // Endpoint Selectors (tUSBRequest.wIndex) passed on USBREQ_CLEAR_FEATURE, // USBREQ_SET_FEATURE and USBREQ_GET_STATUS. // //***************************************************************************** //***************************************************************************** // // Standard USB descriptor types. These values are passed in the upper bytes // of tUSBRequest.wValue on USBREQ_GET_DESCRIPTOR and also appear in the // bDescriptorType field of standard USB descriptors. // //***************************************************************************** //***************************************************************************** // // Definitions related to USB descriptors (sections 9.5 & 9.6) // //***************************************************************************** //***************************************************************************** // //! This structure describes a generic descriptor header. These fields are to //! be found at the beginning of all valid USB descriptors. // //***************************************************************************** typedef struct { // //! The length of this descriptor (including this length byte) expressed //! in bytes. // uint8_t bLength; // //! The type identifier of the descriptor whose information follows. For //! standard descriptors, this field could contain, for example, //! USB_DTYPE_DEVICE to identify a device descriptor or USB_DTYPE_ENDPOINT //! to identify an endpoint descriptor. // uint8_t bDescriptorType; } tDescriptorHeader; //***************************************************************************** // //! This structure describes the USB device descriptor as defined in USB //! 2.0 specification section 9.6.1. // //***************************************************************************** typedef struct { // //! The length of this descriptor in bytes. All device descriptors are //! 18 bytes long. // uint8_t bLength; // //! The type of the descriptor. For a device descriptor, this will be //! USB_DTYPE_DEVICE (1). // uint8_t bDescriptorType; // //! The USB Specification Release Number in BCD format. For USB 2.0, this //! will be 0x0200. // usb16_t bcdUSB; // //! The device class code. // uint8_t bDeviceClass; // //! The device subclass code. This value qualifies the value found in the //! bDeviceClass field. // uint8_t bDeviceSubClass; // //! The device protocol code. This value is qualified by the values of //! bDeviceClass and bDeviceSubClass. // uint8_t bDeviceProtocol; // //! The maximum packet size for endpoint zero. Valid values are 8, 16, 32 //! and 64. // uint8_t bMaxPacketSize0; // //! The device Vendor ID (VID) as assigned by the USB-IF. // usb16_t idVendor; // //! The device Product ID (PID) as assigned by the manufacturer. // usb16_t idProduct; // //! The device release number in BCD format. // usb16_t bcdDevice; // //! The index of a string descriptor describing the manufacturer. // uint8_t iManufacturer; // //! The index of a string descriptor describing the product. // uint8_t iProduct; // //! The index of a string descriptor describing the device's serial //! number. // uint8_t iSerialNumber; // //! The number of possible configurations offered by the device. This //! field indicates the number of distinct configuration descriptors that //! the device offers. // uint8_t bNumConfigurations; } tDeviceDescriptor; //***************************************************************************** // // USB Device Class codes used in the tDeviceDescriptor.bDeviceClass field. // Definitions for the bDeviceSubClass and bDeviceProtocol fields are device // specific and can be found in the appropriate device class header files. // //***************************************************************************** //***************************************************************************** // // Generic values for undefined subclass and protocol. // //***************************************************************************** //***************************************************************************** // // The following are the miscellaneous subclass values. // //***************************************************************************** //***************************************************************************** // // These following are miscellaneous protocol values. // //***************************************************************************** //***************************************************************************** // // These following are hub protocol values. // //***************************************************************************** //***************************************************************************** // //! This structure describes the USB device qualifier descriptor as defined in //! the USB 2.0 specification, section 9.6.2. // //***************************************************************************** typedef struct { // //! The length of this descriptor in bytes. All device qualifier //! descriptors are 10 bytes long. // uint8_t bLength; // //! The type of the descriptor. For a device descriptor, this will be //! USB_DTYPE_DEVICE_QUAL (6). // uint8_t bDescriptorType; // //! The USB Specification Release Number in BCD format. For USB 2.0, this //! will be 0x0200. // usb16_t bcdUSB; // //! The device class code. // uint8_t bDeviceClass; // //! The device subclass code. This value qualifies the value found in the //! bDeviceClass field. // uint8_t bDeviceSubClass; // //! The device protocol code. This value is qualified by the values of //! bDeviceClass and bDeviceSubClass. // uint8_t bDeviceProtocol; // //! The maximum packet size for endpoint zero when operating at a speed //! other than high speed. // uint8_t bMaxPacketSize0; // //! The number of other-speed configurations supported. // uint8_t bNumConfigurations; // //! Reserved for future use. Must be set to zero. // uint8_t bReserved; } tDeviceQualifierDescriptor; //***************************************************************************** // //! This structure describes the USB configuration descriptor as defined in //! USB 2.0 specification section 9.6.3. This structure also applies to the //! USB other speed configuration descriptor defined in section 9.6.4. // //***************************************************************************** typedef struct { // //! The length of this descriptor in bytes. All configuration descriptors //! are 9 bytes long. // uint8_t bLength; // //! The type of the descriptor. For a configuration descriptor, this will //! be USB_DTYPE_CONFIGURATION (2). // uint8_t bDescriptorType; // //! The total length of data returned for this configuration. This //! includes the combined length of all descriptors (configuration, //! interface, endpoint and class- or vendor-specific) returned for this //! configuration. // usb16_t wTotalLength; // //! The number of interface supported by this configuration. // uint8_t bNumInterfaces; // //! The value used as an argument to the SetConfiguration standard request //! to select this configuration. // uint8_t bConfigurationValue; // //! The index of a string descriptor describing this configuration. // uint8_t iConfiguration; // //! Attributes of this configuration. // uint8_t bmAttributes; // //! The maximum power consumption of the USB device from the bus in this //! configuration when the device is fully operational. This is expressed //! in units of 2mA so, for example, 100 represents 200mA. // uint8_t bMaxPower; } tConfigDescriptor; //***************************************************************************** // // Flags used in constructing the value assigned to the field // tConfigDescriptor.bmAttributes. Note that bit 7 is reserved and must be set // to 1. // //***************************************************************************** //***************************************************************************** // //! This structure describes the USB interface descriptor as defined in USB //! 2.0 specification section 9.6.5. // //***************************************************************************** typedef struct { // //! The length of this descriptor in bytes. All interface descriptors //! are 9 bytes long. // uint8_t bLength; // //! The type of the descriptor. For an interface descriptor, this will //! be USB_DTYPE_INTERFACE (4). // uint8_t bDescriptorType; // //! The number of this interface. This is a zero based index into the //! array of concurrent interfaces supported by this configuration. // uint8_t bInterfaceNumber; // //! The value used to select this alternate setting for the interface //! defined in bInterfaceNumber. // uint8_t bAlternateSetting; // //! The number of endpoints used by this interface (excluding endpoint //! zero). // uint8_t bNumEndpoints; // //! The interface class code as assigned by the USB-IF. // uint8_t bInterfaceClass; // //! The interface subclass code as assigned by the USB-IF. // uint8_t bInterfaceSubClass; // //! The interface protocol code as assigned by the USB-IF. // uint8_t bInterfaceProtocol; // //! The index of a string descriptor describing this interface. // uint8_t iInterface; } tInterfaceDescriptor; //***************************************************************************** // //! This structure describes the USB endpoint descriptor as defined in USB //! 2.0 specification section 9.6.6. // //***************************************************************************** typedef struct { // //! The length of this descriptor in bytes. All endpoint descriptors //! are 7 bytes long. // uint8_t bLength; // //! The type of the descriptor. For an endpoint descriptor, this will //! be USB_DTYPE_ENDPOINT (5). // uint8_t bDescriptorType; // //! The address of the endpoint. This field contains the endpoint number //! ORed with flag USB_EP_DESC_OUT or USB_EP_DESC_IN to indicate the //! endpoint direction. // uint8_t bEndpointAddress; // //! The endpoint transfer type, USB_EP_ATTR_CONTROL, USB_EP_ATTR_ISOC, //! USB_EP_ATTR_BULK or USB_EP_ATTR_INT and, if isochronous, additional //! flags indicating usage type and synchronization method. // uint8_t bmAttributes; // //! The maximum packet size this endpoint is capable of sending or //! receiving when this configuration is selected. For high speed //! isochronous or interrupt endpoints, bits 11 and 12 are used to //! pass additional information. // usb16_t wMaxPacketSize; // //! The polling interval for data transfers expressed in frames or //! micro frames depending upon the operating speed. // uint8_t bInterval; } tEndpointDescriptor; //***************************************************************************** // // Flags used in constructing the value assigned to the field // tEndpointDescriptor.bEndpointAddress. // //***************************************************************************** //***************************************************************************** // // Mask used to extract the maximum packet size (in bytes) from the // wMaxPacketSize field of the endpoint descriptor. // //***************************************************************************** //***************************************************************************** // // Endpoint attributes used in tEndpointDescriptor.bmAttributes. // //***************************************************************************** //***************************************************************************** // //! This structure describes the USB string descriptor for index 0 as defined //! in USB 2.0 specification section 9.6.7. Note that the number of language //! IDs is variable and can be determined by examining bLength. The number of //! language IDs present in the descriptor is given by ((bLength - 2) / 2). // //***************************************************************************** typedef struct { // //! The length of this descriptor in bytes. This value will vary //! depending upon the number of language codes provided in the descriptor. // uint8_t bLength; // //! The type of the descriptor. For a string descriptor, this will be //! USB_DTYPE_STRING (3). // uint8_t bDescriptorType; // //! The language code (LANGID) for the first supported language. Note that //! this descriptor may support multiple languages, in which case, the //! number of elements in the wLANGID array will increase and bLength will //! be updated accordingly. // usb16_t wLANGID[1]; } tString0Descriptor; //***************************************************************************** // //! This structure describes the USB string descriptor for all string indexes //! other than 0 as defined in USB 2.0 specification section 9.6.7. // //***************************************************************************** typedef struct { // //! The length of this descriptor in bytes. This value will be 2 greater //! than the number of bytes comprising the UNICODE string that the //! descriptor contains. // uint8_t bLength; // //! The type of the descriptor. For a string descriptor, this will be //! USB_DTYPE_STRING (3). // uint8_t bDescriptorType; // //! The first byte of the UNICODE string. This string is not NULL //! terminated. Its length (in bytes) can be computed by subtracting 2 //! from the value in the bLength field. // uint8_t bString; } tStringDescriptor; //***************************************************************************** // //! Write a 16-bit value to a USB descriptor block. //! //! \param ui16Value is the 16-bit value to write to the descriptor. //! //! This helper macro is used in descriptor definitions to write two-byte //! values. Since the configuration descriptor contains all interface and //! endpoint descriptors in a contiguous block of memory, these descriptors are //! typically defined using an array of bytes rather than as packed structures. //! //! \return Not a function. // //***************************************************************************** //***************************************************************************** // //! Write a 24-bit value to a USB descriptor block. //! //! \param ui32Value is the 24-bit value that to write to the descriptor. //! //! This helper macro is used in descriptor definitions to write three-byte //! values. Since the configuration descriptor contains all interface and //! endpoint descriptors in a contiguous block of memory, these descriptors are //! typically defined using an array of bytes rather than as packed structures. //! //! \return Not a function. // //***************************************************************************** //***************************************************************************** // //! Write a 32-bit value to a USB descriptor block. //! //! \param ui32Value is the 32-bit value that to write to the descriptor. //! //! This helper macro is used in descriptor definitions to write four-byte //! values. Since the configuration descriptor contains all interface and //! endpoint descriptors in a contiguous block of memory, these descriptors are //! typically defined using an array of bytes rather than as packed structures. //! //! \return Not a function. // //***************************************************************************** //***************************************************************************** // //! Traverse to the next USB descriptor in a block. //! //! \param ptr points to the first byte of a descriptor in a block of //! USB descriptors. //! //! This macro aids in traversing lists of descriptors by returning a pointer //! to the next descriptor in the list given a pointer to the current one. //! //! \return Returns a pointer to the next descriptor in the block following //! \e ptr. //! //***************************************************************************** //***************************************************************************** // // Return to default packing when using the IAR Embedded Workbench compiler. // //***************************************************************************** //***************************************************************************** // // Close the usbchap9_src Doxygen group. //! @} // //***************************************************************************** //***************************************************************************** // //! \addtogroup device_api //! @{ // //***************************************************************************** //***************************************************************************** // // Function prototype for any standard USB request. // //***************************************************************************** typedef void (* tStdRequest)(void *pvInstance, tUSBRequest *pUSBRequest); //***************************************************************************** // // Data callback for receiving data from an endpoint. // //***************************************************************************** typedef void (* tInfoCallback)(void *pvInstance, uint32_t ui32Info); //***************************************************************************** // // Callback made to indicate that an interface alternate setting change has // occurred. // //***************************************************************************** typedef void (* tInterfaceCallback)(void *pvInstance, uint8_t ui8InterfaceNum, uint8_t ui8AlternateSetting); //***************************************************************************** // // Generic interrupt handler callbacks. // //***************************************************************************** typedef void (* tUSBIntHandler)(void *pvInstance); //***************************************************************************** // // Interrupt handler callbacks that have status information. // //***************************************************************************** typedef void (* tUSBEPIntHandler)(void *pvInstance, uint32_t ui32Status); //***************************************************************************** // // Generic handler callbacks that are used when the callers needs to call into // an instance of class. // //***************************************************************************** typedef void (* tUSBDeviceHandler)(void *pvInstance, uint32_t ui32Request, void *pvRequestData); //***************************************************************************** // //! USB event handler functions used during enumeration and operation of the //! device stack. // //***************************************************************************** typedef struct { // //! This callback is made whenever the USB host requests a non-standard //! descriptor from the device. // tStdRequest pfnGetDescriptor; // //! This callback is made whenever the USB host makes a non-standard //! request. // tStdRequest pfnRequestHandler; // //! This callback is made in response to a SetInterface request from the //! host. // tInterfaceCallback pfnInterfaceChange; // //! This callback is made in response to a SetConfiguration request from //! the host. // tInfoCallback pfnConfigChange; // //! This callback is made when data has been received following to a call //! to USBDCDRequestDataEP0. // tInfoCallback pfnDataReceived; // //! This callback is made when data has been transmitted following a call //! to USBDCDSendDataEP0. // tInfoCallback pfnDataSent; // //! This callback is made when a USB reset is detected. // tUSBIntHandler pfnResetHandler; // //! This callback is made when the bus has been inactive long enough to //! trigger a suspend condition. // tUSBIntHandler pfnSuspendHandler; // //! This is called when resume signaling is detected. // tUSBIntHandler pfnResumeHandler; // //! This callback is made when the device is disconnected from the USB bus. // tUSBIntHandler pfnDisconnectHandler; // //! This callback is made to inform the device of activity on all endpoints //! other than endpoint zero. // tUSBEPIntHandler pfnEndpointHandler; // //! This generic handler is provided to allow requests based on //! a given instance to be passed into a device. This is commonly used //! by a top level composite device that is using multiple instances of //! a class. // tUSBDeviceHandler pfnDeviceHandler; } tCustomHandlers; //***************************************************************************** // //! This structure defines a contiguous block of data which contains a group //! of descriptors that form part of a configuration descriptor for a device. //! It is assumed that a config section contains only whole descriptors. It is //! not valid to split a single descriptor across multiple sections. //! //***************************************************************************** typedef struct { // //! The number of bytes of descriptor data pointed to by pui8Data. // uint16_t ui16Size; // //! A pointer to a block of data containing an integral number of //! USB descriptors which form part of a larger configuration descriptor. // const uint8_t *pui8Data; } tConfigSection; //***************************************************************************** // //! This is the top level structure defining a USB device configuration //! descriptor. A configuration descriptor contains a collection of device- //! specific descriptors in addition to the basic config, interface and //! endpoint descriptors. To allow flexibility in constructing the //! configuration, the descriptor is described in terms of a list of data //! blocks. The first block must contain the configuration descriptor itself //! and the following blocks are appended to this in order to produce the //! full descriptor sent to the host in response to a GetDescriptor request //! for the configuration descriptor. //! //***************************************************************************** typedef struct { // //! The number of sections comprising the full descriptor for this //! configuration. // uint8_t ui8NumSections; // //! A pointer to an array of ui8NumSections section pointers which must //! be concatenated to form the configuration descriptor. // const tConfigSection * const *psSections; } tConfigHeader; //***************************************************************************** // // Close the Doxygen group. //! @} // //***************************************************************************** //***************************************************************************** // //! \addtogroup general_usblib_api //! @{ // //***************************************************************************** //***************************************************************************** // // Predeclare of the DMA instance structure. // //***************************************************************************** typedef struct tUSBDMAInstance tUSBDMAInstance; //***************************************************************************** // // USB descriptor parsing functions found in usbdesc.c // //***************************************************************************** //***************************************************************************** // //! The USB_DESC_ANY label is used as a wild card in several of the descriptor //! parsing APIs to determine whether or not particular search criteria should //! be ignored. // //***************************************************************************** extern uint32_t USBDescGetNum(tDescriptorHeader *psDesc, uint32_t ui32Size, uint32_t ui32Type); extern tDescriptorHeader *USBDescGet(tDescriptorHeader *psDesc, uint32_t ui32Size, uint32_t ui32Type, uint32_t ui32Index); extern uint32_t USBDescGetNumAlternateInterfaces(tConfigDescriptor *psConfig, uint8_t ui8InterfaceNumber); extern tInterfaceDescriptor *USBDescGetInterface(tConfigDescriptor *psConfig, uint32_t ui32Index, uint32_t ui32AltCfg); extern tEndpointDescriptor * USBDescGetInterfaceEndpoint(tInterfaceDescriptor *psInterface, uint32_t ui32Index, uint32_t ui32Size); //***************************************************************************** // //! The operating mode required by the USB library client. This type is used //! by applications which wish to be able to switch between host and device //! modes by calling the USBStackModeSet() API. // //****************global************************************************************* typedef enum { //USB_FIFO_SZ_1024 //! Operate in USB device mode with active monitoring of VBUS and the //! ID pin must be pulled to a logic high value. // eUSBModeDevice = 0, // //! Operate in USB host mode with active monitoring of VBUS and the ID pin //! must be pulled to a logic low value. // eUSBModeHost, // //! Operate as an On-The-Go device which requires both VBUS and ID to be //! connected directly to the USB controller from the USB connector. // eUSBModeOTG, // //! A marker indicating that no USB mode has yet been set by the //! application. // eUSBModeNone, // //! Force host mode so that the VBUS and ID pins are not used or monitored //! by the USB controller. // eUSBModeForceHost, // //! Forcing device mode so that the VBUS and ID pins are not used or //! monitored by the USB controller. // eUSBModeForceDevice, } tUSBMode; //***************************************************************************** // // A pointer to a USB mode callback function. This function is called by the // USB library to indicate to the application which operating mode it should // use, host or device. // //***************************************************************************** typedef void (*tUSBModeCallback)(uint32_t ui32Index, tUSBMode iMode); //***************************************************************************** // //! USB callback function. //! //! \param pvCBData is the callback pointer associated with the instance //! generating the callback. This is a value provided by the client during //! initialization of the instance making the callback. //! \param ui32Event is the identifier of the asynchronous event which is being //! notified to the client. //! \param ui32MsgParam is an event-specific parameter. //! \param pvMsgData is an event-specific data pointer. //! //! A function pointer provided to the USB layer by the application //! which will be called to notify it of all asynchronous events relating to //! data transmission or reception. This callback is used by device class //! drivers and host pipe functions. //! //! \return Returns an event-dependent value. // //***************************************************************************** typedef uint32_t (* tUSBCallback)(void *pvCBData, uint32_t ui32Event, uint32_t ui32MsgParam, void *pvMsgData); //***************************************************************************** // // Error sources reported via USB_EVENT_ERROR. // //***************************************************************************** // //! The host received an invalid PID in a transaction. // // //! The host did not receive a response from a device. // // //! The host received a stall on an IN endpoint. // // //! The host detected a CRC or bit-stuffing error (isochronous mode). // // //! The host received NAK on an IN endpoint for longer than the specified //! timeout period (interrupt, bulk and control modes). // // //! The host failed to communicate with a device via an IN endpoint. // // //! The host receive FIFO is full. // // //! The host received NAK on an OUT endpoint for longer than the specified //! timeout period (bulk, interrupt and control modes). // // //! The host did not receive a response from a device (isochronous mode). // // //! The host received a stall on an OUT endpoint. // // //! The host failed to communicate with a device via an OUT endpoint. // // //! The host received NAK on endpoint 0 for longer than the configured //! timeout. // // //! The host failed to communicate with a device via an endpoint zero. // // //! The device detected a CRC error in received data. // // //! The device was unable to receive a packet from the host since the receive //! FIFO is full. // // //! The device receive FIFO is full. // //***************************************************************************** // // Close the general_usblib_api Doxygen group. //! @} // //***************************************************************************** //***************************************************************************** // //! \addtogroup usblib_events //! @{ // //***************************************************************************** //***************************************************************************** // //! This structure is used to return generic event based information to an //! application. The following events are currently supported: //! USB_EVENT_CONNECTED, USB_EVENT_DISCONNECTED, USB_EVENT_POWER_FAULT, //! USB_EVENT_POWER_FAULT, USB_EVENT_POWER_ENABLE, //! USB_EVENT_POWER_DISABLE and USB_EVENT_SOF. // //***************************************************************************** typedef struct { // //! One of the USB_EVENT_ values. // uint32_t ui32Event; // //! The caller supplied instance value that is passed to event handlers. // uint32_t ui32Instance; } tEventInfo; //***************************************************************************** // // Base identifiers for groups of USB events. These are used by both the // device class drivers and host layer. // // USB_CLASS_EVENT_BASE is the lowest identifier that should be used for // a class-specific event. Individual event bases are defined for each // of the supported device class drivers. Events with IDs between // USB_EVENT_BASE and USB_CLASS_EVENT_BASE are reserved for stack use. // //***************************************************************************** //***************************************************************************** // // Event base identifiers for the various device classes supported in host // and device modes. // The first 0x800 values of a range are reserved for the device specific // messages and the second 0x800 values of a range are used for the host // specific messages for a given class. // //***************************************************************************** //***************************************************************************** // // General events supported by device classes and host pipes. // //***************************************************************************** // //! The device is now attached to a USB host and ready to begin sending //! and receiving data (used by device classes only). // // //! The device has been disconnected from the USB host (used by device classes //! only). //! //! \note In device mode, the USB_EVENT_DISCONNECTED will not be reported if //! the MCU's PB1/USB0VBUS pin is connected to a fixed +5 Volts rather than //! directly to the VBUS pin on the USB connector. // // //! Data has been received and is in the buffer provided or is ready to be //! read from the FIFO. // // //! This event is sent by a lower layer to inquire about the amount of //! unprocessed data buffered in the layers above. It is used in cases //! where a low level driver needs to ensure that all preceding data has //! been processed prior to performing some action or making some notification. //! Clients receiving this event should return the number of bytes of data //! that are unprocessed or 0 if no outstanding data remains. // // //! This event is sent by a lower layer supporting DMA to request a buffer in //! which the next received packet may be stored. The \e ui32MsgValue //! parameter indicates the maximum size of packet that can be received in this //! channel and \e pvMsgData points to storage which should be written with the //! returned buffer pointer. The return value from the callback should be the //! size of the buffer allocated (which may be less than the maximum size //! passed in \e ui32MsgValue if the client knows that fewer bytes are expected //! to be received) or 0 if no buffer is being returned. // // //! Data has been sent and acknowledged. If this event is received via the //! USB buffer callback, the \e ui32MsgValue parameter indicates the number of //! bytes from the transmit buffer that have been successfully transmitted //! and acknowledged. // // //! An error has been reported on the channel or pipe. The \e ui32MsgValue //! parameter indicates the source(s) of the error and is the logical OR //! combination of "USBERR_" flags defined below. // // //! The bus has entered suspend state. // // //! The bus has left suspend state. // // //! A scheduler event has occurred. // // //! A device or host has detected a stall condition. // // //! The host detected a power fault condition. // // //! The controller has detected a A-Side cable and needs power applied This is //! only generated on OTG parts if automatic power control is disabled. // // //! The controller needs power removed, This is only generated on OTG parts //! if automatic power control is disabled. // // //! This define is used with a device class's pfnDeviceHandler handler function //! to indicate that the USB library has changed the interface number. This //! event is typically due to the class being included in a composite device. //! //! The \e pvInstance is a pointer to an instance of the device being accessed. //! //! The \e ui32Request is USB_EVENT_COMP_IFACE_CHANGE. //! //! The \e pvRequestData is a pointer to a two byte array where the first value //! is the old interface number and the second is the new interface number. // // //! This define is used with a device class's pfnDeviceHandler handler function //! to indicate that the USB library has changed the endpoint number. This //! event is typically due to the class being included in a composite device. //! //! The \e pvInstance is a pointer to an instance of the device being accessed. //! //! The \e ui32Request is USB_EVENT_COMP_EP_CHANGE. //! //! The \e pvRequestData is a pointer to a two byte array where the first value //! is the old endpoint number and the second is the new endpoint number. The //! endpoint numbers should be exactly as USB specification defines them and //! bit 7 set indicates an IN endpoint and bit 7 clear indicates an OUT //! endpoint. // // //! This define is used with a device class's pfnDeviceHandler handler function //! to indicate that the USB library has changed the string index number for a //! string. This event is typically due to the class being included in a //! composite device. //! //! The \e pvInstance is a pointer to an instance of the device being accessed. //! //! The \e ui32Request is USB_EVENT_COMP_STR_CHANGE. //! //! The \e pvRequestData is a pointer to a two byte array where the first value //! is the old string index and the second is the new string index. // // //! This define is used with a device class's pfnDeviceHandler handler function //! to indicate that the USB library has changed the configuration descriptor. //! This allows the class to make final adjustments to the configuration //! descriptor. This event is typically due to the class being included in a //! composite device. //! //! The \e pvInstance is a pointer to an instance of the device being accessed. //! //! The \e ui32Request is USB_EVENT_COMP_CONFIG. //! //! The \e pvRequestData is a pointer to the beginning of the configuration //! descriptor for the device instance. // // //! An unknown device is now attached to a USB host. This value is only valid //! for the generic event handler and not other device handlers. It is //! useful for applications that want to know when an unknown device is //! connected and what the class is of the unknown device. //! //! The \e ui32Instance is actually the class of the unsupported //! device that was connected. // // //! A start of frame event has occurred. This event is disabled by default //! and must be enabled via a call from the application to USBHCDEventEnable(). // //***************************************************************************** // // Close the usblib_events Doxygen group. //! @} // //***************************************************************************** //***************************************************************************** // //! \addtogroup usblib_buffer_api //! @{ // //***************************************************************************** //***************************************************************************** // //! A function pointer type which describes either a class driver packet read //! or packet write function (both have the same prototype) to the USB //! buffer object. // //***************************************************************************** typedef uint32_t (* tUSBPacketTransfer)(void *pvHandle, uint8_t *pi8Data, uint32_t ui32Length, _Bool bLast); //***************************************************************************** // //! A function pointer type which describes either a class driver transmit //! or receive packet available function (both have the same prototype) to the //! USB buffer object. // //***************************************************************************** typedef uint32_t (* tUSBPacketAvailable)(void *pvHandle); //***************************************************************************** // //! The number of bytes of workspace that each USB buffer object requires. //! This workspace memory is provided to the buffer on USBBufferInit() in //! the \e pvWorkspace field of the \e tUSBBuffer structure. // //***************************************************************************** //***************************************************************************** // //! The structure used by the application to initialize a buffer object that //! will provide buffered access to either a transmit or receive channel. // //***************************************************************************** typedef struct { // //! This field sets the mode of the buffer. If true, the buffer //! operates as a transmit buffer and supports calls to USBBufferWrite //! by the client. If false, the buffer operates as a receive buffer //! and supports calls to USBBufferRead. // _Bool bTransmitBuffer; // //! A pointer to the callback function which will be called to notify //! the application of all asynchronous events related to the operation //! of the buffer. // tUSBCallback pfnCallback; // //! A pointer that the buffer will pass back to the client in the //! first parameter of all callbacks related to this instance. // void *pvCBData; // //! The function which should be called to transmit a packet of data //! in transmit mode or receive a packet in receive mode. // tUSBPacketTransfer pfnTransfer; // //! The function which should be called to determine if the endpoint is //! ready to accept a new packet for transmission in transmit mode or //! to determine the size of the buffer required to read a packet in //! receive mode. // tUSBPacketAvailable pfnAvailable; // //! The handle to pass to the low level function pointers //! provided in the pfnTransfer and pfnAvailable members. For USB device //! use, this is the psDevice parameter required by the relevant device //! class driver APIs. For USB host use, this is the pipe identifier //! returned by USBHCDPipeAlloc. // void *pvHandle; // //! A pointer to memory to be used as the ring buffer for this //! instance. // uint8_t *pui8Buffer; // //! The size, in bytes, of the buffer pointed to by pi8Buffer. // uint32_t ui32BufferSize; // //! A pointer to USB_BUFFER_WORKSPACE_SIZE bytes of RAM that the buffer //! object can use for workspace. // void *pvWorkspace; } tUSBBuffer; //***************************************************************************** // //! The structure used for encapsulating all the items associated with a //! ring buffer. // //***************************************************************************** typedef struct { // //! The ring buffer size. // uint32_t ui32Size; // //! The ring buffer write index. // volatile uint32_t ui32WriteIndex; // //! The ring buffer read index. // volatile uint32_t ui32ReadIndex; // //! The ring buffer. // uint8_t *pui8Buf; } tUSBRingBufObject; //***************************************************************************** // // Close the Doxygen group. //! @} // //***************************************************************************** //***************************************************************************** // // USB buffer API function prototypes. // //***************************************************************************** extern const tUSBBuffer *USBBufferInit(const tUSBBuffer *psBuffer); extern void USBBufferZeroLengthPacketInsert(const tUSBBuffer *psBuffer, _Bool bSendZLP); extern void USBBufferInfoGet(const tUSBBuffer *psBuffer, tUSBRingBufObject *psRingBuf); extern void *USBBufferCallbackDataSet(tUSBBuffer *psBuffer, void *pvCBData); extern uint32_t USBBufferWrite(const tUSBBuffer *psBuffer, const uint8_t *pui8Data, uint32_t ui32Length); extern void USBBufferDataWritten(const tUSBBuffer *psBuffer, uint32_t ui32Length); extern void USBBufferDataRemoved(const tUSBBuffer *psBuffer, uint32_t ui32Length); extern void USBBufferFlush(const tUSBBuffer *psBuffer); extern uint32_t USBBufferRead(const tUSBBuffer *psBuffer, uint8_t *pui8Data, uint32_t ui32Length); extern uint32_t USBBufferDataAvailable(const tUSBBuffer *psBuffer); extern uint32_t USBBufferSpaceAvailable(const tUSBBuffer *psBuffer); extern uint32_t USBBufferEventCallback(void *pvCBData, uint32_t ui32Event, uint32_t ui32MsgValue, void *pvMsgData); extern _Bool USBRingBufFull(tUSBRingBufObject *psUSBRingBuf); extern _Bool USBRingBufEmpty(tUSBRingBufObject *psUSBRingBuf); extern void USBRingBufFlush(tUSBRingBufObject *psUSBRingBuf); extern uint32_t USBRingBufUsed(tUSBRingBufObject *psUSBRingBuf); extern uint32_t USBRingBufFree(tUSBRingBufObject *psUSBRingBuf); extern uint32_t USBRingBufContigUsed(tUSBRingBufObject *psUSBRingBuf); extern uint32_t USBRingBufContigFree(tUSBRingBufObject *psUSBRingBuf); extern uint32_t USBRingBufSize(tUSBRingBufObject *psUSBRingBuf); extern uint8_t USBRingBufReadOne(tUSBRingBufObject *psUSBRingBuf); extern void USBRingBufRead(tUSBRingBufObject *psUSBRingBuf, uint8_t *pui8Data, uint32_t ui32Length); extern void USBRingBufWriteOne(tUSBRingBufObject *psUSBRingBuf, uint8_t ui8Data); extern void USBRingBufWrite(tUSBRingBufObject *psUSBRingBuf, const uint8_t *pui8Data, uint32_t ui32Length); extern void USBRingBufAdvanceWrite(tUSBRingBufObject *psUSBRingBuf, uint32_t ui32NumBytes); extern void USBRingBufAdvanceRead(tUSBRingBufObject *psUSBRingBuf, uint32_t ui32NumBytes); extern void USBRingBufInit(tUSBRingBufObject *psUSBRingBuf, uint8_t *pui8Buf, uint32_t ui32Size); //***************************************************************************** // // Mode selection and dual mode interrupt steering functions. // //***************************************************************************** extern void USBStackModeSet(uint32_t ui32Index, tUSBMode iUSBMode, tUSBModeCallback pfnCallback); extern void USBDualModeInit(uint32_t ui32Index); extern void USBDualModeTerm(uint32_t ui32Index); extern void USBOTGMain(uint32_t ui32MsTicks); extern void USBOTGPollRate(uint32_t ui32Index, uint32_t ui32PollRate); extern void USBOTGModeInit(uint32_t ui32Index, uint32_t ui32PollRate, void *pHostData, uint32_t ui32HostDataSize); extern void USBOTGModeTerm(uint32_t ui32Index); extern void USB0OTGModeIntHandler(void); extern void USB0DualModeIntHandler(void); //***************************************************************************** // // Mark the end of the C bindings section for C++ compilers. // //***************************************************************************** //############################################################################# // FILE: usblibpriv.h // TITLE: Private header file used to share internal variables and // library. This header MUST NOT be used by application code. //############################################################################# // $TI Release: F2837xD Support Library v190 $ // $Release Date: Mon Feb 1 16:51:57 CST 2016 $ // $Copyright: // Copyright (C) 2013-2016 Texas Instruments Incorporated - http://www.ti.com/ // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions // are met: // // Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. // // Redistributions in binary form must reproduce the above copyright // notice, this list of conditions and the following disclaimer in the // documentation and/or other materials provided with the // distribution. // // Neither the name of Texas Instruments Incorporated nor the names of // its contributors may be used to endorse or promote products derived // from this software without specific prior written permission. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // $ //############################################################################# //***************************************************************************** // // If building with a C++ compiler, make all of the definitions in this header // have a C binding. // //***************************************************************************** //***************************************************************************** // //! \addtogroup usblib_dma_api //! @{ // //***************************************************************************** //***************************************************************************** // // Internal interrupt handlers called from the main vectors in device and // host mode. // //***************************************************************************** extern void USBDeviceIntHandlerInternal(uint32_t ui32Index, uint32_t ui32Status, uint32_t ui32IntStatusEP); extern void USBHostIntHandlerInternal(uint32_t ui32Index, uint32_t ui32Status, uint32_t ui32IntStatusEP); //***************************************************************************** // // The maximum number of tick handlers that can be registered in a system. // //***************************************************************************** //***************************************************************************** // // This value defines the number of SOF ticks that must pass before a call // is made to InternalUSBStartOfFrameTick. The value 5 ensures that the // function is called every 5 milliseconds assuming that SOF interrupts are // enabled and SOF is present. // //***************************************************************************** //***************************************************************************** // // Tick handler function pointer type. // //***************************************************************************** typedef void(* tUSBTickHandler)(void *pvInstance, uint32_t ui32TicksmS); //***************************************************************************** // // Internal functions use to initialize the tick handler and register tick // callbacks. // //***************************************************************************** extern void InternalUSBTickInit(void); extern void InternalUSBTickReset(void); extern int32_t InternalUSBRegisterTickHandler(tUSBTickHandler pfnHandler, void *pvInstance); extern void InternalUSBStartOfFrameTick(uint32_t ui32TicksmS); extern void InternalUSBHCDSendEvent(uint32_t ui32Index, tEventInfo *psEvent, uint32_t ui32EvFlag); //***************************************************************************** // // g_ui32CurrentUSBTick holds the elapsed time in milliseconds since the // tick module was first initialized based on calls to the function // InternalUSBStartOfFrameTick. The granularity is USB_SOF_TICK_DIVIDE // milliseconds. // //***************************************************************************** extern uint32_t g_ui32CurrentUSBTick; //***************************************************************************** // // g_ui32USBSOFCount is a global counter for Start of Frame interrupts. It is // incremented by the low level device- or host-mode interrupt handlers. // //***************************************************************************** extern uint32_t g_ui32USBSOFCount; //***************************************************************************** // // InternalUSBGetTime is a macro which will return the system time in // milliseconds as calculated based on calls to the function // InternalUSBStartOfFrameTick. The granularity is USB_SOF_TICK_DIVIDE // milliseconds. // // Currently, this merely returns the value of a global variable. // //***************************************************************************** //***************************************************************************** // // Macros to convert between USB controller base address and an index. These // are currently trivial but are included to allow for the possibility of // supporting more than one controller in the future. // //***************************************************************************** // // Maximum number of channels for Type 0 USB controllers. // // // Maximum number of channels for all other USB controllers. // //***************************************************************************** // // Values returned by the USBLibDMAChannelStatus() function. // //***************************************************************************** //***************************************************************************** // // DMA endpoint types used with the USBLibDMAChannelAllocate() function. // //***************************************************************************** //***************************************************************************** // // This is the internal instance data for the DMA functions and should not // be modified outside the usbdma.c file. // //***************************************************************************** struct tUSBDMAInstance { uint32_t ui32Base; uint32_t ui32IntNum; uint32_t pui32Config[8]; uint32_t pui32MaxPacketSize[8]; uint32_t *ppui32Data[8]; uint32_t pui32Count[8]; uint8_t pui8Endpoint[8]; uint32_t pui32EPDMAMode0[8]; uint32_t pui32EPDMAMode1[8]; uint32_t ui32Pending; uint32_t ui32Complete; void (* pfnArbSizeSet)(tUSBDMAInstance *psUSBDMAInst, uint32_t ui32Channel, uint32_t ui32ArbSize); uint32_t (* pfnChannelAllocate)(tUSBDMAInstance *psUSBDMAInst, uint8_t ui8Endpoint, uint32_t ui32MaxPacketSize, uint32_t ui32Config); void (* pfnChannelEnable)(tUSBDMAInstance *psUSBDMAInst, uint32_t ui32Channel); void (* pfnChannelDisable)(tUSBDMAInstance *psUSBDMAInst, uint32_t ui32Channel); void (* pfnChannelRelease)(tUSBDMAInstance *psUSBDMAInst, uint8_t ui8Endpoint); uint32_t (* pfnChannelStatus)(tUSBDMAInstance *psUSBDMAInst, uint32_t ui32Channel); void (* pfnChannelIntDisable)(tUSBDMAInstance *psUSBDMAInst, uint32_t ui32Channel); void (* pfnChannelIntEnable)(tUSBDMAInstance *psUSBDMAInst, uint32_t ui32Channel); void (* pfnIntHandler)(tUSBDMAInstance *psUSBDMAInst, uint32_t ui32Status); uint32_t (* pfnIntStatus)(tUSBDMAInstance *psUSBDMAInst); void (* pfnIntStatusClear)(tUSBDMAInstance *psUSBDMAInst, uint32_t ui32Status); uint32_t (* pfnStatus)(tUSBDMAInstance *psUSBDMAInst); uint32_t (* pfnTransfer)(tUSBDMAInstance *psUSBDMAInst, uint32_t ui32Channel, void *pvBuffer, uint32_t ui32Size); void (* pfnUnitSizeSet)(tUSBDMAInstance *psUSBDMAInst, uint32_t ui32Channel, uint32_t ui32BitSize); }; //***************************************************************************** // // These are the USB libraries DMA functions. // //***************************************************************************** extern tUSBDMAInstance * USBLibDMAInit(uint32_t ui32Index); //***************************************************************************** // //! This function returns the current DMA status for a given DMA channel. //! //! \param psUSBDMAInst is the DMA structure pointer for this instance. //! \param ui32Channel is the DMA channel number used to retrieve the DMA //! status. //! //! This function returns the current status of a DMA transfer on a given //! DMA channel. The DMA channel is specified by the \e ui32Channel parameter. //! //! \return This function returns one of the \b USBLIBSTATUS_DMA_* values. // //***************************************************************************** //***************************************************************************** // //! This function is used to return any global status information for USB DMA. //! //! \param psUSBDMAInst is a generic instance pointer that can be used to //! distinguish between different hardware instances. //! //! This function performs returns the global status for the USB DMA //! interface. //! //! \return Always returns 0. // //***************************************************************************** //***************************************************************************** // //! This function returns the current DMA interrupt status. //! //! \param psUSBDMAInst is the DMA structure pointer for this instance. //! //! This function returns the interrupt status for all DMA channels. The value //! returned is a per channel interrupt mapping with the DMA channels mapped //! into bits 0-31 by channel number with channel 1 starting at bit 0. //! //! \note This function does not return an endpoint interrupt status, but the //! interrupt status for the DMA interface used with the USB controller. //! //! \return This function returns the pending DMA interrupts. // //***************************************************************************** //***************************************************************************** // //! This function clears the requested DMA interrupt status. //! //! \param psUSBDMAInst is the DMA structure pointer for this instance. //! \param ui32Status contains the interrupts to clear. //! //! This function clears the current DMA interrupt status for the //! controller specified by the \e ui32Instance parameter. The \e ui32Status //! value has the same format as the value returned from the //! USBLibDMAIntStatus() function which is a per channel interrupt mapping. //! The DMA channels are mapped into bits 0-31 by channel number with channel 1 //!starting at bit 0. //! //! \return None. // //***************************************************************************** //***************************************************************************** // //! This function enables DMA for a given channel. //! //! \param psUSBDMAInst is the DMA structure pointer for this instance. //! \param ui32Channel is the DMA channel to enable. //! //! This function enables DMA on the channel number passed in the //! \e ui32Channel parameter. //! //! \return None. // //***************************************************************************** //***************************************************************************** // //! This function disables DMA for a given DMA channel. //! //! \param psUSBDMAInst is the DMA structure pointer for this instance. //! \param ui32Channel is the DMA channel to disable. //! //! This function disables DMA on the channel number passed in the //!\e ui32Channel parameter. //! //! \return None. // //***************************************************************************** //***************************************************************************** // //! This function is configures a USB transfer on a given DMA channel. //! //! \param psUSBDMAInst is the DMA structure pointer for this instance. //! \param ui32Channel is the DMA channel to use. //! \param pvBuffer is a pointer to the buffer to use for the transfer. //! \param ui32Size is the size of the data to be transferred in bytes. //! //! This function is called to configure a transfer using the USB //! controller depending on the parameters. The \e ui32Channel parameter //! holds the channel number to use for this transfer which must have already //! been allocated with a call to the USBLibDMAChannelAllocate() function. The //! transaction is configured to transfer \e ui32Size bytes to/from the buffer //! held in the \e pvBuffer pointer. //! //! \return This function returns the number of bytes scheduled to be //! transferred. // //***************************************************************************** //***************************************************************************** // //! This function is called by the USB interrupt handler. //! //! \param psUSBDMAInst is the DMA structure pointer for this instance. //! \param ui32Status is the DMA interrupt status. //! //! This function is called by the USB interrupt handler to allow the DMA //! interface to handle interrupts outside of the context of the normal USB //! interrupt handler. The \e ui32Status is the current DMA interrupt status //! at the time of the USB interrupt. Since some DMA controller interrupts are //! cleared automatically when read, this value must be retrieved by calling //! the USBLibDMAIntStatus() function and passed into this function. //! //! \return None. // //***************************************************************************** //***************************************************************************** // //! This function is used to assign a DMA channel to an endpoint. //! //! \param psUSBDMAInst is the DMA instance data for a USB controller. //! \param ui8Endpoint is the endpoint number to assign a DMA channel. //! \param ui32MaxPacketSize is the maximum packet size for the endpoint //! assigned that is being assigned to the DMA channel. //! \param ui32Config are the basic configuration options for the DMA channel. //! //! This function assigns a DMA channel to a given endpoint. The //! \e ui8Endpoint parameter is the zero based endpoint number that is assigned //! a DMA channel. The \e ui32Config parameter contains any configuration //! options for the DMA channel. The current options include the following: //! - \b USB_DMA_EP_TX - this request is for a transmit DMA channel. //! - \b USB_DMA_EP_RX - this request is for a receive DMA channel. //! //! \note The maximum number of available DMA channels to endpoints varies //! between devices. //! //! \return Zero or the DMA channel assigned to the endpoint. // //***************************************************************************** //***************************************************************************** // //! This function is used to free a DMA channel that was assigned to an //! endpoint. //! //! \param psUSBDMAInst is the DMA instance data for a USB controller. //! \param ui8Endpoint is the DMA channel number to free up. //! //! This function frees up a DMA channel that was allocated to an endpoint //! by the USBLibDMAChannelAllocate() function. //! //! \return None. // //***************************************************************************** //***************************************************************************** // //! This function is used to set the individual transfer size of a DMA channel. //! //! \param psUSBDMAInst is the DMA instance data for a USB controller. //! \param ui32Channel is the DMA channel number to modify. //! \param ui32BitSize is the individual transfer size in bits(8, 16 or 32). //! //! This function configures the individual transfer size of the DMA channel //! provided in the \e ui32Channel parameter. The \e ui32Channel must already //! be allocated to an endpoint by calling the USBLibDMAChannelAllocate() //! function. The \e ui32BitSize parameter should be on of the following //! values: 8, 16 or 32. //! //! \return None. // //***************************************************************************** //***************************************************************************** // //! This function is used to set the arbitration size for a DMA channel. //! //! \param psUSBDMAInst is the DMA instance data for a USB controller. //! \param ui32Channel is the DMA channel number to modify. //! \param ui32ArbSize is the transfer arbitration size in bytes. //! //! This function configures the individual transfer size of the DMA channel //! provided in the \e ui32Channel parameter. The \e ui32Channel must already //! be allocated to an endpoint by calling the USBLibDMAChannelAllocate() //! function. //! //! \return None. // //***************************************************************************** //***************************************************************************** // //! This function enables the DMA interrupt for a given channel. //! //! \param psUSBDMAInst is the DMA structure pointer for this instance. //! \param ui32Channel is the DMA channel interrupt to enable. //! //! This function enables DMA interrupt on the channel number passed in the //! \e ui32Channel parameter. //! //! \return None. // //***************************************************************************** //***************************************************************************** // //! This function disables DMA interrupt for a given DMA channel. //! //! \param psUSBDMAInst is the DMA structure pointer for this instance. //! \param ui32Channel is the DMA channel interrupt to disable. //! //! This function disables the DMA interrupt on the channel number passed in //! the \e ui32Channel parameter. //! //! \return None. // //***************************************************************************** //***************************************************************************** // // Mark the end of the C bindings section for C++ compilers. // //***************************************************************************** //***************************************************************************** // // Close the Doxygen group. //! @} // //***************************************************************************** //############################################################################# // FILE: usbhost.h // TITLE: Host specific definitions for the USB host library //############################################################################# // $TI Release: F2837xD Support Library v190 $ // $Release Date: Mon Feb 1 16:51:57 CST 2016 $ // $Copyright: // Copyright (C) 2013-2016 Texas Instruments Incorporated - http://www.ti.com/ // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions // are met: // // Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. // // Redistributions in binary form must reproduce the above copyright // notice, this list of conditions and the following disclaimer in the // documentation and/or other materials provided with the // distribution. // // Neither the name of Texas Instruments Incorporated nor the names of // its contributors may be used to endorse or promote products derived // from this software without specific prior written permission. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // $ //############################################################################# //***************************************************************************** // // If building with a C++ compiler, make all of the definitions in this header // have a C binding. // //***************************************************************************** //***************************************************************************** // //! \addtogroup usblib_hcd //! @{ // //***************************************************************************** //***************************************************************************** // // This is the type used to identify what the pipe is currently in use for. // //***************************************************************************** //***************************************************************************** // // These are the defines that are used with USBHCDPowerConfigInit(). // //***************************************************************************** //***************************************************************************** // //! This macro is used to declare an instance of an Event driver for the USB //! library. //! //! \param VarName is the name of the variable. //! \param pfnOpen is the callback for the Open call to this driver. This //! value is currently reserved and should be set to 0. //! \param pfnClose is the callback for the Close call to this driver. This //! value is currently reserved and should be set to 0. //! \param pfnEvent is the callback that will be called for various USB events. //! //! The first parameter is the actual name of the variable that will //! be declared by this macro. The second and third parameter are reserved //! for future functionality and are unused and should be set to zero. The //! last parameter is the actual callback function and is specified as //! a function pointer of the type: //! //! void (*pfnEvent)(void *pvData); //! //! When the \e pfnEvent function is called the void pointer that is passed in //! as a parameter should be cast to a pointer to a structure of type //! tEventInfo. This will contain the event that caused the pfnEvent function //! to be called. // //***************************************************************************** //***************************************************************************** // // This is the type definition a callback for events on USB Pipes allocated // by USBHCDPipeAlloc(). // // \param ui32Pipe is well the pipe // \param ui32Event is well the event // // This prototype is used by any Pipe callbacks that are used in the host // class drivers. These functions typically handle data events like // USB_EVENT_RX_AVAILABLE or USB_EVENT_TX_COMPLETE but can be sent other events // depending on the USB host class in use. See the documentation for the // individual classes for the valid events for that class. // // \return None. // //***************************************************************************** typedef void (* tHCDPipeCallback)(uint32_t ui32Pipe, uint32_t ui32Event); //***************************************************************************** // // Predeclare the private tUSBHostDevice structure. // //***************************************************************************** typedef struct tUSBHostDevice tUSBHostDevice; //***************************************************************************** // //! This structure defines a USB host class driver interface, it is parsed to //! find a USB class driver once a USB device is enumerated. // //***************************************************************************** typedef struct { // //! The interface class that this device class driver supports. // uint32_t ui32InterfaceClass; // //! The function is called when this class of device has been detected. // void *(*pfnOpen)(tUSBHostDevice *psDevice); // //! The function is called when the device, originally opened with a call //! to the pfnOpen function, is disconnected. // void (*pfnClose)(void *pvInstance); // //! This is the optional interrupt handler that will be called when an //! endpoint associated with this device instance generates an interrupt. // void (*pfnIntHandler)(void *pvInstance); } tUSBHostClassDriver; //***************************************************************************** // // Close the Doxygen group. //! @} // //***************************************************************************** //***************************************************************************** // // If the g_USBEventDriver is included in the host controller driver list then // this function must be provided by the application. // //***************************************************************************** extern void USBHCDEvents(void *pvData); //***************************************************************************** // // Prototypes for the USB Host controller APIs. // //***************************************************************************** extern void USBHCDMain(void); extern int32_t USBHCDEventEnable(uint32_t ui32Index, void *pvEventDriver, uint32_t ui32Event); extern int32_t USBHCDEventDisable(uint32_t ui32Index, void *pvEventDriver, uint32_t ui32Event); extern void USBHCDInit(uint32_t ui32Index, void *pvData, uint32_t ui32Size); extern void USBHCDPowerConfigInit(uint32_t ui32Index, uint32_t ui32Flags); extern uint32_t USBHCDPowerConfigGet(uint32_t ui32Index); extern uint32_t USBHCDPowerConfigSet(uint32_t ui32Index, uint32_t ui32Config); extern uint32_t USBHCDPowerAutomatic(uint32_t ui32Index); extern void USBHCDRegisterDrivers(uint32_t ui32Index, const tUSBHostClassDriver * const *ppsHClassDrvrs, uint32_t ui32NumDrivers); extern void USBHCDTerm(uint32_t ui32Index); extern void USBHCDSetConfig(uint32_t ui32Index, uint32_t ui32Device, uint32_t ui32Configuration); extern void USBHCDSetInterface(uint32_t ui32Index, uint32_t ui32Device, uint32_t ui32Interface, uint32_t ui32AltSetting); extern void USBHCDSuspend(uint32_t ui32Index); extern void USBHCDResume(uint32_t ui32Index); extern void USBHCDReset(uint32_t ui32Index); extern void USBHCDPipeFree(uint32_t ui32Pipe); extern uint32_t USBHCDPipeAlloc(uint32_t ui32Index, uint32_t ui32EndpointType, tUSBHostDevice *psDevice, tHCDPipeCallback pfnCallback); extern uint32_t USBHCDPipeAllocSize(uint32_t ui32Index, uint32_t ui32EndpointType, tUSBHostDevice *psDevice, uint32_t ui32FIFOSize, tHCDPipeCallback pfnCallback); extern uint32_t USBHCDPipeConfig(uint32_t ui32Pipe, uint32_t ui32MaxPayload, uint32_t ui32Interval, uint32_t ui32TargetEndpoint); extern uint32_t USBHCDPipeStatus(uint32_t ui32Pipe); extern uint32_t USBHCDPipeWrite(uint32_t ui32Pipe, uint8_t *pui8Data, uint32_t ui32Size); extern uint32_t USBHCDPipeRead(uint32_t ui32Pipe, uint8_t *pui8Data, uint32_t ui32Size); extern uint32_t USBHCDPipeSchedule(uint32_t ui32Pipe, uint8_t *pui8Data, uint32_t ui32Size); extern void USBHCDPipeDataAck(uint32_t ui32Pipe); extern uint32_t USBHCDPipeReadNonBlocking(uint32_t ui32Pipe, uint8_t *pui8Data, uint32_t ui32Size); extern uint32_t USBHCDControlTransfer(uint32_t ui32Index, tUSBRequest *psSetupPacket, tUSBHostDevice *psDevice, uint8_t *pui8Data, uint32_t ui32Size, uint32_t ui32MaxPacketSize); extern void USB0HostIntHandler(void); extern uint8_t USBHCDDevHubPort(uint32_t ui32Instance); extern uint8_t USBHCDDevAddress(uint32_t ui32Instance); extern uint8_t USBHCDDevClass(uint32_t ui32Instance, uint32_t ui32Interface); extern uint8_t USBHCDDevSubClass(uint32_t ui32Instance, uint32_t ui32Interface); extern uint8_t USBHCDDevProtocol(uint32_t ui32Instance, uint32_t ui32Interface); //***************************************************************************** // // The host class drivers supported by the USB library. // //***************************************************************************** extern const tUSBHostClassDriver g_sUSBHostMSCClassDriver; extern const tUSBHostClassDriver g_sUSBHIDClassDriver; extern const tUSBHostClassDriver g_sUSBHostAudioClassDriver; //***************************************************************************** // // Mark the end of the C bindings section for C++ compilers. // //***************************************************************************** //############################################################################# // FILE: usbhostpriv.h // TITLE: Internal header file for USB host functions //############################################################################# // $TI Release: F2837xD Support Library v190 $ // $Release Date: Mon Feb 1 16:51:57 CST 2016 $ // $Copyright: // Copyright (C) 2013-2016 Texas Instruments Incorporated - http://www.ti.com/ // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions // are met: // // Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. // // Redistributions in binary form must reproduce the above copyright // notice, this list of conditions and the following disclaimer in the // documentation and/or other materials provided with the // distribution. // // Neither the name of Texas Instruments Incorporated nor the names of // its contributors may be used to endorse or promote products derived // from this software without specific prior written permission. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // $ //############################################################################# //***************************************************************************** // // If building with a C++ compiler, make all of the definitions in this header // have a C binding. // //***************************************************************************** //***************************************************************************** // // The states a hub port can be in during device connection. // //***************************************************************************** typedef enum { // // The port has no device connected. // ePortIdle, // // The port has a device present and is waiting for the enumeration // sequence to begin. // ePortConnected, // // A device connection notification has been received and we have initiated // a reset to the port. We are waiting for the reset to complete. // ePortResetActive, // // The Port reset has completed but now the hub is waiting the required // 10ms before accessing the device. // ePortResetWait, // // A device is connected and the port has been reset. Control has been // passed to the main host handling portion of USBLib to enumerate the // device. // ePortActive, // // A device has completed enumeration. // ePortEnumerated, // // A device is attached to the port but enumeration failed. // ePortError } tHubPortState; //***************************************************************************** // // The list of valid event flags in the g_sUSBHCD.ui32EventEnables member // variable. // //***************************************************************************** //***************************************************************************** // //! This is the structure that holds all of the information for devices //! that are enumerated in the system. It is passed in to Open function of //! USB host class drivers so that they can allocate any endpoints and parse //! out other information that the device class needs to complete enumeration. // //***************************************************************************** struct tUSBHostDevice { // //! The current device address for this device. // uint32_t ui32Address; // //! The current interface for this device. // uint32_t ui32Interface; // //! A flag used to record whether this is a low-speed or a full-speed //! device. // _Bool bLowSpeed; // //! A flag indicating whether or not we have read the device's //! configuration descriptor yet. // _Bool bConfigRead; // //! The hub number to which this device is attached. // uint8_t ui8Hub; // //! The hub port number to which the device is attached. // uint8_t ui8HubPort; // //! The device descriptor for this device. // tDeviceDescriptor sDeviceDescriptor; // //! A pointer to the configuration descriptor for this device. // tConfigDescriptor *psConfigDescriptor; // //! The size of the buffer allocated to psConfigDescriptor. // uint32_t ui32ConfigDescriptorSize; // //! Internal flags used by the host controller driver. // uint32_t ui32Flags; }; //***************************************************************************** // // Functions within the host controller that are called by the hub class driver // //***************************************************************************** extern uint32_t USBHCDHubDeviceConnected(uint32_t ui32Index, uint8_t ui8Hub, uint8_t ui8Port, _Bool bLowSpeed); extern void USBHCDHubDeviceDisconnected(uint32_t ui32Index, uint32_t ui32DevIndex); //***************************************************************************** // // Functions in the hub class driver that are called by the host controller. // //***************************************************************************** extern void USBHHubMain(void); extern void USBHHubInit(void); extern void USBHHubEnumerationComplete(uint8_t ui8Hub, uint8_t ui8Port); extern void USBHHubEnumerationError(uint8_t ui8Hub, uint8_t ui8Port); //***************************************************************************** // // Mark the end of the C bindings section for C++ compilers. // //***************************************************************************** //############################################################################# // FILE: usbhhub.h // TITLE: This hold the host driver for hid class //############################################################################# // $TI Release: F2837xD Support Library v190 $ // $Release Date: Mon Feb 1 16:51:57 CST 2016 $ // $Copyright: // Copyright (C) 2013-2016 Texas Instruments Incorporated - http://www.ti.com/ // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions // are met: // // Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. // // Redistributions in binary form must reproduce the above copyright // notice, this list of conditions and the following disclaimer in the // documentation and/or other materials provided with the // distribution. // // Neither the name of Texas Instruments Incorporated nor the names of // its contributors may be used to endorse or promote products derived // from this software without specific prior written permission. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // $ //############################################################################# //***************************************************************************** // // If building with a C++ compiler, make all of the definitions in this header // have a C binding. // //***************************************************************************** typedef struct tHubInstance tHubInstance; extern const tUSBHostClassDriver g_sUSBHubClassDriver; //***************************************************************************** // // The USB standard allows for up to 127 downstream ports on a single hub. // This would require rather more memory than we would like to set aside so the // default configuration of the hub driver supports hubs with up to 7 // downstream-facing ports. In practice, this should be more than enough // since this covers the vast majority of consumer hubs. Note that, by // default, we will only support 4 devices so you can't fully populate a 7 port // hub and have everything work. // // Feel free to change this but bad things will happen if you increase it above // 31 since we assume the reports will always fit inside a 4 byte buffer. // //***************************************************************************** //***************************************************************************** // // Values used as the ui16Feature parameter to USBHHubClearHubFeature(). // //***************************************************************************** //***************************************************************************** // // Values used as the ui16Feature parameter to USBHHubSetPortFeature() and // USBHHubClearPortFeature(). // //***************************************************************************** //***************************************************************************** // // Values returned via the *pui16HubStatus and *pui16HubChange parameters // passed to USBHHubGetHubStatus(). These may be ORed together into the // returned status value. // //***************************************************************************** //***************************************************************************** // // Values returned via the *pui16PortStatus parameter passed to // USBHHubGetPortStatus(). These may be ORed together into the returned status // value. // //***************************************************************************** //***************************************************************************** // // Values returned via the *pui16PortChange parameter passed to // USBHHubGetPortStatus(). These may be ORed together into the returned status // value. // //***************************************************************************** //***************************************************************************** // // The prototype for the USB Hub host driver callback function. // //***************************************************************************** typedef void (*tUSBHHubCallback)(tHubInstance *psHubInstance, uint32_t ui32Event, uint32_t ui32MsgParam, void *pvMsgData); //***************************************************************************** // // Public function prototypes for the HUB class driver. // //***************************************************************************** extern tHubInstance * USBHHubOpen(tUSBHHubCallback pfnCallback); extern void USBHHubClose(tHubInstance *psHubInstance); //***************************************************************************** // //! \addtogroup usblib_hcd //! @{ // //***************************************************************************** //***************************************************************************** // // External prototypes. // //***************************************************************************** extern tUSBMode g_iUSBMode; extern void OTGDeviceDisconnect(uint32_t ui32Index); //***************************************************************************** // // Internal function prototypes. // //***************************************************************************** static void USBHCDEP0StateTx(void); static void USBHCDEnumHandler(void); static void USBHCDClearFeature(uint32_t ui32DevAddress, uint32_t ui32Endpoint, uint32_t ui32Feature); //***************************************************************************** // // Automatic power enable. // //***************************************************************************** //***************************************************************************** // // Flags used to signal between the interrupt handler and USBHCDMain(). // //***************************************************************************** //***************************************************************************** // // Flags used with the tUSBHostDevice.ui32Flags structure member. // //***************************************************************************** //***************************************************************************** // // This holds the current power configuration that is used when USBHCDInit() // is called. // //***************************************************************************** static uint32_t g_ui32PowerConfig = 0x00000003; //***************************************************************************** // // The states for endpoint 0 during enumeration. // //***************************************************************************** typedef enum { // // The USB device is waiting on a request from the host controller on // endpoint 0.hw_memmap.h // eEP0StateIdle, // // Setup packet is expecting data IN. // eEP0StateSetupIN, // // Setup packet is sending data OUT. // eEP0StateSetupOUT, // // The USB device is receiving data from the device due to an SETUP IN // request. // eEP0StateRx, // // The USB device has completed the IN or OUT request and is now waiting // for the host to acknowledge the end of the IN/OUT transaction. This // is the status phase for a USB control transaction. // eEP0StateStatus, // // This state is for when a response only has a status phase and no // data phase. // eEP0StateStatusIN, // // This endpoint has signaled a stall condition and is waiting for the // stall to be acknowledged by the host controller. // eEP0StateStall, // // An error has occurred on endpoint 0. // eEP0StateError } tEP0State; //***************************************************************************** // // This structure holds the full state for the device enumeration. // //***************************************************************************** typedef struct { // // This is the pointer to the current data being sent out or received // on endpoint 0. // uint8_t *pui8Data; // // This is the number of bytes that remain to be sent from or received // into the g_DeviceState.pEP0Data data buffer. // volatile uint32_t ui32BytesRemaining; // // The amount of data being sent/received due to a request. // uint32_t ui32DataSize; // // This is the current device address in use by endpoint 0. // uint32_t ui32DevAddress; // // The maximum packet size for the device responding to the setup packet. // uint32_t ui32MaxPacketSize; // // The host controller's state. // tEP0State iState; } tHostState; //***************************************************************************** // // This variable holds the current state of endpoint 0. // //***************************************************************************** static volatile tHostState g_sUSBHEP0State = { 0, // pui8Data 0, // ui32BytesRemaining 0, // ui32DataSize 0, // ui32DevAddress 0, // ui32MaxPacketSize eEP0StateIdle // iState }; //***************************************************************************** // // The global delay time for use by SysCtlDelay() function. This is // initialized to an appropriate value for a 50MHz clock. The correct value // will be set in USBHCDInit(). // //***************************************************************************** static uint32_t g_ui32Tickms = 0; static volatile uint32_t g_ui32CurrentTick = 0; //***************************************************************************** // // The current active drivers. // //***************************************************************************** static int32_t g_pi32USBHActiveDriver[5 + 1]; static void *g_ppvDriverInstance[5 + 1]; //***************************************************************************** // // This is the structure used to hold the information for a given USB pipe // that is attached to a device. // //***************************************************************************** typedef struct { // // The current address for this pipe. // tUSBHostDevice *psDevice; // // The current address for this pipe. // uint8_t ui8EPNumber; // // The DMA channel assigned to this endpoint. // uint8_t ui8DMAChannel; // // The current type for this pipe. // uint32_t ui32Type; // // The millisecond interval for this pipe. // uint32_t ui32Interval; // // The next tick value to trigger and event on this pipe. // uint32_t ui32NextEventTick; // // The current call back for this pipe. // tHCDPipeCallback pfnCallback; // // The pointer to which IN data must be copied. // uint8_t *pui8ReadPtr; // // The number of bytes of read data to copy. // uint32_t ui32ReadSize; // // The state of a given USB pipe. // volatile enum { ePipeReading, ePipeReadDMA, ePipeReadDMAWait, ePipeReadSingle, ePipeDataReady, ePipeDataSent, ePipeWriting, ePipeWriteDMA, ePipeWriteDMASend, ePipeWriteDMAWait, ePipeWriteSingle, ePipeStalled, ePipeError, ePipeIdle, ePipeDisabled } iState; // // The actual FIFO offset allocated to this endpoint. // uint16_t ui16FIFOAddr; // // The size of the FIFO entry based on the size parameter. These are // equivalent to the USB_FIFO_SZ_* values in usb.h. // uint8_t ui8FIFOSize; // // The bit offset in the allocation structure. // uint8_t ui8FIFOBitOffset; } tUSBHCDPipe; //***************************************************************************** // // The internal state of the device. // //***************************************************************************** typedef enum { eHCDDevDisconnected, eHCDDevConnected, eHCDDevConnectedHub, eHCDDevRequest, eHCDDevReset, eHCDDevAddressed, eHCDDevConfigured, eHCDDevGetStrings, eHCDDevError, eHCDVBUSError, eHCDPowerFault, eHCDIdle } tUSBHDeviceState; static void ProcessUSBDeviceStateMachine(tUSBHDeviceState iOldState, uint32_t ui32DevIndex); //***************************************************************************** // // This is a fixed number as it relates to the maximum number of USB pipes // available on any USB controller. The actual number on a given device may // be less than this number. // //***************************************************************************** //***************************************************************************** // // This is a fixed number as it relates to the number of USB pipes available // in the USB controller. // //***************************************************************************** //***************************************************************************** // // Marker for an unused DMA channel slot. // //***************************************************************************** //***************************************************************************** // // These definitions are used to manipulate the values returned as allocated // USB pipes. // //***************************************************************************** //***************************************************************************** // // This creates a USB pipe handle from an index. // //***************************************************************************** //***************************************************************************** // // Converts from an endpoint specifier to the offset of the endpoint's // control/status registers. // //***************************************************************************** //***************************************************************************** // // This structure holds the state information for a given host controller. // //***************************************************************************** typedef struct { uint32_t ui32USBBase; tUSBHCDPipe sUSBControlPipe; tUSBHCDPipe psUSBOUTPipes[15]; tUSBHCDPipe psUSBINPipes[15]; // // Each devices state. We support a total of (MAX_USB_DEVICES + 1) devices // to allow for the use if MAX_USB_DEVICES through a single hub (which is // itself a device). // tUSBHostDevice psUSBDevice[5 + 1]; // // Holds the current state of the device. // volatile tUSBHDeviceState piDeviceState[5 + 1]; // // Pointer to the memory pool for this controller. // void *pvPool; // // The pool size for this controller. // uint32_t ui32PoolSize; // // The number of endpoint pairs supported by the controller. // uint32_t ui32NumEndpoints; // // The class drivers for this controller. // const tUSBHostClassDriver * const *ppsClassDrivers; // // The number of class drivers. // uint32_t ui32NumClassDrivers; // // This is the index in the driver list of the event driver. // int32_t i32EventDriver; // // These are the generic event information used by the event driver. // uint32_t ui32EventEnables; uint32_t ui32Class; // // The DMA instance information for this class. // tUSBDMAInstance *psDMAInstance; // // The interrupt number for this instance. // uint32_t ui32IntNum; // // The pending interrupt events that are processed in USBHCDMain(). // uint32_t ui32IntEvents; // // Features. // uint32_t ui32Features; // // The host initiated resume duration in us. // uint32_t ui32LPMHIRD; } tUSBHCD; //***************************************************************************** // // The global to hold all of the state information for a given host controller. // //***************************************************************************** static tUSBHCD g_sUSBHCD = { .psUSBDevice[0].ui32ConfigDescriptorSize = 0 }; //***************************************************************************** // // Allocates the memory needed to support configuration descriptors for // devices. // //***************************************************************************** uint32_t ConfigDescAlloc(tUSBHostDevice *psDevice, uint32_t ui32Size) { uint32_t ui32Idx, ui32BlockSize, ui32PoolSize; uint8_t *pui8Pool; if(g_sUSBHCD.psUSBDevice[0].psConfigDescriptor == 0) { // // 32 bit align the allocation. // ui32Size = (ui32Size + 3) & ~3; if(g_sUSBHCD.ui32PoolSize < ui32Size) { return(0); } // // Set the Allocation flag so that when the device disconnects, // the library will clean up the allocated space and re-initialize // the appropriate variables and structs. // g_sUSBHCD.psUSBDevice[0].ui32Flags |= 0x80000000; // // Allocate the root connection to the device. // g_sUSBHCD.psUSBDevice[0].psConfigDescriptor = g_sUSBHCD.pvPool; g_sUSBHCD.psUSBDevice[0].ui32ConfigDescriptorSize = ui32Size; // // Allocate the hub memory pools (these can end up null). // pui8Pool = (uint8_t *)g_sUSBHCD.pvPool + ui32Size; ui32PoolSize = g_sUSBHCD.ui32PoolSize - ui32Size; // // Divide the pool up into blocks, one for each supported port. We make // sure that each block is a multiple of 4 bytes. // ui32BlockSize = (ui32PoolSize / 5) & ~3; for(ui32Idx = 1; ui32Idx < 5; ui32Idx++) { g_sUSBHCD.psUSBDevice[ui32Idx].psConfigDescriptor = (tConfigDescriptor *)(pui8Pool + (ui32Idx * ui32BlockSize)); g_sUSBHCD.psUSBDevice[ui32Idx].ui32ConfigDescriptorSize = ui32BlockSize; } } return(ui32Size); } //***************************************************************************** // // Frees the memory needed to support configuration descriptors for // devices. // //***************************************************************************** void ConfigDescFree(tUSBHostDevice *psDevice) { uint32_t ui32Idx; // // If this is the root device then deallocate. // if(&g_sUSBHCD.psUSBDevice[0] == psDevice) { for(ui32Idx = 0; ui32Idx < 5; ui32Idx++) { g_sUSBHCD.psUSBDevice[ui32Idx].ui32Flags &= ~0x80000000; g_sUSBHCD.psUSBDevice[ui32Idx].psConfigDescriptor = 0; g_sUSBHCD.psUSBDevice[ui32Idx].ui32ConfigDescriptorSize = 0; } } } //***************************************************************************** // // Return the device index from a ui32Instance value passed from an external // source. // //***************************************************************************** static uint8_t HCDInstanceToDevIndex(uint32_t ui32Instance) { uint32_t ui32DevIndex; // // Get the device instance from the instance value. // ui32DevIndex = (ui32Instance & 0xff); // // If the above math went negative or is too large just return 0xff. // if(ui32DevIndex > 5) { ui32DevIndex = 0xff; } return(ui32DevIndex); } //============================================================================= // // This is the internal function that will map an event to a valid event flag. // // \param ui32Event specifies which event flag to retrieve. // // \return The event flag or 0 if there is no support event flag for the // event specified by the \e ui32Event parameter. // //============================================================================= static uint32_t GetEventFlag(uint32_t ui32Event) { uint32_t ui32EventFlag; ui32EventFlag = 0; // // Search for a valid event flag for the requested event. // switch(ui32Event) { case (0x0000 + 19): { ui32EventFlag |= 0x00000001; break; } case (0x0000 + 0): { ui32EventFlag |= 0x00000002; break; } case (0x0000 + 1): { ui32EventFlag |= 0x00000008; break; } case (0x0000 + 18): { ui32EventFlag |= 0x00000004; break; } case (0x0000 + 11): { ui32EventFlag |= 0x00000010; break; } case (0x0000 + 13): { ui32EventFlag |= 0x00000020; break; } case (0x0000 + 12): { ui32EventFlag |= 0x00000040; break; } default: { break; } } return(ui32EventFlag); } //============================================================================= // //! This function is called to enable a specific USB HCD event notification. //! //! \param ui32Index specifies which USB controller to use. //! \param pvEventDriver is the event driver structure that was passed into //! the USBHCDRegisterDrivers() function as part of the array of //! tUSBHostClassDriver structures. //! \param ui32Event is the event to enable. //! //! This function is called to enable event callbacks for a specific USB HCD //! event. The requested event is passed in the \e ui32Event parameter. Not //! all events can be enables so the function will return zero if the event //! provided cannot be enabled. The \e pvEventDriver is a pointer to the //! event driver structure that the caller passed into the //! USBHCDRegisterDrivers() function. This structure is typically declared //! with the DECLARE_EVENT_DRIVER() macro and included as part of the array //! of pointers to tUSBHostClassDriver structures that is passed to the //! USBHCDRegisterDrivers() function. //! //! \return This function returns a non-zero number if the event was //! successfully enabled and returns zero if the event cannot be enabled. // //============================================================================= int32_t USBHCDEventEnable(uint32_t ui32Index, void *pvEventDriver, uint32_t ui32Event) { int32_t i32Ret; uint32_t ui32EventFlag; { if(!(ui32Index == 0)) { __error__("../USB/host/usbhostenum.c", 737); } }; // // Default the return to fail the call unless a valid event is found. // i32Ret = 0; // // Get the event flag for this event. // ui32EventFlag = GetEventFlag(ui32Event); // // Check if there was an event flag for the corresponding event. // if(ui32EventFlag) { // // Set the enable for this event. // g_sUSBHCD.ui32EventEnables |= ui32EventFlag; // // Indicate that the event was valid and is now enabled. // i32Ret = 1; } return(i32Ret); } //============================================================================= // //! This function is called to disable a specific USB HCD event notification. //! //! \param ui32Index specifies which USB controller to use. //! \param pvEventDriver is the event driver structure that was passed into //! the USBHCDRegisterDrivers() function as part of the array of //! tUSBHostClassDriver structures. //! \param ui32Event is the event to disable. //! //! This function is called to disable event callbacks for a specific USB HCD //! event. The requested event is passed in the \e ui32Event parameter. Not //! all events can be enables so the function will return zero if the event //! provided cannot be enabled. The \e pvEventDriver is a pointer to the //! event driver structure that the caller passed into the //! USBHCDRegisterDrivers() function. This structure is typically declared //! with the DECLARE_EVENT_DRIVER() macro and included as part of the array //! of pointers to tUSBHostClassDriver structures that is passed to the //! USBHCDRegisterDrivers() function. //! //! \return This function returns a non-zero number if the event was //! successfully disabled and returns zero if the event cannot be disabled. // //============================================================================= int32_t USBHCDEventDisable(uint32_t ui32Index, void *pvEventDriver, uint32_t ui32Event) { int32_t i32Ret; uint32_t ui32EventFlag; { if(!(ui32Index == 0)) { __error__("../USB/host/usbhostenum.c", 798); } }; // // Default the return to fail the call unless a valid event is found. // i32Ret = 0; // // Get the event flag for this event. // ui32EventFlag = GetEventFlag(ui32Event); // // Check if there was an event flag for the corresponding event. // if(ui32EventFlag) { // // Clear the enable for this event. // g_sUSBHCD.ui32EventEnables &= ~ui32EventFlag; // // Indicate that the event was valid and is now disabled. // i32Ret = 1; } return(i32Ret); } //***************************************************************************** // // If there is an event driver this function will send out a generic connection // event USB_EVENT_UNKNOWN_CONNECTED indicating that an unknown connection // event has occurred. // //***************************************************************************** static void SendUnknownConnect(uint32_t ui32Index, uint32_t ui32Class) { tEventInfo sEvent; // // If there is an event driver registered and it has a event handler and // the USBHCD_EVFLAG_UNKCNCT is enabled then call the function. // sEvent.ui32Event = (0x0000 + 18); sEvent.ui32Instance = ui32Class; InternalUSBHCDSendEvent(0, &sEvent, 0x00000004); } //***************************************************************************** // // Internal memory allocation space is two 32-bit values where each // bit represents a 64 byte block in the FIFO. This requires 64 bits for // the 4096 bytes of FIFO available. // //***************************************************************************** static uint32_t g_pui32Alloc[2]; //***************************************************************************** // // This function handles freeing FIFO memory that has been allocated using the // FIFOAlloc() function. // //***************************************************************************** static void FIFOFree(tUSBHCDPipe *psUSBPipe) { uint32_t ui32Mask; // // Calculate the mask value to use to clear off the allocated blocks used // by the USB pipe specified by psUSBPipe. // ui32Mask = ((uint32_t)1 << (psUSBPipe->ui8FIFOSize - 2)) - 1; ui32Mask = (uint32_t)ui32Mask << psUSBPipe->ui8FIFOBitOffset; // // Determine which 32 bit word to access based on the size. // if(psUSBPipe->ui8FIFOSize > 0x00000003) { // // If the FIFO size is greater than 64 then use the upper 32 bits. // g_pui32Alloc[1] &= ~ui32Mask; } else { // // If the FIFO size is less than or equal to 64 then use the lower // 32 bits. // g_pui32Alloc[0] &= ~ui32Mask; } } //***************************************************************************** // // This function is used to allocate FIFO memory to a given USB pipe. // // \param psUSBPipe is the USB pipe that needs FIFO memory allocated. // \param ui32Size is the minimum size in bytes of the FIFO to allocate. // // This function will allocate \e ui32Size bytes to the USB pipe in the // \e psUSBPipe parameter. The function will fill the psUSBPipe structure // members ui8FIFOSize and ui8FIFOAddr with values that can be used with the // USBFIFOConfigSet() API. This allocation uses a first fit algorithm. // // \return This function returns the size of the block allocated. // //***************************************************************************** static uint32_t FIFOAlloc(tUSBHCDPipe *psUSBPipe, uint32_t ui32Size) { uint32_t ui32Blocks, ui32Start, ui32BlockSize, ui32Temp, ui32Index; uint16_t ui16FIFOAddr; // // Save which 32 bit value to access, the upper is for blocks greater // than 64 and the lower is for block 64 or less. // if(ui32Size > 64) { ui32Index = 1; } else { ui32Index = 0; } // // Initial FIFO address is 0. // ui16FIFOAddr = 0; // // Initialize the bit pattern and bit location. // ui32Blocks = 1; ui32Start = 0; // // The initial block size is always the minimum size of 64 bytes. // ui32BlockSize = 64; // // The initial size and offset are 64 and 0. // psUSBPipe->ui8FIFOBitOffset = 0; psUSBPipe->ui8FIFOSize = 3; // // Scan through 32 bits looking for a memory block large enough to fill // the request. // while(ui16FIFOAddr <= 32) { // // If the pattern is zero then it is a possible match. // if((g_pui32Alloc[ui32Index] & ui32Blocks) == 0) { // // If the size is large enough then save it and break out of the // loop. // if(ui32BlockSize >= ui32Size) { // // Mark the memory as allocated. // g_pui32Alloc[ui32Index] |= ui32Blocks; break; } // // Increment the size of the FIFO block. // psUSBPipe->ui8FIFOSize++; // // Add in a new bit to the size of the allocation. // ui32Blocks = ui32Blocks | (ui32Blocks << 1) ; // // Double the current size. // ui32BlockSize <<= 1; } else { // // Need to start over looking because the last allocation match // failed, so reset the bit offset to the current location and the // size to 64 bytes. // psUSBPipe->ui8FIFOBitOffset = ui16FIFOAddr; psUSBPipe->ui8FIFOSize = 3; // // Reset the block size to the minimum (64 bytes). // ui32BlockSize = 64; // // Store the current starting bit location and set the block mask // to this value. // ui32Start = (uint32_t)1 << ui16FIFOAddr; ui32Blocks = ui32Start; } // // Increase the address of the FIFO offset. // ui16FIFOAddr++; } // // If there was no block large enough then fail this call. // if(ui16FIFOAddr > 32) { ui32BlockSize = 0; psUSBPipe->ui16FIFOAddr = 0; psUSBPipe->ui8FIFOBitOffset = 0; psUSBPipe->ui8FIFOSize = 0; } else { // // Calculate the offset in the FIFO. // ui32Temp = psUSBPipe->ui8FIFOBitOffset * 64; // // Sizes greater than 64 are allocated in the second half of the FIFO // memory space. // if(ui32Size > 64) { ui32Temp += 2048; } // // Convert this to the value that can be set in the USB controller. // psUSBPipe->ui16FIFOAddr = (uint16_t)ui32Temp; } return(ui32BlockSize); } //***************************************************************************** // //! This function is used to allocate a USB HCD pipe. //! //! \param ui32Index specifies which USB controller to use. //! \param ui32EndpointType is the type of endpoint that this pipe will be //! communicating with. //! \param psDevice is the device instance associated with this endpoint. //! \param ui32Size is the size of the FIFO in bytes. //! \param pfnCallback is the function that will be called when events occur on //! this USB Pipe. //! //! Since there are a limited number of USB HCD pipes that can be used in the //! host controller, this function is used to temporarily or permanently //! acquire one of the endpoints. Unlike the USBHCDPipeAlloc() function this //! function allows the caller to specify the size of the FIFO allocated to //! this endpoint in the \e ui32Size parameter. This function also provides a //! method to register a callback for status changes on this endpoint. If no //! callbacks are desired then the \e pfnCallback function should be set to 0. //! The callback should be used when using the USBHCDPipeSchedule() function //! so that the caller is notified when the action is complete. //! //! \return This function returns a value indicating which pipe was reserved. //! If the value is 0 then there were no pipes currently available. This value //! should be passed to any USBHCDPipe APIs to indicate which pipe is being //! accessed. // //***************************************************************************** uint32_t USBHCDPipeAllocSize(uint32_t ui32Index, uint32_t ui32EndpointType, tUSBHostDevice *psDevice, uint32_t ui32Size, tHCDPipeCallback pfnCallback) { int32_t i32Idx; uint32_t ui32HubAddr; { if(!(ui32Index == 0)) { __error__("../USB/host/usbhostenum.c", 1094); } }; // // Find a USB pipe that is free. // for(i32Idx = 0; i32Idx < 15; i32Idx++) { // // Handle OUT Pipes. // if(ui32EndpointType & 0x00010000) { // // A zero address indicates free. // if(g_sUSBHCD.psUSBOUTPipes[i32Idx].psDevice == 0) { // // Set up uDMA for the pipe. // if(ui32EndpointType & 0x01000000) { // // Allocate a DMA channel to the endpoint. // g_sUSBHCD.psUSBOUTPipes[i32Idx].ui8DMAChannel = g_sUSBHCD . psDMAInstance ->pfnChannelAllocate(g_sUSBHCD . psDMAInstance, (((uint32_t)(i32Idx + 1) << 4) & 0xFF), ui32Size, 0x00000000 | 0x00000040); // // If no DMA channel was available then just disable DMA // on this pipe. // if(g_sUSBHCD.psUSBOUTPipes[i32Idx].ui8DMAChannel == 0) { ui32EndpointType &= ~0x01000000; } } // // Save the endpoint type and device address and callback // function. // g_sUSBHCD.psUSBOUTPipes[i32Idx].ui32Type = ui32EndpointType; g_sUSBHCD.psUSBOUTPipes[i32Idx].psDevice = psDevice; g_sUSBHCD.psUSBOUTPipes[i32Idx].pfnCallback = pfnCallback; // // Clear out any pending status on this endpoint in case it // was in use before a allowing a new device class to use it. // USBHostEndpointStatusClear(0x00040000, (((uint32_t)(i32Idx + 1) << 4) & 0xFF), 0x0000FFFF); // // Initialize the endpoint as idle. // g_sUSBHCD.psUSBOUTPipes[i32Idx].iState = ePipeIdle; // // Allocate space in the FIFO for this endpoint. // if(FIFOAlloc(&g_sUSBHCD.psUSBOUTPipes[i32Idx], ui32Size) != 0) { // // Configure the FIFO. // USBFIFOConfigSet(0x00040000, (((uint32_t)(i32Idx + 1) << 4) & 0xFF), g_sUSBHCD.psUSBOUTPipes[i32Idx].ui16FIFOAddr, g_sUSBHCD.psUSBOUTPipes[i32Idx].ui8FIFOSize, 0x00002000); } // // Set the function address for this endpoint. // USBHostAddrSet(0x00040000, (((uint32_t)(i32Idx + 1) << 4) & 0xFF), psDevice->ui32Address, 0x00002000); // // Set the hub and port address for the endpoint. // ui32HubAddr = psDevice->ui8Hub | ((uint32_t)psDevice->ui8HubPort << 8); USBHostHubAddrSet(0x00040000, (((uint32_t)(i32Idx + 1) << 4) & 0xFF), ui32HubAddr, (0x00002000 | (psDevice->bLowSpeed ? 0x00000000 : 0x00001000))); break; } } // // Handle IN Pipes. // else if(ui32EndpointType & 0x00020000) { // // A zero address indicates free. // if(g_sUSBHCD.psUSBINPipes[i32Idx].psDevice == 0) { // // Set up uDMA for the pipe. // if(ui32EndpointType & 0x01000000) { // // Allocate a DMA channel to the endpoint. // g_sUSBHCD.psUSBINPipes[i32Idx].ui8DMAChannel = g_sUSBHCD . psDMAInstance ->pfnChannelAllocate(g_sUSBHCD . psDMAInstance, (((uint32_t)(i32Idx + 1) << 4) & 0xFF), ui32Size, 0x00000080 | 0x00000040); // // If no DMA channel was available then just disable DMA // on this pipe. // if(g_sUSBHCD.psUSBINPipes[i32Idx].ui8DMAChannel == 0) { ui32EndpointType &= ~0x01000000; } } // // Save the endpoint type and device address and callback // function. // g_sUSBHCD.psUSBINPipes[i32Idx].ui32Type = ui32EndpointType; g_sUSBHCD.psUSBINPipes[i32Idx].psDevice = psDevice; g_sUSBHCD.psUSBINPipes[i32Idx].pfnCallback = pfnCallback; // // Clear out any pending status on this endpoint in case it // was in use before a allowing a new device class to use it. // USBHostEndpointStatusClear(0x00040000, (((uint32_t)(i32Idx + 1) << 4) & 0xFF), 0xFFFF0000); // // Allocate space in the FIFO for this endpoint. // if(FIFOAlloc(&g_sUSBHCD.psUSBINPipes[i32Idx], ui32Size) != 0) { // // Configure the FIFO. // USBFIFOConfigSet(0x00040000, (((uint32_t)(i32Idx + 1) << 4) & 0xFF), g_sUSBHCD.psUSBINPipes[i32Idx].ui16FIFOAddr, g_sUSBHCD.psUSBINPipes[i32Idx].ui8FIFOSize, 0x00000000); } // // Set the function address for this endpoint. // USBHostAddrSet(0x00040000, (((uint32_t)(i32Idx + 1) << 4) & 0xFF), psDevice->ui32Address, 0x00000000); // // Set the hub and port address for the endpoint. // ui32HubAddr = psDevice->ui8Hub | ((uint32_t)psDevice->ui8HubPort << 8); USBHostHubAddrSet(0x00040000, (((uint32_t)(i32Idx + 1) << 4) & 0xFF), ui32HubAddr, (0x00000000 | (psDevice->bLowSpeed ? 0x00000000 : 0x00001000))); // // Reset the state of the pipe to idle. // g_sUSBHCD.psUSBINPipes[i32Idx].iState = ePipeIdle; break; } } } // // Did not find a free pipe. // if(i32Idx == 15) { return(0); } // // Return the pipe index and type that was allocated. // return(ui32EndpointType | i32Idx); } //***************************************************************************** // //! This function is used to allocate a USB HCD pipe. //! //! \param ui32Index specifies which USB controller to use. //! \param ui32EndpointType is the type of endpoint that this pipe will be //! communicating with. //! \param psDevice is the device instance associated with this endpoint. //! \param pfnCallback is the function that will be called when events occur on //! this USB Pipe. //! //! Since there are a limited number of USB HCD pipes that can be used in the //! host controller, this function is used to temporarily or permanently //! acquire one of the endpoints. It also provides a method to register a //! callback for status changes on this endpoint. If no callbacks are desired //! then the \e pfnCallback function should be set to 0. The callback should //! be used when using the USBHCDPipeSchedule() function so that the caller is //! notified when the action is complete. //! //! \return This function returns a value indicating which pipe was reserved. //! If the value is 0 then there were no pipes currently available. This value //! should be passed to any USBHCDPipe APIs to indicate which pipe is being //! accessed. // //***************************************************************************** uint32_t USBHCDPipeAlloc(uint32_t ui32Index, uint32_t ui32EndpointType, tUSBHostDevice *psDevice, tHCDPipeCallback pfnCallback) { // // The old API allocated only 64 bytes to each endpoint. // return(USBHCDPipeAllocSize(ui32Index, ui32EndpointType, psDevice, 64, pfnCallback)); } //***************************************************************************** // //! This function is used to configure a USB HCD pipe. //! //! This should be called after allocating a USB pipe with a call to //! USBHCDPipeAlloc(). It is used to set the configuration associated with an //! endpoint like the max payload and target endpoint. The \e ui32MaxPayload //! parameter is typically read directly from the devices endpoint descriptor //! and is expressed in bytes. //! //! Setting the \e ui32Interval parameter depends on the type of endpoint being //! configured. For endpoints that do not need to use the \e ui32Interval //! parameter \e ui32Interval should be set to 0. For Bulk \e ui32Interval is //! a value from 2-16 and will set the NAK timeout value as //! 2^(\e ui32Interval-1) frames. For interrupt endpoints \e ui32Interval is a //! value from 1-255 and is the count in frames between polling the endpoint. //! For isochronous endpoints \e ui32Interval ranges from 1-16 and is the //! polling interval in frames represented as 2^(\e ui32Interval-1) frames. //! //! \param ui32Pipe is the allocated endpoint to modify. //! \param ui32MaxPayload is maximum data that can be handled per transaction. //! \param ui32Interval is the polling interval for data transfers expressed in //! frames. //! \param ui32TargetEndpoint is the target endpoint on the device to //! communicate with. //! //! \return If the call was successful, this function returns zero any other //! value indicates an error. // //***************************************************************************** uint32_t USBHCDPipeConfig(uint32_t ui32Pipe, uint32_t ui32MaxPayload, uint32_t ui32Interval, uint32_t ui32TargetEndpoint) { uint32_t ui32Flags; uint32_t ui32Index; // // Get the index number from the allocated pipe. // ui32Index = (ui32Pipe & 0x0000ffff); // // Set the direction. // if(ui32Pipe & 0x00010000) { // // Set the mode for this endpoint. // if(g_sUSBHCD.psUSBOUTPipes[ui32Index].ui32Type & 0x00200000) { ui32Flags = 0x00000100; } else if(g_sUSBHCD.psUSBOUTPipes[ui32Index].ui32Type & 0x00400000) { ui32Flags = 0x00000200; } else if(g_sUSBHCD.psUSBOUTPipes[ui32Index].ui32Type & 0x00800000) { ui32Flags = 0x00000000; } else { ui32Flags = 0x00000300; } ui32Flags |= 0x00002000; g_sUSBHCD.psUSBOUTPipes[ui32Index].ui8EPNumber = (uint8_t)ui32TargetEndpoint; // // Save the interval and the next tick to trigger a scheduler event. // g_sUSBHCD.psUSBOUTPipes[ui32Index].ui32Interval = ui32Interval; g_sUSBHCD.psUSBOUTPipes[ui32Index].ui32NextEventTick = ui32Interval + g_ui32CurrentTick; // // Set the device speed. // ui32Flags |= (g_sUSBHCD.psUSBOUTPipes[ui32Index].psDevice->bLowSpeed ? 0x00000000 : 0x00001000); // // Set up the appropriate flags if uDMA is used. // if(ui32Pipe & 0x01000000) { ui32Flags |= 0x00000008 | 0x00000001; } } else { // // Set the mode for this endpoint. // if(g_sUSBHCD.psUSBINPipes[ui32Index].ui32Type & 0x00200000) { ui32Flags = 0x00000100; } else if(g_sUSBHCD.psUSBINPipes[ui32Index].ui32Type & 0x00400000) { ui32Flags = 0x00000200; } else if(g_sUSBHCD.psUSBINPipes[ui32Index].ui32Type & 0x00800000) { ui32Flags = 0x00000000; } else { ui32Flags = 0x00000300; } ui32Flags |= 0x00000000; g_sUSBHCD.psUSBINPipes[ui32Index].ui8EPNumber = (uint8_t)ui32TargetEndpoint; // // Save the interval and the next tick to trigger a scheduler event. // g_sUSBHCD.psUSBINPipes[ui32Index].ui32Interval = ui32Interval; g_sUSBHCD.psUSBINPipes[ui32Index].ui32NextEventTick = ui32Interval + g_ui32CurrentTick; // // Set the device speed. // ui32Flags |= (g_sUSBHCD.psUSBINPipes[ui32Index].psDevice->bLowSpeed ? 0x00000000 : 0x00001000); // // Set up the appropriate flags if uDMA is used. // if(ui32Pipe & 0x01000000) { ui32Flags |= 0x00000010 | 0x00000004 | 0x00000002; } } // // Configure the endpoint according to the flags determined above. // USBHostEndpointConfig(0x00040000, (((uint32_t)((ui32Pipe & 0x0000ffff) + 1) << 4) & 0xFF), ui32MaxPayload, ui32Interval, ui32TargetEndpoint, ui32Flags); return(0); } //***************************************************************************** // //! This function is used to return the current status of a USB HCD pipe. //! //! This function will return the current status for a given USB pipe. If //! there is no status to report this call will simply return //! \b USBHCD_PIPE_NO_CHANGE. //! //! \param ui32Pipe is the USB pipe for this status request. //! //! \return This function returns the current status for the given endpoint. //! This will be one of the \b USBHCD_PIPE_* values. // //***************************************************************************** uint32_t USBHCDPipeStatus(uint32_t ui32Pipe) { return(0); } //***************************************************************************** // //! This function is used to write data to a USB HCD pipe. //! //! \param ui32Pipe is the USB pipe to put data into. //! \param pui8Data is a pointer to the data to send. //! \param ui32Size is the amount of data to send. //! //! This function will block until it has sent as much data as was //! requested using the USB pipe's FIFO. The caller should have registered a //! callback with the USBHCDPipeAlloc() call in order to be informed when the //! data has been transmitted. The value returned by this function can be less //! than the \e ui32Size requested if the USB pipe has less space available //! than this request is making. //! //! \return This function returns the number of bytes that were scheduled to //! be sent on the given USB pipe. // //***************************************************************************** uint32_t USBHCDPipeWrite(uint32_t ui32Pipe, uint8_t *pui8Data, uint32_t ui32Size) { uint32_t ui32Endpoint, ui32RemainingBytes, ui32ByteToSend, ui32PipeIdx; _Bool bUseDMA; // // Determine which endpoint interface that this pipe is using. // ui32Endpoint = (((uint32_t)((0x0000ffff & ui32Pipe) + 1) << 4) & 0xFF); // // Get index used for looking up pipe data // ui32PipeIdx = ui32Pipe & 0x0000ffff; // // Set the total number of bytes to send out. // ui32RemainingBytes = ui32Size; // // Default to using DMA. // bUseDMA = 0; // // Initialize the bytes to send to all of the remaining bytes. // ui32ByteToSend = ui32RemainingBytes; // // Send all of the requested data. // while(ui32RemainingBytes != 0) { // // If uDMA is not enabled for this pipe, or if the uDMA workaround // is applied, then don't use uDMA for this transfer. // if(ui32Pipe & 0x01000000) { // // Disable the USB interrupt. // IntDisable(g_sUSBHCD . ui32IntNum); // // Start the DMA transfer. // if(g_sUSBHCD . psDMAInstance ->pfnTransfer(g_sUSBHCD . psDMAInstance, g_sUSBHCD . psUSBOUTPipes[ui32PipeIdx]. ui8DMAChannel, pui8Data, ui32RemainingBytes) != 0) { if(ui32RemainingBytes < 64) { g_sUSBHCD.psUSBOUTPipes[ui32PipeIdx].iState = ePipeWriteDMASend; } else if((ui32RemainingBytes % 64) == 0) { g_sUSBHCD.psUSBOUTPipes[ui32PipeIdx].iState = ePipeWriteDMA; } else { g_sUSBHCD.psUSBOUTPipes[ui32PipeIdx].iState = ePipeWriteDMASend; } bUseDMA = 1; } // // Enable the USB interrupt. // IntEnable(g_sUSBHCD . ui32IntNum); } if(bUseDMA == 0) { // // Only send 64 bytes at a time if not using DMA. // if (ui32RemainingBytes <= 64) { ui32ByteToSend = ui32RemainingBytes; } else { ui32ByteToSend = 64; } // // Start a write request. // g_sUSBHCD.psUSBOUTPipes[ui32PipeIdx].iState = ePipeWriting; // // Disable uDMA on the USB endpoint // USBEndpointDMADisable(0x00040000, ui32Endpoint, 0x00002000); // // Put the data in the buffer. // USBEndpointDataPut(0x00040000, ui32Endpoint, pui8Data, ui32ByteToSend); // // Schedule the data to be sent. // USBEndpointDataSend(0x00040000, ui32Endpoint, 0x00000102); } // // Wait for a status change. // while(1) { // // If an error event occurs then exit out of the loop. // if(g_sUSBHCD.ui32IntEvents & (0x04 | 0x01 | 0x08)) { // // Set the pipe state to error. // g_sUSBHCD.psUSBOUTPipes[ui32PipeIdx].iState = ePipeError; // // Needs to be set to exit out of large while loop. // ui32RemainingBytes = 0; break; } // // If the data was successfully sent then decrement the count and // continue. // else if(g_sUSBHCD.psUSBOUTPipes[ui32PipeIdx].iState == ePipeDataSent) { // // Decrement the remaining data and advance the pointer. // ui32RemainingBytes -= ui32ByteToSend; pui8Data += ui32ByteToSend; break; } else if(g_sUSBHCD.psUSBOUTPipes[ui32PipeIdx].iState == ePipeStalled) { // // Zero out the size so that the caller knows that no data was // written. // ui32Size = 0; // // Needs to be set to exit out of large while loop. // ui32RemainingBytes = 0; // // If DMA is being used, then disable the channel. // if(bUseDMA == 1) { // // Disable the DMA channel. // g_sUSBHCD . psDMAInstance ->pfnChannelDisable(g_sUSBHCD . psDMAInstance, g_sUSBHCD . psUSBOUTPipes[ui32PipeIdx]. ui8DMAChannel); } // // This is the actual endpoint number. // USBHCDClearFeature( g_sUSBHCD.psUSBOUTPipes[ui32PipeIdx].psDevice->ui32Address, ui32Pipe, 0x0000); // // If there was a stall, then no more data is coming so break // out. // break; } else if(g_sUSBHCD.psUSBOUTPipes[ui32PipeIdx].iState == ePipeError) { // // An error occurred so stop this transaction and set the // number of bytes to zero. // ui32Size = 0; // // Needs to be set to exit out of large while loop. // ui32RemainingBytes = 0; break; } } } // // Go Idle once this state has been reached. // g_sUSBHCD.psUSBOUTPipes[ui32PipeIdx].iState = ePipeIdle; return(ui32Size); } //***************************************************************************** // //! This function is used to schedule and IN transaction on a USB HCD pipe. //! //! \param ui32Pipe is the USB pipe to read data from. //! \param pui8Data is a pointer to store the data that is received. //! \param ui32Size is the size in bytes of the buffer pointed to by //! \e pui8Data. //! //! This function will not block depending on the type of pipe passed in will //! schedule either a send of data to the device or a read of data from the //! device. In either case the amount of data will be limited to what will //! fit in the FIFO for a given endpoint. //! //! \return This function returns the number of bytes that were sent in the //! case of a transfer of data or it will return 0 for a request on a USB IN //! pipe. // //***************************************************************************** uint32_t USBHCDPipeSchedule(uint32_t ui32Pipe, uint8_t *pui8Data, uint32_t ui32Size) { uint32_t ui32Endpoint, ui32PipeIdx; // // Get index used for looking up pipe data // ui32PipeIdx = ui32Pipe & 0x0000ffff; // // Determine which endpoint interface that this pipe is using. // ui32Endpoint = (((uint32_t)((0x0000ffff & ui32Pipe) + 1) << 4) & 0xFF); if(ui32Pipe & 0x00010000) { // // Check if uDMA is enabled on this pipe. // if(ui32Pipe & 0x01000000) { // // Start a write request. // g_sUSBHCD.psUSBOUTPipes[0x0000ffff & ui32Pipe].iState = ePipeWriteDMASend; g_sUSBHCD . psDMAInstance ->pfnTransfer(g_sUSBHCD . psDMAInstance, g_sUSBHCD . psUSBOUTPipes[ui32PipeIdx]. ui8DMAChannel, pui8Data, ui32Size); } else { // // Start a write request. // g_sUSBHCD.psUSBOUTPipes[0x0000ffff & ui32Pipe].iState = ePipeWriting; // // Put the data in the buffer. // USBEndpointDataPut(0x00040000, ui32Endpoint, pui8Data, ui32Size); // // Schedule the data to be sent. // USBEndpointDataSend(0x00040000, ui32Endpoint, 0x00000102); } } else { // // If uDMA is not enabled for this pipe, or if the uDMA workaround // is applied, then do not use uDMA for this transfer. // if((ui32Pipe & 0x01000000) == 0) { // // Start a read request. // g_sUSBHCD.psUSBINPipes[0x0000ffff & ui32Pipe].iState = ePipeReading; // // Disable uDMA on the endpoint // USBEndpointDMADisable(0x00040000, ui32Endpoint, 0x00000000); } // // Otherwise, uDMA should be used for this transfer, so set up // the uDMA channel in advance of triggering the IN request. // else { g_sUSBHCD.psUSBINPipes[0x0000ffff & ui32Pipe].iState = ePipeReadDMA; g_sUSBHCD . psDMAInstance ->pfnTransfer(g_sUSBHCD . psDMAInstance, g_sUSBHCD . psUSBINPipes[ui32PipeIdx]. ui8DMAChannel, pui8Data, ui32Size); } // // Remember details of the buffer into which the data will be read. // g_sUSBHCD.psUSBINPipes[ui32PipeIdx].pui8ReadPtr = pui8Data; g_sUSBHCD.psUSBINPipes[ui32PipeIdx].ui32ReadSize = ui32Size; // // Trigger a request for data from the device. // USBHostRequestIN(0x00040000, ui32Endpoint); // // No data was put into or read from the buffer. // ui32Size = 0; } return(ui32Size); } //***************************************************************************** // //! This function is used to read data from a USB HCD pipe. //! //! \param ui32Pipe is the USB pipe to read data from. //! \param pui8Data is a pointer to store the data that is received. //! \param ui32Size is the size in bytes of the buffer pointed to by //! \e pui8Data. //! //! This function will not block and will only read as much data as requested //! or as much data is currently available from the USB pipe. The caller //! should have registered a callback with the USBHCDPipeAlloc() call in order //! to be informed when the data has been received. The value returned by this //! function can be less than the \e ui32Size requested if the USB pipe has //! less data available than was requested. //! //! \return This function returns the number of bytes that were returned in the //! \e pui8Data buffer. // //***************************************************************************** uint32_t USBHCDPipeReadNonBlocking(uint32_t ui32Pipe, uint8_t *pui8Data, uint32_t ui32Size) { uint32_t ui32Endpoint; // // Determine which endpoint interface that this pipe is using. // ui32Endpoint = (((uint32_t)((0x0000ffff & ui32Pipe) + 1) << 4) & 0xFF); // // Read the data out of the USB endpoint interface. // USBEndpointDataGet(0x00040000, ui32Endpoint, pui8Data, &ui32Size); // // Acknowledge that the data was read from the endpoint. // USBHostEndpointDataAck(0x00040000, ui32Endpoint); // // Go Idle once this state has been reached. // g_sUSBHCD.psUSBINPipes[0x0000ffff & ui32Pipe].iState = ePipeIdle; return(ui32Size); } //***************************************************************************** // //! This function acknowledges data received via an interrupt IN pipe. //! //! \param ui32Pipe is the USB INT pipe whose last packet is to be //! acknowledged. //! //! This function is used to acknowledge reception of data on an interrupt IN //! pipe. A transfer on an interrupt IN endpoint is scheduled via a call to //! USBHCDPipeSchedule() and the application is notified when data is received //! using a USB_EVENT_RX_AVAILABLE event. In the handler for this event, the //! application must call USBHCDPipeDataAck() to have the USB controller ACK //! the data from the device and complete the transaction. //! //! \return None. // //***************************************************************************** void USBHCDPipeDataAck(uint32_t ui32Pipe) { uint32_t ui32Endpoint; // // Determine which endpoint interface that this pipe is using. // ui32Endpoint = (((uint32_t)((0x0000ffff & ui32Pipe) + 1) << 4) & 0xFF); // // Acknowledge that the data was read from the endpoint. // USBHostEndpointDataAck(0x00040000, ui32Endpoint); // // Go Idle once this state has been reached. // g_sUSBHCD.psUSBINPipes[0x0000ffff & ui32Pipe].iState = ePipeIdle; } //***************************************************************************** // //! This function is used to read data from a USB HCD pipe. //! //! \param ui32Pipe is the USB pipe to read data from. //! \param pui8Data is a pointer to store the data that is received. //! \param ui32Size is the size in bytes of the buffer pointed to by //! \e pui8Data. //! //! This function will block and will only return when it has read as much data //! as requested from the USB pipe. The caller must register a callback with //! the USBHCDPipeAlloc() call in order to be informed when the data has been //! received. If the caller provides a non-zero pointer in the \e pui8Data //! parameter then the data is copied into the buffer before the callback //! occurs. If the caller provides a zero in \e pui8Data parameter //! then the caller is responsible for reading the data out of the FIFO when //! the \b USB_EVENT_RX_AVAILABLE callback event occurs. The value returned //! by this function can be less than the \e ui32Size requested if the USB pipe //! has less data available than was requested. //! //! \return This function returns the number of bytes that were returned in the //! \e pui8Data buffer. // //***************************************************************************** uint32_t USBHCDPipeRead(uint32_t ui32Pipe, uint8_t *pui8Data, uint32_t ui32Size) { uint32_t ui32Endpoint, ui32RemainingBytes, ui32BytesRead, ui32PipeIdx; _Bool bUseDMA; // // Get index used for looking up pipe data // ui32PipeIdx = ui32Pipe & 0x0000ffff; // // Initialized the number of bytes read. // ui32BytesRead = 0; // // Determine which endpoint interface that this pipe is using. // ui32Endpoint = (((uint32_t)(ui32PipeIdx + 1) << 4) & 0xFF); // // Set the remaining bytes to received. // ui32RemainingBytes = ui32Size; // // Default to using DMA. // if(ui32Pipe & 0x01000000){ bUseDMA = 1; }else{ bUseDMA = 0; } // // Continue until all data requested has been received. // while(ui32RemainingBytes != 0) { // // Start a read request. // g_sUSBHCD.psUSBINPipes[ui32PipeIdx].iState = ePipeReading; // // Try the DMA transfer should be used for this transfer, so set up // the uDMA channel in advance of triggering the IN request. // if(ui32Pipe & 0x01000000) { // // Disable the USB interrupt. // IntDisable(g_sUSBHCD . ui32IntNum); if(g_sUSBHCD . psDMAInstance ->pfnTransfer(g_sUSBHCD . psDMAInstance, g_sUSBHCD . psUSBINPipes[ui32PipeIdx]. ui8DMAChannel, pui8Data, ui32Size) != 0) { g_sUSBHCD.psUSBINPipes[ui32PipeIdx].iState = ePipeReadDMA; ui32BytesRead = ui32Size; } else { bUseDMA = 0; } // // Disable the USB interrupt. // IntEnable(g_sUSBHCD . ui32IntNum); } // // If unable to use DMA then get ready to transfer without DMA. // if(bUseDMA == 0) { // // Disable uDMA on the endpoint // USBEndpointDMADisable(0x00040000, ui32Endpoint, 0x00000000); // // Set up for the next transaction. // g_sUSBHCD.psUSBINPipes[ui32PipeIdx].pui8ReadPtr = pui8Data; g_sUSBHCD.psUSBINPipes[ui32PipeIdx].ui32ReadSize = (ui32RemainingBytes < 64) ? ui32RemainingBytes : 64; } // // Trigger a request for data from the device. // USBHostRequestIN(0x00040000, ui32Endpoint); // // Wait for a status change. // while(1) { // // Check if the device stalled the request. // if(g_sUSBHCD.psUSBINPipes[ui32PipeIdx].iState == ePipeStalled) { // // Zero out the size so that the caller knows that no data was // read. // ui32Size = 0; // // There are also no remaining bytes to read. // ui32RemainingBytes = 0; // // If DMA is being used, then disable the channel. // if(bUseDMA == 1) { g_sUSBHCD . psDMAInstance ->pfnChannelDisable(g_sUSBHCD . psDMAInstance, g_sUSBHCD . psUSBINPipes[ui32PipeIdx]. ui8DMAChannel); } // // This is the actual endpoint number. // USBHCDClearFeature( g_sUSBHCD.psUSBINPipes[ui32PipeIdx].psDevice->ui32Address, ui32Pipe, 0x0000); // // If there was a stall, then no more data is coming so break // out. // break; } // // If any error event occurs then exit out of the loop. // if(g_sUSBHCD.ui32IntEvents & (0x04 | 0x01 | 0x08)) { // // Set the pipe state to error. // g_sUSBHCD.psUSBINPipes[ui32PipeIdx].iState = ePipeError; break; } // // If data is ready then return it. // if(g_sUSBHCD.psUSBINPipes[ui32PipeIdx].iState == ePipeDataReady) { // // If not using DMA then read the data from the USB. Otherwise // the data will already be in the buffer. // if(bUseDMA == 0) { // // Compute bytes to transfer and set up transfer // ui32BytesRead = ui32RemainingBytes > 64 ? 64 : ui32RemainingBytes; // // Acknowledge that the data was read from the endpoint. // USBHostEndpointDataAck(0x00040000, ui32Endpoint); } // // Subtract the number of bytes read from the bytes remaining. // ui32RemainingBytes -= ui32BytesRead; // // If there were less than 64 bytes read, then this was a short // packet and no more data will be returned. // if(ui32BytesRead < 64) { // // Subtract off the bytes that were not received and exit // the loop. // ui32Size = ui32Size - ui32RemainingBytes; break; } else { // // Move the buffer ahead to receive more data into the // buffer. // pui8Data += 64; } break; } else if(g_sUSBHCD.psUSBINPipes[ui32PipeIdx].iState == ePipeError) { // // An error occurred so stop this transaction and set the // number of bytes to zero. // ui32Size = 0; ui32RemainingBytes = 0; break; } else if((g_sUSBHCD.psUSBINPipes[ui32PipeIdx].iState == ePipeReadDMAWait) && (g_sUSBHCD . psDMAInstance ->pfnChannelStatus(g_sUSBHCD . psDMAInstance, g_sUSBHCD . psUSBINPipes[ui32PipeIdx]. ui8DMAChannel) & 0x00000001)) { break; } } } // // Go Idle once this state has been reached. // g_sUSBHCD.psUSBINPipes[ui32PipeIdx].iState = ePipeIdle; return(ui32Size); } //***************************************************************************** // //! This function is used to release a USB pipe. //! //! \param ui32Pipe is the allocated USB pipe to release. //! //! This function is used to release a USB pipe that was allocated by a call to //! USBHCDPipeAlloc() for use by some other device endpoint in the system. //! Freeing an unallocated or invalid pipe will not generate an error and will //! instead simply return. //! //! \return None. // //***************************************************************************** void USBHCDPipeFree(uint32_t ui32Pipe) { uint32_t ui32Index; // // Get the index number from the allocated pipe. // ui32Index = (ui32Pipe & 0x0000ffff); if(ui32Pipe & 0x00010000) { // // Clear the address and type for this endpoint to free it up. // g_sUSBHCD.psUSBOUTPipes[ui32Index].psDevice = 0; g_sUSBHCD.psUSBOUTPipes[ui32Index].ui32Type = 0; g_sUSBHCD.psUSBOUTPipes[ui32Index].pfnCallback = 0; // // Check if this pipe has allocated a DMA channel. // if(g_sUSBHCD.psUSBOUTPipes[ui32Index].ui8DMAChannel != 0xff) { // // Release the DMA channel associated with this endpoint. // g_sUSBHCD . psDMAInstance ->pfnChannelRelease(g_sUSBHCD . psDMAInstance, g_sUSBHCD . psUSBOUTPipes[ui32Index]. ui8DMAChannel); // // Clear out the current channel in use by this pipe. // g_sUSBHCD.psUSBOUTPipes[ui32Index].ui8DMAChannel = 0xff; } // // Free up the FIFO memory used by this endpoint. // if(g_sUSBHCD.psUSBOUTPipes[ui32Index].ui8FIFOSize) { FIFOFree(&g_sUSBHCD.psUSBOUTPipes[ui32Index]); } // // Set the function address for this endpoint back to zero. // USBHostAddrSet(0x00040000, (((uint32_t)(ui32Index + 1) << 4) & 0xFF), 0, 0x00002000); // // Set the hub and port address for the endpoint back to zero and the // speed back to LOW. // USBHostHubAddrSet(0x00040000, (((uint32_t)(ui32Index + 1) << 4) & 0xFF), 0, (0x00002000 | 0x00000000)); } else if(ui32Pipe & 0x00020000) { // // Clear the address and type for this endpoint to free it up. // g_sUSBHCD.psUSBINPipes[ui32Index].psDevice = 0; g_sUSBHCD.psUSBINPipes[ui32Index].ui32Type = 0; g_sUSBHCD.psUSBINPipes[ui32Index].pfnCallback = 0; // // Check if this pipe has allocated a DMA channel. // if(g_sUSBHCD.psUSBINPipes[ui32Index].ui8DMAChannel != 0xff) { // // Release the DMA channel associated with this endpoint. // g_sUSBHCD . psDMAInstance ->pfnChannelRelease(g_sUSBHCD . psDMAInstance, g_sUSBHCD . psUSBINPipes[ui32Index]. ui8DMAChannel); // // Clear out the current channel in use by this pipe. // g_sUSBHCD.psUSBINPipes[ui32Index].ui8DMAChannel = 0xff; } // // Free up the FIFO memory used by this endpoint. // if(g_sUSBHCD.psUSBINPipes[ui32Pipe & 0x0000ffff].ui8FIFOSize) { FIFOFree(&g_sUSBHCD.psUSBINPipes[ui32Pipe & 0x0000ffff]); } // // Set the function address for this endpoint back to zero. // USBHostAddrSet(0x00040000, (((uint32_t)(ui32Index + 1) << 4) & 0xFF), 0, 0x00000000); // // Set the hub and port address for the endpoint back to zero and the // speed back to LOW. // USBHostHubAddrSet(0x00040000, (((uint32_t)(ui32Index + 1) << 4) & 0xFF), 0, (0x00000000 | 0x00000000)); // // Clear any pending IN transactions. // USBHostRequestINClear(0x00040000, (((uint32_t)(ui32Index + 1) << 4) & 0xFF)); } } //***************************************************************************** // // This internal function initializes the HCD code. // // \param ui32Index specifies which USB controller to use. // \param pvPool is a pointer to the data to use as a memory pool for this // controller. // \param ui32PoolSize is the size in bytes of the buffer passed in as pvPool. // // This function will perform all the necessary operations to allow the USB // host controller to begin enumeration and communication with a device. This // function should typically be called once at the start of an application // before any other calls are made to the host controller. // // \return None. // //***************************************************************************** static void USBHCDInitInternal(uint32_t ui32Index, void *pvPool, uint32_t ui32PoolSize) { int32_t i32Idx; { if(!(ui32Index == 0)) { __error__("../USB/host/usbhostenum.c", 2366); } }; // // Get the number of endpoints supported by this device. // g_sUSBHCD.ui32NumEndpoints = USBNumEndpointsGet(0x00040000); // // The first 64 Bytes are allocated to endpoint 0. // g_pui32Alloc[0] = 1; g_pui32Alloc[1] = 0; // // Save the base address for this controller. // g_sUSBHCD.ui32USBBase = 0x00040000; // // Save the USB interrupt number. // g_sUSBHCD.ui32IntNum = 0xC6090F; // // All Pipes are unused at start. // for(i32Idx = 0; i32Idx < 15; i32Idx++) { g_sUSBHCD.psUSBINPipes[i32Idx].psDevice = 0; g_sUSBHCD.psUSBINPipes[i32Idx].ui32Type = 0x00100000; g_sUSBHCD.psUSBINPipes[i32Idx].ui8DMAChannel = 0xff; g_sUSBHCD.psUSBOUTPipes[i32Idx].psDevice = 0; g_sUSBHCD.psUSBOUTPipes[i32Idx].ui32Type = 0x00100000; g_sUSBHCD.psUSBOUTPipes[i32Idx].ui8DMAChannel = 0xff; } // // Make sure that the hub driver is initialized since it is called even // if it is not present in the system. // USBHHubInit(); // // Initialize the DMA interface. // g_sUSBHCD.psDMAInstance = USBLibDMAInit(g_sUSBHCD.ui32USBBase); // // Initialized the device structures. // for(i32Idx = 0; i32Idx <= 5; i32Idx++) { // // Clear the configuration descriptor and state. // g_sUSBHCD.piDeviceState[i32Idx] = eHCDIdle; g_sUSBHCD.psUSBDevice[i32Idx].psConfigDescriptor = 0; g_sUSBHCD.psUSBDevice[i32Idx].bConfigRead = 0; // // Initialize the device descriptor. // g_sUSBHCD.psUSBDevice[i32Idx].sDeviceDescriptor.bLength = 0; g_sUSBHCD.psUSBDevice[i32Idx].sDeviceDescriptor.bMaxPacketSize0 = 0; // // Initialize the device address. // g_sUSBHCD.psUSBDevice[i32Idx].ui32Address = 0; // // Set the current interface to 0. // g_sUSBHCD.psUSBDevice[i32Idx].ui32Interface = 0; // // Clear the active driver for the device. // g_pi32USBHActiveDriver[i32Idx] = -1; // // Initialize the device flags. // g_sUSBHCD.psUSBDevice[i32Idx].ui32Flags = 0; } // // Allocate the memory needed for reading descriptors. // g_sUSBHCD.pvPool = pvPool; g_sUSBHCD.ui32PoolSize = ui32PoolSize; // // Initialize the device class. // g_sUSBHCD.ui32Class = 0xffffffff; // // Default enable connect, disconnect, unknown device and power fault // event notifications. // g_sUSBHCD.ui32EventEnables = 0x00000002 | 0x00000004 | 0x00000008 | 0x00000010 | 0x00000040 | 0x00000020; // // Initialize the USB tick module. // InternalUSBTickInit(); // // Only do hardware update if the stack is in Host mode, do not touch the // hardware for OTG mode operation. // if((g_iUSBMode == eUSBModeHost) || (g_iUSBMode == eUSBModeForceHost)) { // // Configure the End point 0. // USBHostEndpointConfig(0x00040000, 0x00000000, 64, 0, 0, (0x00000300 | 0x00001000 | 0x00002000)); // // Enable USB Interrupts. // USBIntEnableControl(0x00040000, 0x00000004 | 0x00000020 | 0x00000008 | 0x00000040 | 0x00000004 | 0x00000010 | 0x00000002 | 0x00000001 | 0x00000080 | 0x00000200 | 0x00000100); USBIntEnableEndpoint(0x00040000, 0xFFFFFFFF); // // Enable the USB interrupt. // IntEnable(g_sUSBHCD . ui32IntNum); // // There is no automatic power in pure host mode. // USBHCDPowerConfigSet(ui32Index, (g_ui32PowerConfig & ~0x00000002)); // // Force the power on as well as this point. // USBHostPwrEnable(0x00040000); // // This is required to get into host mode on some parts. // USBOTGSessionRequest(0x00040000, 1); } } //***************************************************************************** // //! This function is used to set the power pin and power fault configuration. //! //! \param ui32Index specifies which USB controller to use. //! \param ui32PwrConfig is the power configuration to use for the application. //! //! This function must be called before HCDInit() is called so that the power //! pin configuration can be set before power is enabled. The \e ui32PwrConfig //! flags specify the power fault level sensitivity, the power fault action, //! and the power enable pin level and source. //! //! One of the following can be selected as the power fault level sensitivity: //! //! - \b USBHCD_FAULT_LOW - An external power fault is indicated by the pin //! being driven low. //! - \b USBHCD_FAULT_HIGH - An external power fault is indicated by the pin //! being driven high. //! //! One of the following can be selected as the power fault action: //! //! - \b USBHCD_FAULT_VBUS_NONE - No automatic action when power fault //! detected. //! - \b USBHCD_FAULT_VBUS_TRI - Automatically Tri-state the USBnEPEN pin on a //! power fault. //! - \b USBHCD_FAULT_VBUS_DIS - Automatically drive the USBnEPEN pin to it's //! inactive state on a power fault. //! //! One of the following can be selected as the power enable level and source: //! //! - \b USBHCD_VBUS_MANUAL - Power control is completely managed by the //! application, the USB library will provide a //! power callback to request power state changes. //! - \b USBHCD_VBUS_AUTO_LOW - USBEPEN is driven low by the USB controller //! automatically if USBOTGSessionRequest() has //! enabled a session. //! - \b USBHCD_VBUS_AUTO_HIGH - USBEPEN is driven high by the USB controller //! automatically if USBOTGSessionRequest() has //! enabled a session. //! //! If USBHCD_VBUS_MANUAL is used then the application must provide an //! event driver to receive the USB_EVENT_POWER_ENABLE and //! USB_EVENT_POWER_DISABLE events and enable and disable power to VBUS when //! requested by the USB library. The application should respond to a power //! control callback by enabling or disabling VBUS as soon as possible and //! before returning from the callback function. //! //! \note The following values should no longer be used with the USB //! library: \b USB_HOST_PWRFLT_LOW, \b USB_HOST_PWRFLT_HIGH, //! \b USB_HOST_PWRFLT_EP_NONE, \b USB_HOST_PWRFLT_EP_TRI, //! \b USB_HOST_PWRFLT_EP_LOW, \b USB_HOST_PWRFLT_EP_HIGH, //! \b USB_HOST_PWREN_LOW, \b USB_HOST_PWREN_HIGH, \b USB_HOST_PWREN_VBLOW, and //! \b USB_HOST_PWREN_VBHIGH. //! //! \return None. // //***************************************************************************** void USBHCDPowerConfigInit(uint32_t ui32Index, uint32_t ui32PwrConfig) { { if(!(ui32Index == 0)) { __error__("../USB/host/usbhostenum.c", 2592); } }; // // Save the value as it will be used later. // g_ui32PowerConfig = ui32PwrConfig; } //***************************************************************************** // //! This function is used to get the power pin and power fault configuration. //! //! \param ui32Index specifies which USB controller to use. //! //! This function will return the current power control pin configuration as //! set by the USBHCDPowerConfigInit() function or the defaults if not yet set. //! See the USBHCDPowerConfigInit() documentation for the meaning of the bits //! that are returned by this function. //! //! \return The configuration of the power control pins. //! //***************************************************************************** uint32_t USBHCDPowerConfigGet(uint32_t ui32Index) { { if(!(ui32Index == 0)) { __error__("../USB/host/usbhostenum.c", 2617); } }; // // Save the value as it will be used later. // return(g_ui32PowerConfig); } //***************************************************************************** // //! This function is used to set the power pin and power fault configuration. //! //! \param ui32Index specifies which USB controller to use. //! \param ui32Config specifies which USB power configuration to use. //! //! This function will set the current power control pin configuration as //! set by the USBHCDPowerConfigInit() function or the defaults if not yet set. //! See the USBHCDPowerConfigInit() documentation for the meaning of the bits //! that are set by this function. //! //! \return Returns zero to indicate the power setting is now active. //! //***************************************************************************** uint32_t USBHCDPowerConfigSet(uint32_t ui32Index, uint32_t ui32Config) { { if(!(ui32Index == 0)) { __error__("../USB/host/usbhostenum.c", 2643); } }; // // Remember the current setting. // g_ui32PowerConfig = ui32Config; // // Clear out the two flag bits. // ui32Config = g_ui32PowerConfig & ~(0x00000004 | 0x00000400); // // If there is an automatic disable power action specified then set the // polarity of the signal to match EPEN. // if(g_ui32PowerConfig & 0x00000400) { // // Insure that the assumption below is true. // { if(!((0x00000003 & 1) == 1)) { __error__("../USB/host/usbhostenum.c", 2665); } }; { if(!((0x00000002 & 1) == 0)) { __error__("../USB/host/usbhostenum.c", 2666); } }; // // This is taking advantage of the difference between // USBHCD_VBUS_AUTO_LOW and USBHCD_VBUS_AUTO_HIGH being that bit // one is set when EPEN is active high. // if(g_ui32PowerConfig & 1) { g_ui32PowerConfig |= 0x00000240; ui32Config |= 0x00000240; } else { g_ui32PowerConfig |= 0x00000340; ui32Config |= 0x00000340; } } // // Initialize the power configuration. // USBHostPwrConfig(0x00040000, ui32Config); // // If not in manual mode then just turn on power. // if((g_ui32PowerConfig & 0x00000004) == 0) { // // Power the USB bus. // USBHostPwrEnable(0x00040000); } // // Return success. // return(0); } //***************************************************************************** // //! This function returns if the current power settings will automatically //! handle enabling and disabling VBUS power. //! //! \param ui32Index specifies which USB controller to query. //! //! This function returns if the current power control pin configuration will //! automatically apply power or whether it will be left to the application //! to turn on power when it is notified. //! //! \return A non-zero value indicates that power is automatically applied and //! a value of zero indicates that the application must manually apply power. //! //***************************************************************************** uint32_t USBHCDPowerAutomatic(uint32_t ui32Index) { // // Check if the controller is automatically applying power or not. // if(g_ui32PowerConfig & 0x00000004) { return(0); } return(1); } //***************************************************************************** // //! This function is used to initialize the HCD code. //! //! \param ui32Index specifies which USB controller to use. //! \param pvPool is a pointer to the data to use as a memory pool for this //! controller. //! \param ui32PoolSize is the size in bytes of the buffer passed in as //! \e pvPool. //! //! This function will perform all the necessary operations to allow the USB //! host controller to begin enumeration and communication with devices. This //! function should typically be called once at the start of an application //! once all of the device and class drivers are ready for normal operation. //! This call will start up the USB host controller and any connected device //! will immediately start the enumeration sequence. //! //! The USBStackModeSet() function can be called with eUSBModeHost in order to //! cause the USB library to force the USB operating mode to a host controller. //! This allows the application to used the USBVBUS and USBID pins as GPIOs on //! devices that support forcing OTG to operate as a host only controller. By //! default the USB library will assume that the USBVBUS and USBID pins are //! configured as USB pins and not GPIOs. //! //! The memory pool passed to this function must be at least as large as a //! typical configuration descriptor for devices that are to be supported. //! This value is application-dependent however it should never be less than 32 //! bytes and, in most cases, should be at least 64 bytes. If there is not //! sufficient memory to load a configuration descriptor from a device, the //! device will not be recognized by the USB library's host controller driver. //! //! \return None. // //***************************************************************************** void USBHCDInit(uint32_t ui32Index, void *pvPool, uint32_t ui32PoolSize) { int32_t i32Driver; // // Check the arguments. // { if(!(ui32Index == 0)) { __error__("../USB/host/usbhostenum.c", 2777); } }; // // Make sure there is at least enough to read the configuration descriptor. // { if(!(ui32PoolSize >= sizeof(tConfigDescriptor))) { __error__("../USB/host/usbhostenum.c", 2782); } }; // // Should not call this if the stack is in device mode. // { if(!(g_iUSBMode != eUSBModeDevice)) { __error__("../USB/host/usbhostenum.c", 2787); } }; { if(!(g_iUSBMode != eUSBModeForceDevice)) { __error__("../USB/host/usbhostenum.c", 2788); } }; // // If the mode was not set then default to eUSBModeHost. // if(g_iUSBMode == eUSBModeNone) { g_iUSBMode = eUSBModeHost; } // // Reset the USB controller. // SysCtlPeripheralReset(0x0010000B); // // Enable Clocking to the USB controller. // SysCtlPeripheralEnable(0x0010000B); // // Turn on USB Phy clock. // SysCtlUSBPLLEnable(); // // If the application not requesting OTG mode then set the mode to forced // host mode. If the mode is actually eUSBModeHost, this will be switched // off when ID pin detection is complete and the ID is no longer in use. // if(g_iUSBMode != eUSBModeOTG) { // // Force Host mode on devices that support force host mode. // USBHostMode(0x00040000); } // // Call our internal function to perform the initialization. // USBHCDInitInternal(ui32Index, pvPool, ui32PoolSize); // // No event driver is present by default. // g_sUSBHCD.i32EventDriver = -1; // // Search through the Host Class driver list for the devices class. // for(i32Driver = 0; i32Driver < g_sUSBHCD.ui32NumClassDrivers; i32Driver++) { if(g_sUSBHCD.ppsClassDrivers[i32Driver]->ui32InterfaceClass == 0xffffffff) { // // Event driver was found so remember it. // g_sUSBHCD.i32EventDriver = i32Driver; } } // // Get the number of ticks per millisecond, this is only used by blocking // delays using the SysCtlDelay() function. // g_ui32Tickms = SysCtlClockGet(20000000) / 3000; } //***************************************************************************** // //! This function is used to initialize the HCD class driver list. //! //! \param ui32Index specifies which USB controller to use. //! \param ppsHClassDrvs is an array of host class drivers that are //! supported on this controller. //! \param ui32NumDrivers is the number of entries in the \e pHostClassDrivers //! array. //! //! This function will set the host classes supported by the host controller //! specified by the \e ui32Index parameter. This function should be called //! before enabling the host controller driver with the USBHCDInit() function. //! //! \return None. // //***************************************************************************** void USBHCDRegisterDrivers(uint32_t ui32Index, const tUSBHostClassDriver * const *ppsHClassDrvs, uint32_t ui32NumDrivers) { { if(!(ui32Index == 0)) { __error__("../USB/host/usbhostenum.c", 2880); } }; // // Save the class drivers. // g_sUSBHCD.ppsClassDrivers = ppsHClassDrvs; // // Save the number of class drivers. // g_sUSBHCD.ui32NumClassDrivers = ui32NumDrivers; } //***************************************************************************** // //! This function is used to terminate the HCD code. //! //! \param ui32Index specifies which USB controller to release. //! //! This function will clean up the USB host controller and disable it in //! preparation for shutdown or a switch to USB device mode. Once this call is //! made, \e USBHCDInit() may be called to reinitialize the controller and //! prepare for host mode operation. //! //! \return None. // //***************************************************************************** void USBHCDTerm(uint32_t ui32Index) { int32_t i32Idx; { if(!(ui32Index == 0)) { __error__("../USB/host/usbhostenum.c", 2912); } }; // // End the session. // USBOTGSessionRequest(0x00040000, 0); // // Remove power from the USB bus. // USBHostPwrDisable(0x00040000); // // Disable USB interrupts. // IntDisable(g_sUSBHCD . ui32IntNum); USBIntDisableControl(0x00040000, 0x000003FF); USBIntDisableEndpoint(0x00040000, 0xFFFFFFFF); // // Set the host controller state back to it's initial values. // for(i32Idx = 0; i32Idx < 15; i32Idx++) { g_sUSBHCD.psUSBINPipes[i32Idx].ui32Type = 0x00100000; g_sUSBHCD.psUSBOUTPipes[i32Idx].ui32Type = 0x00100000; } // // Free the memory used by the configuration descriptor. // ConfigDescFree(&g_sUSBHCD.psUSBDevice[0]); g_sUSBHCD.piDeviceState[0] = eHCDIdle; g_sUSBHCD.psUSBDevice[0].psConfigDescriptor = 0; g_sUSBHCD.psUSBDevice[0].bConfigRead = 0; g_sUSBHCD.psUSBDevice[0].sDeviceDescriptor.bLength = 0; g_sUSBHCD.psUSBDevice[0].sDeviceDescriptor.bMaxPacketSize0 = 0; g_sUSBHCD.psUSBDevice[0].ui32Address = 0; g_sUSBHCD.psUSBDevice[0].ui32Interface = 0; g_sUSBHCD.pvPool = 0; g_sUSBHCD.ui32PoolSize = 0; } //***************************************************************************** // //! This function generates reset signaling on the USB bus. //! //! \param ui32Index specifies which USB controller to use. //! //! This function handles sending out reset signaling on the USB bus. After //! returning from this function, any attached device on the USB bus should //! have returned to it's reset state. //! //! \return None. // //***************************************************************************** void USBHCDReset(uint32_t ui32Index) { { if(!(ui32Index == 0)) { __error__("../USB/host/usbhostenum.c", 2974); } }; // // Start the reset signaling. // USBHostReset(0x00040000, 1); // // Wait 20ms // SysCtlDelay(g_ui32Tickms * 20); // // End reset signaling on the bus. // USBHostReset(0x00040000, 0); // // Need to wait at least 10ms to let the device recover from // the reset. This is the delay specified in the USB 2.0 spec. // We will hold the reset for 20ms. // SysCtlDelay(g_ui32Tickms * 20); } //***************************************************************************** // //! This function will generate suspend signaling on the USB bus. //! //! \param ui32Index specifies which USB controller to use. //! //! This function is used to generate suspend signaling on the USB bus. In //! order to leave the suspended state, the application should call //! USBHCDResume(). //! //! \return None. // //***************************************************************************** void USBHCDSuspend(uint32_t ui32Index) { { if(!(ui32Index == 0)) { __error__("../USB/host/usbhostenum.c", 3015); } }; // // Start the suspend signaling. // USBHostSuspend(0x00040000); } //***************************************************************************** // //! This function will generate resume signaling on the USB bus. //! //! \param ui32Index specifies which USB controller to use. //! //! This function is used to generate resume signaling on the USB bus in order //! to cause USB devices to leave their suspended state. This call should //! not be made unless a preceding call to USBHCDSuspend() has been made. //! //! \return None. // //***************************************************************************** void USBHCDResume(uint32_t ui32Index) { { if(!(ui32Index == 0)) { __error__("../USB/host/usbhostenum.c", 3039); } }; // // Start the resume signaling. // USBHostResume(0x00040000, 1); // // Wait 100ms // SysCtlDelay(g_ui32Tickms * 100); // // End reset signaling on the bus. // USBHostResume(0x00040000, 0); } //***************************************************************************** // //! This function issues a request for the current configuration descriptor //! from a device. //! //! \param ui32Index specifies which USB controller to use. //! \param psDevice is a pointer to the device structure that holds the buffer //! to store the configuration descriptor. //! //! This function will request the configuration descriptor from the device. //! The \e psDevice->ConfigDescriptor member variable is used to hold the data //! for this request. This buffer will be allocated from the pool provided by //! the HCDInit() function. \e psDevice->sDeviceDescriptor.bMaxPacketSize0 //! should be valid prior to this call in order to correctly receive the //! configuration descriptor. If this variable is not valid then this call //! will not return accurate data. //! //! \return The number of bytes returned due to the request. This value can be //! zero if the device did not respond. // //***************************************************************************** static uint32_t USBHCDGetConfigDescriptor(uint32_t ui32Index, tUSBHostDevice *psDevice) { tUSBRequest sSetupPacket; uint32_t ui32Bytes; tConfigDescriptor sConfigDescriptor; { if(!(ui32Index == 0)) { __error__("../USB/host/usbhostenum.c", 3085); } }; ui32Bytes = 0; // // This is a Standard Device IN request. // sSetupPacket.bmRequestType = 0x80 | 0x00 | 0x00; // // Request a Device Descriptor. // sSetupPacket.bRequest = 0x06; {((usb16_t *)&(sSetupPacket . wValue))->LSB = (uint32_t)2 << 8 & 0xFF; ((usb16_t *)&(sSetupPacket . wValue))->MSB = ((uint32_t)2 << 8 & 0xFF00) >> 8;}; // // Index is always 0 for device configurations requests. // {((usb16_t *)&(sSetupPacket . wIndex))->LSB = 0 & 0xFF; ((usb16_t *)&(sSetupPacket . wIndex))->MSB = (0 & 0xFF00) >> 8;}; // // Only ask for the configuration header first to see how big the // whole thing is. // if(!psDevice->bConfigRead) { // // Only request the space available. // {((usb16_t *)&(sSetupPacket . wLength))->LSB = sizeof(tConfigDescriptor) & 0xFF; ((usb16_t *)&(sSetupPacket . wLength))->MSB = (sizeof(tConfigDescriptor) & 0xFF00) >> 8;}; // // Put the setup packet in the buffer. // ui32Bytes = USBHCDControlTransfer(0, &sSetupPacket, psDevice, (uint8_t *)&sConfigDescriptor, sizeof(tConfigDescriptor), psDevice->sDeviceDescriptor.bMaxPacketSize0); } // // If the Configuration header was successfully returned then get the // full configuration descriptor. // if(ui32Bytes == sizeof(tConfigDescriptor)) { // // Save the total size and request the full configuration descriptor. // sSetupPacket.wLength = sConfigDescriptor.wTotalLength; // // Not enough space to hold this configuration descriptor. // if(ConfigDescAlloc(psDevice, ((unsigned short)(((usb16_t *)&(sConfigDescriptor . wTotalLength))->LSB | ((usb16_t *)&(sConfigDescriptor . wTotalLength))->MSB << 8))) == 0) { return(0); } // // Don't allow the buffer to be larger than was allocated. // if(((unsigned short)(((usb16_t *)&(sSetupPacket . wLength))->LSB | ((usb16_t *)&(sSetupPacket . wLength))->MSB << 8)) > psDevice->ui32ConfigDescriptorSize) { return(0); } // // Put the setup packet in the buffer. // ui32Bytes = USBHCDControlTransfer(0, &sSetupPacket, psDevice, (uint8_t *)psDevice->psConfigDescriptor, ((unsigned short)(((usb16_t *)&(sSetupPacket . wLength))->LSB | ((usb16_t *)&(sSetupPacket . wLength))->MSB << 8)), psDevice->sDeviceDescriptor.bMaxPacketSize0); // // If we read the descriptor, remember the fact. // if(ui32Bytes) { psDevice->bConfigRead = 1; } } return(ui32Bytes); } //***************************************************************************** // //! This function issues a request for a device descriptor from a device. //! //! \param ui32Index specifies which USB controller to use. //! \param psDevice is a pointer to the device structure that holds the buffer //! to store the device descriptor into. //! //! This function will request the device descriptor from the device. The //! \e psDevice->sDeviceDescriptor descriptor is used to hold the data for this //! request. \e psDevice->sDeviceDescriptor.bMaxPacketSize0 should be //! initialized to zero or to the valid maximum packet size if it is known. If //! this variable is not set to zero, then this call will determine the maximum //! packet size for endpoint 0 and save it in the structure member //! bMaxPacketSize0. //! //! \return The number of bytes returned due to the request. This value can be //! zero if the device did not respond. // //***************************************************************************** static uint32_t USBHCDGetDeviceDescriptor(uint32_t ui32Index, tUSBHostDevice *psDevice) { tUSBRequest sSetupPacket; uint32_t ui32Bytes; { if(!(ui32Index == 0)) { __error__("../USB/host/usbhostenum.c", 3201); } }; // // This is a Standard Device IN request. // sSetupPacket.bmRequestType = 0x80 | 0x00 | 0x00; // // Request a Device Descriptor. // sSetupPacket.bRequest = 0x06; {((usb16_t *)&(sSetupPacket . wValue))->LSB = (uint32_t)1 << 8 & 0xFF; ((usb16_t *)&(sSetupPacket . wValue))->MSB = ((uint32_t)1 << 8 & 0xFF00) >> 8;}; // // Index is always 0 for device requests. // {((usb16_t *)&(sSetupPacket . wIndex))->LSB = 0 & 0xFF; ((usb16_t *)&(sSetupPacket . wIndex))->MSB = (0 & 0xFF00) >> 8;}; // // All devices must have at least an 8 byte max packet size so just ask // for 8 bytes to start with. // {((usb16_t *)&(sSetupPacket . wLength))->LSB = sizeof(tDeviceDescriptor) & 0xFF; ((usb16_t *)&(sSetupPacket . wLength))->MSB = (sizeof(tDeviceDescriptor) & 0xFF00) >> 8;}; ui32Bytes = 0; // // Discover the max packet size for endpoint 0. // if(psDevice->sDeviceDescriptor.bMaxPacketSize0 == 0) { // // Put the setup packet in the buffer. // ui32Bytes = USBHCDControlTransfer(ui32Index, &sSetupPacket, psDevice, (uint8_t *)&(psDevice->sDeviceDescriptor), sizeof(tDeviceDescriptor), 8); } // // Now get the full descriptor now that the actual maximum packet size // is known. // if(ui32Bytes < sizeof(tDeviceDescriptor)) { {((usb16_t *)&(sSetupPacket . wLength))->LSB = (uint16_t)sizeof(tDeviceDescriptor) & 0xFF; ((usb16_t *)&(sSetupPacket . wLength))->MSB = ((uint16_t)sizeof(tDeviceDescriptor) & 0xFF00) >> 8;}; ui32Bytes = USBHCDControlTransfer(ui32Index, &sSetupPacket, psDevice, (uint8_t *)&(psDevice->sDeviceDescriptor), sizeof(tDeviceDescriptor), psDevice->sDeviceDescriptor.bMaxPacketSize0); } return(ui32Bytes); } //***************************************************************************** // //! This function is used to send the set address command to a device. //! //! \param ui32DevIndex is the index of the device whose address is to be //! set. This value must be 0 to indicate that the device is connected //! directly to the host controller. Higher values indicate devices connected //! via a hub. //! \param ui32DevAddress is the new device address to use for a device. //! //! The USBHCDSetAddress() function is used to set the USB device address, once //! a device has been discovered on the bus. This call is typically issued //! following a USB reset triggered by a call the USBHCDReset(). The //! address passed into this function via the \e ui32DevAddress parameter is //! used for all further communications with the device after this function //! returns. //! //! \return None. // //***************************************************************************** void USBHCDSetAddress(uint32_t ui32DevIndex, uint32_t ui32DevAddress) { tUSBRequest sSetupPacket; // // This is a Standard Device OUT request. // sSetupPacket.bmRequestType = 0x00 | 0x00 | 0x00; // // Request a Device Descriptor. // sSetupPacket.bRequest = 0x05; {((usb16_t *)&(sSetupPacket . wValue))->LSB = ui32DevAddress & 0xFF; ((usb16_t *)&(sSetupPacket . wValue))->MSB = (ui32DevAddress & 0xFF00) >> 8;}; // // Index is always 0 for device requests. // {((usb16_t *)&(sSetupPacket . wIndex))->LSB = 0 & 0xFF; ((usb16_t *)&(sSetupPacket . wIndex))->MSB = (0 & 0xFF00) >> 8;}; // // Only request the space available. // {((usb16_t *)&(sSetupPacket . wLength))->LSB = 0 & 0xFF; ((usb16_t *)&(sSetupPacket . wLength))->MSB = (0 & 0xFF00) >> 8;}; // // Put the setup packet in the buffer. // USBHCDControlTransfer(0, &sSetupPacket, &g_sUSBHCD.psUSBDevice[ui32DevIndex], 0, 0, 64); // // Must delay 2ms after setting the address. // SysCtlDelay(g_ui32Tickms * 2); } //***************************************************************************** // //! This function is used to send a Clear Feature request to a device. //! //! \param ui32DevAddress is the USB bus address of the device that will //! receive this request. //! \param ui32Pipe is the pipe that will be used to send the request. //! \param ui32Feature is one of the USB_FEATURE_* definitions. //! //! This function will issue a Clear Feature request to the device indicated //! by the \e ui32DevAddress parameter. The \e ui32Pipe parameter is the USB //! pipe that should be used to send this request. The \e ui32Feature //! parameter should be one of the following values: //! //! * \b USB_FEATURE_EP_HALT is used to end a HALT condition on a devices //! endpoint. //! * \b USB_FEATURE_REMOTE_WAKE is used to disable a device's remote wake //! feature. //! * \b USB_FEATURE_TEST_MODE is used take the USB device out of test mode. //! //! \return None. // //***************************************************************************** void USBHCDClearFeature(uint32_t ui32DevAddress, uint32_t ui32Pipe, uint32_t ui32Feature) { tUSBRequest sSetupPacket; uint32_t ui32Index; // // Get the index number from the allocated pipe. // ui32Index = (ui32Pipe & 0x0000ffff); // // This is a Standard Device OUT request. // sSetupPacket.bmRequestType = 0x00 | 0x00 | 0x02; // // Request a Device Descriptor. // sSetupPacket.bRequest = 0x01; {((usb16_t *)&(sSetupPacket . wValue))->LSB = ui32Feature & 0xFF; ((usb16_t *)&(sSetupPacket . wValue))->MSB = (ui32Feature & 0xFF00) >> 8;}; // // Set the endpoint to access. // if(ui32Pipe & 0x00020000) { {((usb16_t *)&(sSetupPacket . wIndex))->LSB = g_sUSBHCD . psUSBINPipes[ui32Index]. ui8EPNumber | 0x80 & 0xFF; ((usb16_t *)&(sSetupPacket . wIndex))->MSB = (g_sUSBHCD . psUSBINPipes[ui32Index]. ui8EPNumber | 0x80 & 0xFF00) >> 8;}; } else { {((usb16_t *)&(sSetupPacket . wIndex))->LSB = g_sUSBHCD . psUSBOUTPipes[ui32Index]. ui8EPNumber & 0xFF; ((usb16_t *)&(sSetupPacket . wIndex))->MSB = (g_sUSBHCD . psUSBOUTPipes[ui32Index]. ui8EPNumber & 0xFF00) >> 8;}; } // // This is always 0. // {((usb16_t *)&(sSetupPacket . wLength))->LSB = 0 & 0xFF; ((usb16_t *)&(sSetupPacket . wLength))->MSB = (0 & 0xFF00) >> 8;}; // // Put the setup packet in the buffer. // USBHCDControlTransfer(0, &sSetupPacket, &g_sUSBHCD.psUSBDevice[ui32DevAddress - 1], 0, 0, 64); // // Set the endpoint to access. // if(ui32Pipe & 0x00020000) { USBEndpointDataToggleClear(0x00040000, (((uint32_t)(ui32Index + 1) << 4) & 0xFF), 0x00000000); } else { USBEndpointDataToggleClear(0x00040000, (((uint32_t)(ui32Index + 1) << 4) & 0xFF), 0x00002000); } // // Must delay 2ms after clearing the feature. // SysCtlDelay(g_ui32Tickms * 2); } //***************************************************************************** // //! This function is used to set the current configuration for a device. //! //! \param ui32Index specifies which USB controller to use. //! \param ui32Device is the USB device for this function. //! \param ui32Configuration is one of the devices valid configurations. //! //! This function is used to set the current device configuration for a USB //! device. The \e ui32Configuration value must be one of the configuration //! indexes that was returned in the configuration descriptor from the device, //! or a value of 0. If 0 is passed in, the device will return to it's //! addressed state and no longer be in a configured state. If the value is //! non-zero then the device will change to the requested configuration. //! //! \return None. // //***************************************************************************** void USBHCDSetConfig(uint32_t ui32Index, uint32_t ui32Device, uint32_t ui32Configuration) { tUSBRequest sSetupPacket; tUSBHostDevice *psDevice; { if(!(ui32Index == 0)) { __error__("../USB/host/usbhostenum.c", 3439); } }; psDevice = (tUSBHostDevice *)ui32Device; // // This is a Standard Device OUT request. // sSetupPacket.bmRequestType = 0x00 | 0x00 | 0x00; // // Request a Device Descriptor. // sSetupPacket.bRequest = 0x09; {((usb16_t *)&(sSetupPacket . wValue))->LSB = ui32Configuration & 0xFF; ((usb16_t *)&(sSetupPacket . wValue))->MSB = (ui32Configuration & 0xFF00) >> 8;}; // // Index is always 0 for device requests. // {((usb16_t *)&(sSetupPacket . wIndex))->LSB = 0 & 0xFF; ((usb16_t *)&(sSetupPacket . wIndex))->MSB = (0 & 0xFF00) >> 8;}; // // Only request the space available. // {((usb16_t *)&(sSetupPacket . wLength))->LSB = 0 & 0xFF; ((usb16_t *)&(sSetupPacket . wLength))->MSB = (0 & 0xFF00) >> 8;}; // // Put the setup packet in the buffer. // USBHCDControlTransfer(0, &sSetupPacket, psDevice, 0, 0, 64); } //***************************************************************************** // //! This function is used to set the current interface and alternate setting //! for an interface on a device. //! //! \param ui32Index specifies which USB controller to use. //! \param ui32Device is the USB device for this function. //! \param ui32Interface is one of the valid interface numbers for a device. //! \param ui32AltSetting is one of the valid alternate interfaces for the //! \e ui32Interface number. //! //! This function is used to change the alternate setting for one of the valid //! interfaces on a USB device. The \e ui32Device specifies the device //! instance that was returned when the device was connected. This call will //! set the USB device's interface based on the \e ui32Interface and //! \e ui32AltSetting. //! //! \b Example: Set the USB device interface 2 to alternate setting 1. //! //! \verbatim //! USBHCDSetInterface(0, ui32Device, 2, 1); //! \endverbatim //! //! \return None. // //***************************************************************************** void USBHCDSetInterface(uint32_t ui32Index, uint32_t ui32Device, uint32_t ui32Interface, uint32_t ui32AltSetting) { tUSBRequest sSetupPacket; tUSBHostDevice *psDevice; { if(!(ui32Index == 0)) { __error__("../USB/host/usbhostenum.c", 3505); } }; psDevice = (tUSBHostDevice *)ui32Device; // // This is a Standard Device OUT request. // sSetupPacket.bmRequestType = 0x00 | 0x00 | 0x01; // // Request a Device Descriptor. // sSetupPacket.bRequest = 0x0b; // // Index is the interface to access. // {((usb16_t *)&(sSetupPacket . wIndex))->LSB = ui32Interface & 0xFF; ((usb16_t *)&(sSetupPacket . wIndex))->MSB = (ui32Interface & 0xFF00) >> 8;}; // // wValue is the alternate setting. // {((usb16_t *)&(sSetupPacket . wValue))->LSB = ui32AltSetting & 0xFF; ((usb16_t *)&(sSetupPacket . wValue))->MSB = (ui32AltSetting & 0xFF00) >> 8;}; // // Only request the space available. // {((usb16_t *)&(sSetupPacket . wLength))->LSB = 0 & 0xFF; ((usb16_t *)&(sSetupPacket . wLength))->MSB = (0 & 0xFF00) >> 8;}; // // Put the setup packet in the buffer. // USBHCDControlTransfer(0, &sSetupPacket, psDevice, 0, 0, 64); } //***************************************************************************** // // The internal function to see if a new schedule event should occur. // // This function is called by the main interrupt handler due to start of frame // interrupts to determine if a new scheduler event should be sent to the USB // pipe. // // \return None. // //***************************************************************************** void USBHostCheckPipes(void) { int32_t i32Idx; g_ui32CurrentTick++; for(i32Idx = 0; i32Idx < g_sUSBHCD.ui32NumEndpoints; i32Idx++) { // // Skip unused pipes. // if(g_sUSBHCD.psUSBINPipes[i32Idx].ui32Type == 0x00100000) { continue; } // // If the tick has expired and it has an interval then update it. // if((g_sUSBHCD.psUSBINPipes[i32Idx].ui32Interval != 0) && (g_sUSBHCD.psUSBINPipes[i32Idx].ui32NextEventTick == g_ui32CurrentTick)) { // // Schedule the next event. // g_sUSBHCD.psUSBINPipes[i32Idx].ui32NextEventTick += g_sUSBHCD.psUSBINPipes[i32Idx].ui32Interval; // // If the pipe is IDLE and there is a callback, let the higher // level drivers know that a new transfer can be scheduled. // if((g_sUSBHCD.psUSBINPipes[i32Idx].iState == ePipeIdle) && (g_sUSBHCD.psUSBINPipes[i32Idx].pfnCallback)) { g_sUSBHCD.psUSBINPipes[i32Idx].pfnCallback( (g_sUSBHCD . psUSBINPipes[i32Idx]. ui32Type | i32Idx), (0x0000 + 9)); } } } } //***************************************************************************** // // The internal USB host mode interrupt handler. // // \param ui32Index is the USB controller associated with this interrupt. // \param ui32Status is the current interrupt status as read via a call to // USBIntStatus(). This is the value of USBIS. // \param ui32IntStatusEP is the current interrupt status of the endpoint // as read from USBIntStatus(). This is the value of RXIS and TXIS. // // This the main USB interrupt handler called when operating in host mode. // This handler will branch the interrupt off to the appropriate handlers // depending on the current status of the USB controller. // // The two-tiered structure for the interrupt handler ensures that it is // possible to use the same handler code in both host and OTG modes and // means that device code can be excluded from applications that only require // support for USB host mode operation. // // \return None. // //***************************************************************************** void USBHostIntHandlerInternal(uint32_t ui32Index, uint32_t ui32Status, uint32_t ui32IntStatusEP) { uint32_t ui32EPStatus, ui32DMAIntStatus, ui32Idx, ui32DevIndex; static uint32_t ui32SOFDivide = 0; int32_t i32ClassDrvr; // // By default, assume we are dealing with the device directly connected // to the host controller and that we need to notify its class driver of // this interrupt. // g_sUSBHCD.psUSBDevice[0].ui32Flags |= 0x00000001; if(ui32Status & 0x00000008) { // // Indicate that a start of frame has occurred. // g_sUSBHCD.ui32IntEvents |= 0x10; } // // A power fault has occurred so notify the application. // if(ui32Status & 0x00000100) { // // Indicate that a power fault has occurred. // g_sUSBHCD.ui32IntEvents |= 0x08; // // Turn off power to the bus. // USBHostPwrDisable(0x00040000); // // Disable USB interrupts. // IntDisable(g_sUSBHCD . ui32IntNum); return; } // // In the event of a USB VBUS error, end the session and remove power to // the device. // if(ui32Status & 0x00000080) { // // Set the VBUS error event. We deliberately clear all other events // since this one means anything else that is outstanding is // irrelevant. // g_sUSBHCD.ui32IntEvents = 0x01; return; } // // Received a reset from the host. // if(ui32Status & 0x00000004) { } // // Suspend was signaled on the bus. // if(ui32Status & 0x00000001) { } // // Start the session. // if(ui32Status & 0x00000040) { // // Power the USB bus. // USBHostPwrEnable(0x00040000); USBOTGSessionRequest(0x00040000, 1); } // // Resume was signaled on the bus. // if(ui32Status & 0x00000002) { } // // Device connected so tell the main routine to issue a reset. // if(ui32Status & 0x00000010) { // // Set the connect flag and clear disconnect if it happens to be set. // g_sUSBHCD.ui32IntEvents |= 0x02; g_sUSBHCD.ui32IntEvents &= ~0x04; // // Power the USB bus. // USBHostPwrEnable(0x00040000); } // // Handle the ID detection so that the ID pin can be used as a // GPIO in eUSBModeHost. // if(ui32Status & 0x00000200) { // // If in eUSBModeHost mode then switch back to OTG detection // so that VBUS can be monitored but free up the ID pin. // if(g_iUSBMode == eUSBModeHost) { USBOTGMode(0x00040000); } } // // Device was unplugged. // if(ui32Status & 0x00000020) { // // Set the disconnect flag and clear connect if it happens to be set. // g_sUSBHCD.ui32IntEvents |= 0x04; g_sUSBHCD.ui32IntEvents &= ~0x02; } // // Start of Frame was received. // if(ui32Status & 0x00000008) { // // Increment the global Start of Frame counter. // g_ui32USBSOFCount++; // // Increment our SOF divider. // ui32SOFDivide++; // // Have we counted enough SOFs to allow us to call the tick function? // if(ui32SOFDivide == 5) { // // Yes - reset the divider and call the SOF tick handler. // ui32SOFDivide = 0; InternalUSBStartOfFrameTick(5); } } // // Check to see if any DMA transfers are pending // ui32DMAIntStatus = g_sUSBHCD . psDMAInstance ->pfnIntStatus(g_sUSBHCD . psDMAInstance); if(ui32DMAIntStatus) { // // Handle any DMA interrupt processing. // g_sUSBHCD . psDMAInstance ->pfnIntHandler(g_sUSBHCD . psDMAInstance, ui32DMAIntStatus); for(ui32Idx = 0; ui32Idx < 15; ui32Idx++) { if((g_sUSBHCD.psUSBINPipes[ui32Idx].iState == ePipeReadDMAWait) || (g_sUSBHCD.psUSBINPipes[ui32Idx].iState == ePipeReadDMA)) { // // If the DMA channel transfer is complete, send an ack. // if(g_sUSBHCD . psDMAInstance ->pfnChannelStatus(g_sUSBHCD . psDMAInstance, g_sUSBHCD . psUSBINPipes[ui32Idx]. ui8DMAChannel) == 0x00000001) { // // Acknowledge the IN request. // USBHostEndpointDataAck(0x00040000, (((uint32_t)(ui32Idx + 1) << 4) & 0xFF)); // // If using uDMA then the endpoint status interrupt will // not occur. So process the data ready event here. // g_sUSBHCD.psUSBINPipes[ui32Idx].iState = ePipeDataReady; // // Only call a handler if one is present. // if(g_sUSBHCD.psUSBINPipes[ui32Idx].pfnCallback) { g_sUSBHCD.psUSBINPipes[ui32Idx].pfnCallback( (g_sUSBHCD . psUSBINPipes[ui32Idx]. ui32Type | ui32Idx), (0x0000 + 2)); } // // Remember that we need to notify this device's class // driver that an interrupt occurred. // g_sUSBHCD.psUSBINPipes[ui32Idx].psDevice->ui32Flags |= 0x00000001; } } else if(g_sUSBHCD.psUSBOUTPipes[ui32Idx].iState == ePipeWriteDMASend) { // // If the uDMA channel transfer is complete, then tell // the USB controller to go ahead and send the data // if(g_sUSBHCD . psDMAInstance ->pfnChannelStatus(g_sUSBHCD . psDMAInstance, g_sUSBHCD . psUSBOUTPipes[ui32Idx]. ui8DMAChannel) & 0x00000001) { USBEndpointDataSend(0x00040000, (((uint32_t)(ui32Idx + 1) << 4) & 0xFF), 0x00000102); // // Now waiting on the final endpoint interrupt. // g_sUSBHCD.psUSBOUTPipes[ui32Idx].iState = ePipeWriteDMAWait; } } else if(g_sUSBHCD.psUSBOUTPipes[ui32Idx].iState == ePipeWriteDMA) { // // Data was transmitted successfully. // g_sUSBHCD.psUSBOUTPipes[ui32Idx].iState = ePipeDataSent; // // Only call a handler if one is present. // if(g_sUSBHCD.psUSBOUTPipes[ui32Idx].pfnCallback) { // // Notify the pipe that its last transaction was completed. // g_sUSBHCD.psUSBOUTPipes[ui32Idx].pfnCallback( (g_sUSBHCD . psUSBOUTPipes[ui32Idx]. ui32Type | ui32Idx), (0x0000 + 5)); } } } } // // Use the controller interrupt status from ui32IntStatusEP. // This is made up of the values of RXIS and TXIS. // ui32Status = ui32IntStatusEP; // // Handle end point 0 interrupts. // if(ui32Status & 0x00000001) { // // Indicate that a start of frame has occurred. // g_sUSBHCD.ui32IntEvents |= 0x20; } for(ui32Idx = 0; ui32Idx < 15; ui32Idx++) { // // Check the next pipe, the first time through this will clear out // any interrupts dealing with endpoint zero since it was handled // above. // ui32Status >>= 1; // // Break out if there are no more pending interrupts. // if(ui32Status == 0) { break; } // // Check the status of the receive(IN) pipes. // if(ui32Status & 0x10000) { // // Clear the status flag for the IN Pipe. // ui32Status &= ~0x10000; // // Read the status of the endpoint connected to this pipe. // ui32EPStatus = USBEndpointStatus(0x00040000, (((uint32_t)(ui32Idx + 1) << 4) & 0xFF)); // // Check if the device stalled the request. // if(ui32EPStatus & 0x00400000) { // // Clear the stall condition on this endpoint pipe. // USBHostEndpointStatusClear(0x00040000, (((uint32_t)(ui32Idx + 1) << 4) & 0xFF), 0x00400000); // // Save the STALLED state. // g_sUSBHCD.psUSBINPipes[ui32Idx].iState = ePipeStalled; // // Notify the pipe that it was stalled. // if(g_sUSBHCD.psUSBINPipes[ui32Idx].pfnCallback) { g_sUSBHCD.psUSBINPipes[ui32Idx].pfnCallback( (g_sUSBHCD . psUSBINPipes[ui32Idx]. ui32Type | ui32Idx), (0x0000 + 10)); } } else if(ui32EPStatus & 0x00040000) { // // We can no longer communicate with this device for some // reason. It may have been disconnected from a hub, for // example. Merely clear the status and continue. // USBHostEndpointStatusClear(0x00040000, (((uint32_t)(ui32Idx + 1) << 4) & 0xFF), 0x00040000); // // Save the STALLED state. // g_sUSBHCD.psUSBINPipes[ui32Idx].iState = ePipeError; // // Notify the pipe that it was stalled. // if(g_sUSBHCD.psUSBINPipes[ui32Idx].pfnCallback) { g_sUSBHCD.psUSBINPipes[ui32Idx].pfnCallback( (g_sUSBHCD . psUSBINPipes[ui32Idx]. ui32Type | ui32Idx), (0x0000 + 6)); } } // // Handle the case where the pipe is reading a single packet. // else if(g_sUSBHCD.psUSBINPipes[ui32Idx].iState == ePipeReadDMA) { // // Enable the DMA channel and wait for it to complete. // g_sUSBHCD.psUSBINPipes[ui32Idx].iState = ePipeReadDMAWait; g_sUSBHCD . psDMAInstance ->pfnChannelEnable(g_sUSBHCD . psDMAInstance, g_sUSBHCD . psUSBINPipes[ui32Idx]. ui8DMAChannel); } else if(g_sUSBHCD.psUSBINPipes[ui32Idx].iState == ePipeReading) { // // Data is available. // g_sUSBHCD.psUSBINPipes[ui32Idx].iState = ePipeDataReady; // // Read the data out of the USB endpoint interface into the // buffer provided by the caller to USBHCDPipeRead() or // USBHCDPipeSchedule() if a buffer was provided already. // if(g_sUSBHCD.psUSBINPipes[ui32Idx].pui8ReadPtr) { USBEndpointDataGet(0x00040000, (((uint32_t)(ui32Idx + 1) << 4) & 0xFF), g_sUSBHCD.psUSBINPipes[ui32Idx].pui8ReadPtr, &g_sUSBHCD.psUSBINPipes[ui32Idx].ui32ReadSize); } // // Notify the pipe that its last transaction was completed. // if(g_sUSBHCD.psUSBINPipes[ui32Idx].pfnCallback) { g_sUSBHCD.psUSBINPipes[ui32Idx].pfnCallback( (g_sUSBHCD . psUSBINPipes[ui32Idx]. ui32Type | ui32Idx), (0x0000 + 2)); } } // // Remember that we need to notify this device's class // driver that an interrupt occurred. // g_sUSBHCD.psUSBINPipes[ui32Idx].psDevice->ui32Flags |= 0x00000001; } // // Check the status of the transmit(OUT) pipes. // if(ui32Status & 1) { // // Read the status of the endpoint connected to this pipe. // ui32EPStatus = USBEndpointStatus(0x00040000, (((uint32_t)(ui32Idx + 1) << 4) & 0xFF)); // // Check if the device stalled the request. // if(ui32EPStatus & 0x00000020) { // // Clear the stall condition on this endpoint pipe. // USBHostEndpointStatusClear(0x00040000, (((uint32_t)(ui32Idx + 1) << 4) & 0xFF), 0x00000020); // // Save the STALLED state. // g_sUSBHCD.psUSBOUTPipes[ui32Idx].iState = ePipeStalled; // // Only call a handler if one is present. // if(g_sUSBHCD.psUSBOUTPipes[ui32Idx].pfnCallback) { // // Notify the pipe that it was stalled. // g_sUSBHCD.psUSBOUTPipes[ui32Idx].pfnCallback( (g_sUSBHCD . psUSBOUTPipes[ui32Idx]. ui32Type | ui32Idx), (0x0000 + 10)); } } else if(ui32EPStatus & 0x00000004) { // // Clear the error condition on this endpoint pipe. // USBHostEndpointStatusClear(0x00040000, (((uint32_t)(ui32Idx + 1) << 4) & 0xFF), 0x00000004); // // Save the Pipes error state. // g_sUSBHCD.psUSBOUTPipes[ui32Idx].iState = ePipeError; // // Only call a handler if one is present. // if(g_sUSBHCD.psUSBOUTPipes[ui32Idx].pfnCallback) { // // Notify the pipe that had an error. // g_sUSBHCD.psUSBOUTPipes[ui32Idx].pfnCallback( (g_sUSBHCD . psUSBOUTPipes[ui32Idx]. ui32Type | ui32Idx), (0x0000 + 6)); } } else if((g_sUSBHCD.psUSBOUTPipes[ui32Idx].iState == ePipeWriting) || (g_sUSBHCD.psUSBOUTPipes[ui32Idx].iState == ePipeWriteDMAWait)) { // // Data was transmitted successfully. // g_sUSBHCD.psUSBOUTPipes[ui32Idx].iState = ePipeDataSent; // // Only call a handler if one is present. // if(g_sUSBHCD.psUSBOUTPipes[ui32Idx].pfnCallback) { // // Notify the pipe that its last transaction was completed. // g_sUSBHCD.psUSBOUTPipes[ui32Idx].pfnCallback( (g_sUSBHCD . psUSBOUTPipes[ui32Idx]. ui32Type | ui32Idx), (0x0000 + 5)); } } // // Clear the stall condition on this endpoint pipe. // USBHostEndpointStatusClear(0x00040000, (((uint32_t)(ui32Idx + 1) << 4) & 0xFF), ui32EPStatus); // // Remember that we need to notify this device's class // driver that an interrupt occurred. // if(g_sUSBHCD.psUSBOUTPipes[ui32Idx].psDevice) { g_sUSBHCD.psUSBINPipes[ui32Idx].psDevice->ui32Flags |= 0x00000001; } } } // // Send back notifications to any class driver whose endpoint required // service during the handler. // for(ui32DevIndex = 0; ui32DevIndex <= 5; ui32DevIndex++) { // // Which class driver does this device use? // i32ClassDrvr = g_pi32USBHActiveDriver[ui32DevIndex]; // // If a class driver is in use, and one of its endpoints was serviced // and the class driver has an interrupt callback... // if((i32ClassDrvr >= 0) && (g_sUSBHCD.psUSBDevice[ui32DevIndex].ui32Flags & 0x00000001) && (g_sUSBHCD.ppsClassDrivers[i32ClassDrvr]->pfnIntHandler)) { // // ...call the class driver's interrupt notification callback. // g_sUSBHCD.ppsClassDrivers[i32ClassDrvr]->pfnIntHandler( g_ppvDriverInstance[ui32DevIndex]); } } } //***************************************************************************** // //! The USB host mode interrupt handler for controller index 0. //! //! This the main USB interrupt handler entry point. This handler will branch //! the interrupt off to the appropriate handlers depending on the current //! status of the USB controller. This function must be placed in the //! interrupt table in order for the USB Library host stack to function. //! //! \return None. // //***************************************************************************** void USB0HostIntHandler(void) { uint32_t ui32Status; uint32_t ui32IntStatusEP; // // Get the control interrupt status. // ui32Status = USBIntStatus(0x00040000, &ui32IntStatusEP); // // Call the internal handler to process the interrupts. // USBHostIntHandlerInternal(0, ui32Status, ui32IntStatusEP); } //***************************************************************************** // //! This function opens the class driver. //! //! \param ui32Index specifies which USB controller to use. //! \param ui32DeviceNum is the device number for the driver to load. //! //! This function opens the driver needed based on the class value found in //! the device's interface descriptor. //! //! \return This function returns -1 if no driver is found, or it returns the //! index of the driver found in the list of host class drivers. // //***************************************************************************** static int32_t USBHCDOpenDriver(uint32_t ui32Index, uint32_t ui32DeviceNum) { int32_t i32Driver; uint32_t ui32Class; tInterfaceDescriptor *psInterface; tEventInfo sEvent; { if(!(ui32Index == 0)) { __error__("../USB/host/usbhostenum.c", 4233); } }; // // Get the interface descriptor. // psInterface = USBDescGetInterface( g_sUSBHCD.psUSBDevice[ui32DeviceNum].psConfigDescriptor, g_sUSBHCD.psUSBDevice[ui32DeviceNum].ui32Interface, 0xFFFFFFFF); // // Read the interface class. // ui32Class = psInterface->bInterfaceClass; // // Search through the Host Class driver list for the devices class. // for(i32Driver = 0; i32Driver < g_sUSBHCD.ui32NumClassDrivers; i32Driver++) { // // If a driver was found call the open for this driver and save which // driver is in use. // if(g_sUSBHCD.ppsClassDrivers[i32Driver]->ui32InterfaceClass == ui32Class) { // // Call the open function for the class driver. // g_ppvDriverInstance[ui32DeviceNum] = g_sUSBHCD.ppsClassDrivers[i32Driver]->pfnOpen( &g_sUSBHCD.psUSBDevice[ui32DeviceNum]); // // If the driver was successfully loaded then break out of the // loop. // if(g_ppvDriverInstance[ui32DeviceNum] != 0) { break; } } } // // If no drivers were found then return -1 to indicate an invalid // driver instance. // if(i32Driver == g_sUSBHCD.ui32NumClassDrivers) { // // Send an unknown connection event. // SendUnknownConnect(ui32Index, ui32Class); // // Indicate that no driver was found. // i32Driver = -1; } else { // // If the connect event is enabled then send the event. // sEvent.ui32Event = (0x0000 + 0); sEvent.ui32Instance = (ui32Index << 16) | ui32DeviceNum; InternalUSBHCDSendEvent(0, &sEvent, 0x00000002); } return(i32Driver); } //***************************************************************************** // // This function will send an event to a registered event driver. // // \param ui32Index specifies which USB controller to use. // \param psEvent is a pointer to the event structure to send. // // This function is only used internally to the USB library and will check // if an event driver is registered and send on the event. // // Note: This function should not be called outside of the USB library. // // \return None. // //***************************************************************************** void InternalUSBHCDSendEvent(uint32_t ui32Index, tEventInfo *psEvent, uint32_t ui32EvFlag) { // // Make sure that an event driver has been registered. // if((g_sUSBHCD.i32EventDriver != -1) && (g_sUSBHCD.ppsClassDrivers[g_sUSBHCD.i32EventDriver]->pfnIntHandler) && (g_sUSBHCD.ui32EventEnables & ui32EvFlag)) { g_sUSBHCD.ppsClassDrivers[g_sUSBHCD.i32EventDriver]->pfnIntHandler( psEvent); } } //***************************************************************************** // // This function handles the necessary clean up for device disconnect. // // \param ui32Index is the device number for the device that was disconnected. // // This function handles all of the necessary clean up after a device // disconnect has been detected by the stack. This includes calling back the // appropriate driver if necessary. // // \return None. // //***************************************************************************** static void USBHCDDeviceDisconnected(uint32_t ui32Index, uint32_t ui32DevIndex) { tEventInfo sEvent; { if(!(ui32Index == 0)) { __error__("../USB/host/usbhostenum.c", 4356); } }; { if(!(ui32DevIndex <= 5)) { __error__("../USB/host/usbhostenum.c", 4357); } }; // // If there is an event driver with a valid event handler and the // USBHCD_EVFLAG_DISCNCT is enabled, then call the registered event // handler. // sEvent.ui32Event = (0x0000 + 1); sEvent.ui32Instance = (ui32Index << 16) | ui32DevIndex; InternalUSBHCDSendEvent(0, &sEvent, 0x00000008); // // Reset the class. // g_sUSBHCD.ui32Class = 0xffffffff; // // Free configuration descriptor memory if any has been allocated. // if(g_sUSBHCD.psUSBDevice[ui32DevIndex].ui32Flags & 0x80000000) { // // Free the memory used by the configuration descriptor. // ConfigDescFree(&g_sUSBHCD.psUSBDevice[ui32DevIndex]); g_sUSBHCD.psUSBDevice[ui32DevIndex].ui32Flags = 0; g_sUSBHCD.psUSBDevice[ui32DevIndex].bConfigRead = 0; } // // Reset the max packet size so that this will be re-read from new devices. // g_sUSBHCD.psUSBDevice[ui32DevIndex].sDeviceDescriptor.bMaxPacketSize0 = 0; // // No longer have a device descriptor. // g_sUSBHCD.psUSBDevice[ui32DevIndex].sDeviceDescriptor.bLength = 0; // // No longer addressed. // g_sUSBHCD.psUSBDevice[ui32DevIndex].ui32Address = 0; // // If this was an active driver then close it out. // if(g_pi32USBHActiveDriver[ui32DevIndex] >= 0) { // // Call the driver Close entry point. // g_sUSBHCD.ppsClassDrivers[g_pi32USBHActiveDriver[ui32DevIndex]]-> pfnClose(g_ppvDriverInstance[ui32DevIndex]); // // No active driver now present. // g_pi32USBHActiveDriver[ui32DevIndex] = -1; g_ppvDriverInstance[ui32DevIndex] = 0; } // // This call is necessary for OTG controllers to know that the host // stack has completed handling the disconnect of the device before // removing power and returning to a state that can allow OTG // negotiations once again. // We only do this if the disconnected device // was attached directly to us (device index 0). // if((ui32DevIndex == 0) && (g_iUSBMode == eUSBModeOTG)) { OTGDeviceDisconnect(0); } } //***************************************************************************** // //! This function is the main routine for the Host Controller Driver. //! //! This function is the main routine for the host controller driver, and must //! be called periodically by the main application outside of a callback //! context. This allows for a simple cooperative system to access the the //! host controller driver interface without the need for an RTOS. All time //! critical operations are handled in interrupt context but all blocking //! operations are run from the this function to allow them to block and wait //! for completion without holding off other interrupts. //! //! \return None. // //***************************************************************************** void USBHCDMain(void) { tUSBHDeviceState iOldState; int32_t i32Dev; tEventInfo sEvent; // // Save the old state to detect changes properly. // iOldState = g_sUSBHCD.piDeviceState[0]; // // Fix up the state if any important interrupt events occurred. // if(g_sUSBHCD.ui32IntEvents) { // // Disable the USB interrupt. // IntDisable(g_sUSBHCD . ui32IntNum); if(g_sUSBHCD.ui32IntEvents & 0x08) { // // A power fault has occurred so notify the application if there // is an event handler and the event has been enabled. // sEvent.ui32Event = (0x0000 + 11); sEvent.ui32Instance = 0; InternalUSBHCDSendEvent(0, &sEvent, 0x00000010); g_sUSBHCD.piDeviceState[0] = eHCDPowerFault; } else if(g_sUSBHCD.ui32IntEvents & 0x01) { // // A VBUS error has occurred. This event trumps connect and // disconnect since it will cause a controller reset. // g_sUSBHCD.piDeviceState[0] = eHCDVBUSError; } else { // // Has a device connected? // if(g_sUSBHCD.ui32IntEvents & 0x02) { g_sUSBHCD.piDeviceState[0] = eHCDDevReset; g_sUSBHCD.psUSBDevice[0].ui8Hub = 0; g_sUSBHCD.psUSBDevice[0].ui8HubPort = 0; } else { // // Has a device disconnected? // if(g_sUSBHCD.ui32IntEvents & 0x04) { g_sUSBHCD.piDeviceState[0] = eHCDDevDisconnected; } } // // Handle the start of frame event // if(g_sUSBHCD.ui32IntEvents & 0x10) { // // If the connect event is enabled then send the event. // sEvent.ui32Event = (0x0000 + 19); sEvent.ui32Instance = 0; InternalUSBHCDSendEvent(0, &sEvent, 0x00000001); USBHostCheckPipes(); // // Call the hub driver to have it perform any necessary // processing to handle downstream devices. // USBHHubMain(); } } // // Clear the flags. // g_sUSBHCD.ui32IntEvents = 0; // // Enable the USB interrupt. // IntEnable(g_sUSBHCD . ui32IntNum); } // // Process the state machine for each connected device. Yes, the exit // condition for this loop is correct since we support (MAX_USB_DEVICES+1) // devices (the hub counts as one). // for(i32Dev = 0; i32Dev <= 5; i32Dev++) { // // If this is not the first device (i.e. the one directly connected to // the host controller) then set the old state to the current state // since we won't have mucked with it in any of the previous code. // if(i32Dev != 0) { iOldState = g_sUSBHCD.piDeviceState[i32Dev]; } // // Process the state machine for this device. // ProcessUSBDeviceStateMachine(iOldState, i32Dev); } } static void ProcessUSBDeviceStateMachine(tUSBHDeviceState iOldState, uint32_t ui32DevIndex) { switch(g_sUSBHCD.piDeviceState[ui32DevIndex]) { // // There was a power fault condition so shut down and wait for the // application to re-initialized the system. // case eHCDPowerFault: { break; } // // There was a VBUS error so handle it. // case eHCDVBUSError: { // // Disable USB interrupts. // IntDisable(g_sUSBHCD . ui32IntNum); // // If there was a device in any state of connection then indicate // that it has been disconnected. // if((iOldState != eHCDIdle) && (iOldState != eHCDPowerFault)) { // // Handle device disconnect. // USBHCDDeviceDisconnected(0, ui32DevIndex); } // // Reset the controller. // SysCtlPeripheralReset(0x0010000B); // // Wait for 100ms before trying to re-power the device. // SysCtlDelay(g_ui32Tickms * 100); // // Re-initialize the HCD. // USBHCDInitInternal(0, g_sUSBHCD.pvPool, g_sUSBHCD.ui32PoolSize); break; } // // Trigger a reset to the connected device. // case eHCDDevReset: { if(!ui32DevIndex) { // // Trigger a Reset. This is only ever done for devices // attached directly to the controller. // while(0)((int32_t (*)(char *, ...))0)("USB reset.\n"); USBHCDReset(0); } // // The state moves to connected but not configured. // g_sUSBHCD.piDeviceState[0] = eHCDDevConnected; // // Remember that we don't have a valid configuration descriptor // yet. // g_sUSBHCD.psUSBDevice[0].bConfigRead = 0; break; } // // Device connection has been established now start enumerating // the device. // case eHCDDevConnected: case eHCDDevConnectedHub: { // // First check if we have read the device descriptor at all // before proceeding. // if(g_sUSBHCD.psUSBDevice[ui32DevIndex].sDeviceDescriptor.bLength == 0) { // // Initialize a request for the device descriptor. // while(0)((int32_t (*)(char *, ...))0)("Connection %d - getting device descriptor\n", ui32DevIndex); if(USBHCDGetDeviceDescriptor(0, &g_sUSBHCD.psUSBDevice[ui32DevIndex]) == 0) { // // If the device descriptor cannot be read then the device // will be treated as unknown. // g_sUSBHCD.piDeviceState[ui32DevIndex] = eHCDDevError; while(0)((int32_t (*)(char *, ...))0)("Connection %d - failed to get descriptor\n", ui32DevIndex); // // Send an unknown connection event. // SendUnknownConnect(0, 1); // // If the device is connected via a hub, tell the hub // driver that we experienced an error enumerating the // device. // if(g_sUSBHCD.psUSBDevice[ui32DevIndex].ui8Hub) { USBHHubEnumerationError( g_sUSBHCD.psUSBDevice[ui32DevIndex].ui8Hub, g_sUSBHCD.psUSBDevice[ui32DevIndex].ui8HubPort); } } } // // If we have the device descriptor then move on to setting // the address of the device. // else if(g_sUSBHCD.psUSBDevice[ui32DevIndex].ui32Address == 0) { while(0)((int32_t (*)(char *, ...))0)("Connection %d - setting address %d\n", ui32DevIndex, ui32DevIndex + 1); // // Send the set address command. // USBHCDSetAddress(ui32DevIndex, (ui32DevIndex + 1)); // // Save the address. // g_sUSBHCD.psUSBDevice[ui32DevIndex].ui32Address = (ui32DevIndex + 1); // // Move on to the addressed state. // g_sUSBHCD.piDeviceState[ui32DevIndex] = eHCDDevAddressed; } break; } case eHCDDevAddressed: { // // First check if we have read the configuration descriptor. // if(!g_sUSBHCD.psUSBDevice[ui32DevIndex].bConfigRead) { while(0)((int32_t (*)(char *, ...))0)("Connection %d - getting config descriptor\n", ui32DevIndex); // // Initialize a request for the configuration descriptor. // if(USBHCDGetConfigDescriptor(0, &g_sUSBHCD.psUSBDevice[ui32DevIndex]) == 0) { // // If the device descriptor cannot be read then the device // will be treated as unknown. // g_sUSBHCD.piDeviceState[ui32DevIndex] = eHCDDevError; while(0)((int32_t (*)(char *, ...))0)("Connection %d - failed to get descriptor\n", ui32DevIndex); // // Send an unknown connection event. // SendUnknownConnect(0, 0); // // If the device is connected via a hub, tell the hub // driver that we experienced an error enumerating the // device. // if(g_sUSBHCD.psUSBDevice[ui32DevIndex].ui8Hub) { USBHHubEnumerationError( g_sUSBHCD.psUSBDevice[ui32DevIndex].ui8Hub, g_sUSBHCD.psUSBDevice[ui32DevIndex].ui8HubPort); } } } // // Now have addressed and received the device configuration, // so get ready to set the device configuration. // else { while(0)((int32_t (*)(char *, ...))0)("Connection %d - setting configuration.\n", ui32DevIndex); // // Use the first configuration to set the device // configuration. // USBHCDSetConfig(0, (uint32_t)&g_sUSBHCD.psUSBDevice[ui32DevIndex], 1); // // Move on to the configured state. // g_sUSBHCD.piDeviceState[ui32DevIndex] = eHCDDevConfigured; // // Open the driver for the device. // g_pi32USBHActiveDriver[ui32DevIndex] = USBHCDOpenDriver(0, ui32DevIndex); // // If the device is connected via a hub, tell the hub // driver that enumeration is complete. // if(g_sUSBHCD.psUSBDevice[ui32DevIndex].ui8Hub) { USBHHubEnumerationComplete( g_sUSBHCD.psUSBDevice[ui32DevIndex].ui8Hub, g_sUSBHCD.psUSBDevice[ui32DevIndex].ui8HubPort); } } break; } // // The device was making a request and is now complete. // case eHCDDevRequest: { g_sUSBHCD.piDeviceState[ui32DevIndex] = eHCDDevConnected; break; } // // The strings are currently not accessed. // case eHCDDevGetStrings: { break; } // // Basically Idle at this point. // case eHCDDevDisconnected: { while(0)((int32_t (*)(char *, ...))0)("Connection %d - disconnected.\n", ui32DevIndex); // // Handle device disconnect. // USBHCDDeviceDisconnected(0, ui32DevIndex); // // Return to the Idle state. // g_sUSBHCD.piDeviceState[ui32DevIndex] = eHCDIdle; break; } // // Connection and enumeration is complete so allow this function // to exit. // case eHCDDevConfigured: { break; } // // Poorly behaving device are in limbo in this state until removed. // case eHCDDevError: { while(0)((int32_t (*)(char *, ...))0)("Connection %d - Error!\n", ui32DevIndex); // // If this device is connected directly to us, tidy up and ignore // it until it is removed. If the device is connected to a hub, // we just leave it in the error state until it is removed. // if(ui32DevIndex == 0) { g_sUSBHCD.ui32IntEvents |= 0x04; g_sUSBHCD.piDeviceState[ui32DevIndex] = eHCDIdle; } break; } default: { break; } } } //***************************************************************************** // //! This function completes a control transaction to a device. //! //! \param ui32Index is the controller index to use for this transfer. //! \param psSetupPacket is the setup request to be sent. //! \param psDevice is the device instance pointer for this request. //! \param pui8Data is the data to send for OUT requests or the receive buffer //! for IN requests. //! \param ui32Size is the size of the buffer in pui8Data. //! \param ui32MaxPacketSize is the maximum packet size for the device for this //! request. //! //! This function handles the state changes necessary to send a control //! transaction to a device. This function should not be called from within //! an interrupt callback as it is a blocking function. //! //! \return The number of bytes of data that were sent or received as a result //! of this request. // //***************************************************************************** uint32_t USBHCDControlTransfer(uint32_t ui32Index, tUSBRequest *psSetupPacket, tUSBHostDevice *psDevice, uint8_t *pui8Data, uint32_t ui32Size, uint32_t ui32MaxPacketSize) { uint32_t ui32Remaining; uint32_t ui32DataSize; // // Debug sanity check. // { if(!(g_sUSBHEP0State . iState == eEP0StateIdle)) { __error__("../USB/host/usbhostenum.c", 4914); } }; { if(!(ui32Index == 0)) { __error__("../USB/host/usbhostenum.c", 4915); } }; // // Initialize the state of the data for this request. // g_sUSBHEP0State.pui8Data = pui8Data; g_sUSBHEP0State.ui32BytesRemaining = ui32Size; g_sUSBHEP0State.ui32DataSize = ui32Size; // // Set the maximum packet size. // g_sUSBHEP0State.ui32MaxPacketSize = ui32MaxPacketSize; // // Save the current address. // g_sUSBHEP0State.ui32DevAddress = psDevice->ui32Address; // // Set the address the host will used to communicate with the device. // USBHostAddrSet(0x00040000, 0x00000000, g_sUSBHEP0State.ui32DevAddress, 0x00002000); // // Put the data in the correct FIFO. // USBEndpointDataPut(0x00040000, 0x00000000, (uint8_t *)psSetupPacket, sizeof(tUSBRequest)); // // If this is an IN request, change to that state. // if(psSetupPacket->bmRequestType & 0x80) { g_sUSBHEP0State.iState = eEP0StateSetupIN; } else { // // If there is no data then this is not an OUT request. // if(ui32Size != 0) { // // Since there is data, this is an OUT request. // g_sUSBHEP0State.iState = eEP0StateSetupOUT; } else { // // Otherwise this request has no data and just a status phase. // g_sUSBHEP0State.iState = eEP0StateStatusIN; } } // // Make sure we are talking to the correct device. // USBHostHubAddrSet(0x00040000, 0x00000000, (psDevice->ui8Hub | ((uint32_t)psDevice->ui8HubPort << 8)), 0x00002000 | (psDevice->bLowSpeed ? 0x00000000 : 0x00001000)); // // Send the Setup packet. // USBEndpointDataSend(0x00040000, 0x00000000, 0x0000110a); // // Block until endpoint 0 returns to the IDLE state. // while(g_sUSBHEP0State.iState != eEP0StateIdle) { IntDisable(g_sUSBHCD . ui32IntNum); if((g_sUSBHCD.ui32IntEvents & (0x20 | 0x10)) == (0x20 | 0x10)) { g_sUSBHCD.ui32IntEvents &= ~(0x20 | 0x10); USBHCDEnumHandler(); } IntEnable(g_sUSBHCD . ui32IntNum); if(g_sUSBHEP0State.iState == eEP0StateError) { return(0xffffffff); } // // If we aborted the transfer due to an error, tell the caller // that no bytes were transferred. // if(g_sUSBHCD.ui32IntEvents & (0x01 | 0x04)) { return(0xffffffff); } } // // Calculate and return the number of bytes that were sent or received. // The extra copy into local variables is required to prevent some // compilers from warning about undefined order of volatile access. // ui32DataSize = g_sUSBHEP0State.ui32DataSize; ui32Remaining = g_sUSBHEP0State.ui32BytesRemaining; return(ui32DataSize - ui32Remaining); } //***************************************************************************** // // Starts enumerating a new device connected via the hub. // // \param ui32Index is the index of the USB controller to use. // \param ui32Hub is the hub address from which the connection is being made. // \param ui32Port is the hub port number that the new device is connected to. // \param pui8ConfigPool is memory to be used to store the device's // configuration descriptor. // \param ui32ConfigSize is the number of bytes available in the buffer pointed // to by pui8ConfigPool. // // This function is called by the hub class driver after it has detected a new // device connection and reset the device. // // \return Returns the index of the device allocated or 0 if no resources are // available. Device index 0 is the hub itself. // //***************************************************************************** uint32_t USBHCDHubDeviceConnected(uint32_t ui32Index, uint8_t ui8Hub, uint8_t ui8Port, _Bool bLowSpeed) { uint32_t ui32DevIndex; // // Debug sanity checks. // { if(!(ui32Index == 0)) { __error__("../USB/host/usbhostenum.c", 5059); } }; { if(!(ui8Port)) { __error__("../USB/host/usbhostenum.c", 5060); } }; while(0)((int32_t (*)(char *, ...))0)("Connection from hub %d, port %d.\n", ui8Hub, ui8Port); // // Look for a free slot in the device table. // for(ui32DevIndex = 1; ui32DevIndex <= 5; ui32DevIndex++) { if((g_sUSBHCD.psUSBDevice[ui32DevIndex].ui32Flags & 0x80000000) == 0) { // // We found one. Set the state to ensure that it gets enumerated. // g_sUSBHCD.psUSBDevice[ui32DevIndex].ui32Flags = 0x80000000; g_sUSBHCD.psUSBDevice[ui32DevIndex].psConfigDescriptor->bLength = 0; g_sUSBHCD.psUSBDevice[ui32DevIndex].ui8Hub = ui8Hub; g_sUSBHCD.psUSBDevice[ui32DevIndex].ui8HubPort = ui8Port; g_sUSBHCD.psUSBDevice[ui32DevIndex].bLowSpeed = bLowSpeed; g_sUSBHCD.psUSBDevice[ui32DevIndex].sDeviceDescriptor.bLength = 0; // // Set the state to ensure enumeration begins. // g_sUSBHCD.piDeviceState[ui32DevIndex] = eHCDDevConnectedHub; while(0)((int32_t (*)(char *, ...))0)("Allocating device %d\n", ui32DevIndex); // // Pass the device index back to the hub driver. // return(ui32DevIndex); } } // // If we get here, there are device slots available so send back an invalid // device index to tell the caller to ignore this device. // return(0); } //***************************************************************************** // // Called when a device is disconnected from a hub. // // \param ui32Index is the index of the USB controller to use. // \param ui32DevIndex is the device index for the USB device that was // disconnected. // //***************************************************************************** void USBHCDHubDeviceDisconnected(uint32_t ui32Index, uint32_t ui32DevIndex) { // // Debug sanity checks. // { if(!(ui32Index == 0)) { __error__("../USB/host/usbhostenum.c", 5119); } }; { if(!(ui32DevIndex && (ui32DevIndex <= 5))) { __error__("../USB/host/usbhostenum.c", 5120); } }; while(0)((int32_t (*)(char *, ...))0)("Disconnection from hub %d, port %d, device %d\n", g_sUSBHCD.psUSBDevice[ui32DevIndex].ui8Hub, g_sUSBHCD.psUSBDevice[ui32DevIndex].ui8HubPort, ui32DevIndex); // // Set the device state to ensure that USBHCDMain cleans it up. // g_sUSBHCD.piDeviceState[ui32DevIndex] = eHCDDevDisconnected; } //***************************************************************************** // // This is the endpoint 0 interrupt handler. // // \return None. // //***************************************************************************** static void USBHCDEnumHandler(void) { uint32_t ui32EPStatus; uint32_t ui32DataSize; // // Get the end point 0 status. // ui32EPStatus = USBEndpointStatus(0x00040000, 0x00000000); // // If there was an error then go to the error state. // if(ui32EPStatus == 0x00000010) { // // Clear this status indicating that the status packet was // received. // USBHostEndpointStatusClear(0x00040000, 0x00000000, 0x00000010); USBFIFOFlush(0x00040000, 0x00000000, 0); // // Just go back to the idle state. // g_sUSBHEP0State.iState = eEP0StateError; return; } switch(g_sUSBHEP0State.iState) { // // Handle the status state, this is a transitory state from // USB_STATE_TX or USB_STATE_RX back to USB_STATE_IDLE. // case eEP0StateStatus: { // // Handle the case of a received status packet. // if(ui32EPStatus & (0x00000001 | 0x00000040)) { // // Clear this status indicating that the status packet was // received. // USBHostEndpointStatusClear(0x00040000, 0x00000000, (0x00000001 | 0x00000040)); } // // Just go back to the idle state. // g_sUSBHEP0State.iState = eEP0StateIdle; break; } // // This state triggers a STATUS IN request from the device. // case eEP0StateStatusIN: { // // Generate an IN request from the device. // USBHostRequestStatus(0x00040000); // // Change to the status phase and wait for the response. // g_sUSBHEP0State.iState = eEP0StateStatus; break; } // // In the IDLE state the code is waiting to receive data from the host. // case eEP0StateIdle: { break; } // // Data is still being sent to the host so handle this in the // EP0StateTx() function. // case eEP0StateSetupOUT: { // // Send remaining data if necessary. // USBHCDEP0StateTx(); break; } // // Handle the receive state for commands that are receiving data on // endpoint 0. // case eEP0StateSetupIN: { // // Generate a new IN request to the device. // USBHostRequestIN(0x00040000, 0x00000000); // // Proceed to the RX state to receive the requested data. // g_sUSBHEP0State.iState = eEP0StateRx; break; } // // The endpoint remains in this state until all requested data has // been received. // case eEP0StateRx: { // // There was a stall on endpoint 0 so go back to the idle state // as this command has been terminated. // if(ui32EPStatus & 0x00000004) { g_sUSBHEP0State.iState = eEP0StateIdle; // // Clear the stalled state on endpoint 0. // USBHostEndpointStatusClear(0x00040000, 0x00000000, ui32EPStatus); break; } // // Set the number of bytes to get out of this next packet. // ui32DataSize = g_sUSBHEP0State.ui32BytesRemaining; if(ui32DataSize > g_sUSBHEP0State.ui32MaxPacketSize) { // // Don't send more than EP0_MAX_PACKET_SIZE bytes. // ui32DataSize = 64; } if(ui32DataSize != 0) { // // Get the data from the USB controller end point 0. // USBEndpointDataGet(0x00040000, 0x00000000, g_sUSBHEP0State.pui8Data, &ui32DataSize); } // // Advance the pointer. // g_sUSBHEP0State.pui8Data += ui32DataSize; // // Decrement the number of bytes that are being waited on. // g_sUSBHEP0State.ui32BytesRemaining -= ui32DataSize; // // Need to ack the data on end point 0 in this case // without setting data end. // USBHostEndpointDataAck(0x00040000, 0x00000000); // // If there was not more than the maximum packet size bytes of data // the this was a int16_t packet and indicates that this transfer // is complete. If there were exactly // g_sUSBHEP0State.ui32MaxPacketSize remaining then there still // needs to be null packet sent before this transfer is complete. // if((ui32DataSize < g_sUSBHEP0State.ui32MaxPacketSize) || (g_sUSBHEP0State.ui32BytesRemaining == 0)) { // // Return to the idle state. // g_sUSBHEP0State.iState = eEP0StateStatus; // // No more data. // g_sUSBHEP0State.pui8Data = 0; // // Send a null packet to acknowledge that all data was // received. // USBEndpointDataSend(0x00040000, 0x00000000, 0x00000142); } else { // // Request more data. // USBHostRequestIN(0x00040000, 0x00000000); } break; } // // The device stalled endpoint zero so check if the stall needs to be // cleared once it has been successfully sent. // case eEP0StateStall: { // // Reset the global end point 0 state to IDLE. // g_sUSBHEP0State.iState = eEP0StateIdle; break; } // // Halt on an unknown state, but only in DEBUG builds. // default: { { if(!(0)) { __error__("../USB/host/usbhostenum.c", 5375); } }; break; } } } //***************************************************************************** // // This internal function handles sending data on endpoint 0. // // \return None. // //***************************************************************************** static void USBHCDEP0StateTx(void) { uint32_t ui32NumBytes; uint8_t *pui8Data; // // In the TX state on endpoint 0. // g_sUSBHEP0State.iState = eEP0StateSetupOUT; // // Set the number of bytes to send this iteration. // ui32NumBytes = g_sUSBHEP0State.ui32BytesRemaining; // // Limit individual transfers to 64 bytes. // if(ui32NumBytes > 64) { ui32NumBytes = 64; } // // Save the pointer so that it can be passed to the USBEndpointDataPut() // function. // pui8Data = (uint8_t *)g_sUSBHEP0State.pui8Data; // // Advance the data pointer and counter to the next data to be sent. // g_sUSBHEP0State.ui32BytesRemaining -= ui32NumBytes; g_sUSBHEP0State.pui8Data += ui32NumBytes; // // Put the data in the correct FIFO. // USBEndpointDataPut(0x00040000, 0x00000000, pui8Data, ui32NumBytes); // // If this is exactly 64 then don't set the last packet yet. // if(ui32NumBytes == 64) { // // There is more data to send or exactly 64 bytes were sent, this // means that there is either more data coming or a null packet needs // to be sent to complete the transaction. // USBEndpointDataSend(0x00040000, 0x00000000, 0x00000102); } else { // // Send the last bit of data. // USBEndpointDataSend(0x00040000, 0x00000000, 0x00000102); // // Now go to the status state and wait for the transmit to complete. // g_sUSBHEP0State.iState = eEP0StateStatusIN; } } //***************************************************************************** // //! This function returns the USB hub port for the requested device instance. //! //! \param ui32Instance is a unique value indicating which device to query. //! //! This function returns the USB hub port for the device that is associated //! with the \e ui32Instance parameter. The caller must use the value for //! \e ui32Instance was passed to the application when it receives a //! USB_EVENT_CONNECTED event. The function returns the USB hub port for //! the interface number specified by the \e ui32Interface parameter. //! //! \return The USB hub port for the requested interface. // //***************************************************************************** uint8_t USBHCDDevHubPort(uint32_t ui32Instance) { uint32_t ui32DevIndex; ui32DevIndex = HCDInstanceToDevIndex(ui32Instance); if(ui32DevIndex == 0xff) { return(ui32DevIndex); } return(g_sUSBHCD.psUSBDevice[ui32DevIndex].ui8HubPort); } //***************************************************************************** // //! This function will return the USB address for the requested device //! instance. //! //! \param ui32Instance is a unique value indicating which device to query. //! //! This function returns the USB address for the device that is associated //! with the \e ui32Instance parameter. The caller must use a value for //! \e ui32Instance have been passed to the application when it receives a //! \b USB_EVENT_CONNECTED event. The function will return the USB address for //! the interface number specified by the \e ui32Interface parameter. //! //! \return The USB address for the requested interface. // //***************************************************************************** uint8_t USBHCDDevAddress(uint32_t ui32Instance) { uint32_t ui32DevIndex; ui32DevIndex = HCDInstanceToDevIndex(ui32Instance); if(ui32DevIndex == 0xff) { return(ui32DevIndex); } return(g_sUSBHCD.psUSBDevice[ui32DevIndex].ui32Address); } //***************************************************************************** // //! This function will return the USB class for the requested device //! instance. //! //! \param ui32Instance is a unique value indicating which device to query. //! \param ui32Interface is the interface number to query for the USB class. //! //! This function returns the USB class for the device that is associated //! with the \e ui32Instance parameter. The caller must use a value for //! \e ui32Instance have been passed to the application when it receives a //! USB_EVENT_CONNECTED event. The function will return the USB class for //! the interface number specified by the \e ui32Interface parameter. If //! \e ui32Interface is set to 0xFFFFFFFF then the function will return the USB //! class for the first interface that is found in the device's USB //! descriptors. //! //! \return The USB class for the requested interface. // //***************************************************************************** uint8_t USBHCDDevClass(uint32_t ui32Instance, uint32_t ui32Interface) { uint32_t ui32DevIndex; tInterfaceDescriptor *psInterface; ui32DevIndex = HCDInstanceToDevIndex(ui32Instance); // // If the instance was not valid return an undefined class. // if(ui32DevIndex == 0xff) { return(0x00); } // // Get the interface descriptor. // psInterface = USBDescGetInterface( g_sUSBHCD.psUSBDevice[ui32DevIndex].psConfigDescriptor, g_sUSBHCD.psUSBDevice[ui32DevIndex].ui32Interface, ui32Interface); // // Make sure that the interface requested actually exists. // if(psInterface) { // // Return the interface class. // return(psInterface->bInterfaceClass); } // // No valid interface so return an undefined class. // return(0x00); } //***************************************************************************** // //! This function will return the USB subclass for the requested device //! instance. //! //! \param ui32Instance is a unique value indicating which device to query. //! \param ui32Interface is the interface number to query for the USB subclass. //! //! This function returns the USB subclass for the device that is associated //! with the \e ui32Instance parameter. The caller must use a value for //! \e ui32Instance have been passed to the application when it receives a //! \b USB_EVENT_CONNECTED event. The function will return the USB subclass //! for the interface number specified by the \e ui32Interface parameter. If //! \e ui32Interface is set to 0xFFFFFFFF then the function will return the USB //! subclass for the first interface that is found in the device's USB //! descriptors. //! //! \return The USB subclass for the requested interface. // //***************************************************************************** uint8_t USBHCDDevSubClass(uint32_t ui32Instance, uint32_t ui32Interface) { uint32_t ui32DevIndex; tInterfaceDescriptor *psInterface; ui32DevIndex = HCDInstanceToDevIndex(ui32Instance); // // If the instance was not valid return an undefined subclass. // if(ui32DevIndex == 0xff) { return(0x00); } // // Get the interface descriptor. // psInterface = USBDescGetInterface( g_sUSBHCD.psUSBDevice[ui32DevIndex].psConfigDescriptor, g_sUSBHCD.psUSBDevice[ui32DevIndex].ui32Interface, ui32Interface); // // Make sure that the interface requested actually exists. // if(psInterface) { // // Return the interface subclass. // return(psInterface->bInterfaceSubClass); } // // No valid interface so return an undefined subclass. // return(0x00); } //***************************************************************************** // //! This function returns the USB protocol for the requested device instance. //! //! \param ui32Instance is a unique value indicating which device to query. //! \param ui32Interface is the interface number to query for the USB protocol. //! //! This function returns the USB protocol for the device that is associated //! with the \e ui32Instance parameter. The caller must use a value for //! \e ui32Instance have been passed to the application when it receives a //! USB_EVENT_CONNECTED event. The function will return the USB protocol for //! the interface number specified by the \e ui32Interface parameter. If //! \e ui32Interface is set to 0xFFFFFFFF then the function will return the USB //! protocol for the first interface that is found in the device's USB //! descriptors. //! //! \return The USB protocol for the requested interface. // //***************************************************************************** uint8_t USBHCDDevProtocol(uint32_t ui32Instance, uint32_t ui32Interface) { uint32_t ui32DevIndex; tInterfaceDescriptor *psInterface; ui32DevIndex = HCDInstanceToDevIndex(ui32Instance); // // If the instance was not valid return an undefined protocol. // if(ui32DevIndex == 0xff) { return(0x00); } // // Get the interface descriptor. // psInterface = USBDescGetInterface( g_sUSBHCD.psUSBDevice[ui32DevIndex].psConfigDescriptor, g_sUSBHCD.psUSBDevice[ui32DevIndex].ui32Interface, ui32Interface); // // Make sure that the interface requested actually exists. // if(psInterface) { // // Return the interface protocol. // return(psInterface->bInterfaceProtocol); } // // No valid interface so return an undefined protocol. // return(0x00); } //***************************************************************************** // // Close the Doxygen group. //! @} // //*****************************************************************************