copied over all of the custom pcb stuff and switched connectors + added PWM headers to the power board
git-svn-id: https://robotics.mvla.net/svn/frc971/2013/trunk/src@4029 f308d9b7-e957-4cde-b6ac-9a88185e7312
diff --git a/gyro_board/src/usb/LPCUSB/usbcontrol.c b/gyro_board/src/usb/LPCUSB/usbcontrol.c
new file mode 100644
index 0000000..e02f492
--- /dev/null
+++ b/gyro_board/src/usb/LPCUSB/usbcontrol.c
@@ -0,0 +1,236 @@
+/*
+ LPCUSB, an USB device driver for LPC microcontrollers
+ Copyright (C) 2006 Bertrik Sikken (bertrik@sikken.nl)
+
+ 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.
+ 3. The name of the author may not be used to endorse or promote products
+ derived from this software without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 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.
+*/
+
+
+/** @file
+ Control transfer handler.
+
+ This module handles control transfers and is normally installed on the
+ endpoint 0 callback.
+
+ Control transfers can be of the following type:
+ 0 Standard;
+ 1 Class;
+ 2 Vendor;
+ 3 Reserved.
+
+ A callback can be installed for each of these control transfers using
+ USBRegisterRequestHandler.
+ When an OUT request arrives, data is collected in the data store provided
+ with the USBRegisterRequestHandler call. When the transfer is done, the
+ callback is called.
+ When an IN request arrives, the callback is called immediately to either
+ put the control transfer data in the data store, or to get a pointer to
+ control transfer data. The data is then packetised and sent to the host.
+*/
+
+#include "usbdebug.h"
+
+#include "usbstruct.h"
+#include "usbapi.h"
+
+
+
+#define MAX_CONTROL_SIZE 128 /**< maximum total size of control transfer data */
+#define MAX_REQ_HANDLERS 4 /**< standard, class, vendor, reserved */
+
+static TSetupPacket Setup; /**< setup packet */
+
+static unsigned char *pbData; /**< pointer to data buffer */
+static int iResidue; /**< remaining bytes in buffer */
+static int iLen; /**< total length of control transfer */
+
+/** Array of installed request handler callbacks */
+static TFnHandleRequest *apfnReqHandlers[4] = {NULL, NULL, NULL, NULL};
+/** Array of installed request data pointers */
+static unsigned char *apbDataStore[4] = {NULL, NULL, NULL, NULL};
+
+/**
+ Local function to handle a request by calling one of the installed
+ request handlers.
+
+ In case of data going from host to device, the data is at *ppbData.
+ In case of data going from device to host, the handler can either
+ choose to write its data at *ppbData or update the data pointer.
+
+ @param [in] pSetup The setup packet
+ @param [in,out] *piLen Pointer to data length
+ @param [in,out] ppbData Data buffer.
+
+ @return TRUE if the request was handles successfully
+ */
+static BOOL _HandleRequest(TSetupPacket *pSetup, int *piLen, unsigned char **ppbData)
+{
+ TFnHandleRequest *pfnHandler;
+ int iType;
+
+ iType = REQTYPE_GET_TYPE(pSetup->bmRequestType);
+ pfnHandler = apfnReqHandlers[iType];
+ if (pfnHandler == NULL) {
+ DBG("No handler for reqtype %d\n", iType);
+ return FALSE;
+ }
+
+ return pfnHandler(pSetup, piLen, ppbData);
+}
+
+
+/**
+ Local function to stall the control endpoint
+
+ @param [in] bEPStat Endpoint status
+ */
+static void StallControlPipe(unsigned char bEPStat)
+{
+ unsigned char *pb;
+ int i;
+
+ USBHwEPStall(0x80, TRUE);
+
+// dump setup packet
+ DBG("STALL on [");
+ pb = (unsigned char *) & Setup;
+ for (i = 0; i < 8; i++) {
+ DBG(" %02x", *pb++);
+ }
+ DBG("] stat=%x\n", bEPStat);
+}
+
+
+/**
+ Sends next chunk of data (possibly 0 bytes) to host
+ */
+static void DataIn(void)
+{
+ int iChunk;
+
+ if (MAX_PACKET_SIZE0 < iResidue) {
+ iChunk = MAX_PACKET_SIZE0;
+ } else {
+ iChunk = iResidue;
+ }
+
+ USBHwEPWrite(0x80, pbData, iChunk);
+ pbData += iChunk;
+ iResidue -= iChunk;
+}
+
+
+/**
+ * Handles IN/OUT transfers on EP0
+ *
+ * @param [in] bEP Endpoint address
+ * @param [in] bEPStat Endpoint status
+ */
+void USBHandleControlTransfer(unsigned char bEP, unsigned char bEPStat)
+{
+ int iChunk, iType;
+
+ if (bEP == 0x00) {
+ // OUT transfer
+ if (bEPStat & EP_STATUS_SETUP) {
+ // setup packet, reset request message state machine
+ USBHwEPRead(0x00, (unsigned char *)&Setup, sizeof(Setup));
+ DBG("S%x", Setup.bRequest);
+
+ // defaults for data pointer and residue
+ iType = REQTYPE_GET_TYPE(Setup.bmRequestType);
+ pbData = apbDataStore[iType];
+ iResidue = Setup.wLength;
+ iLen = Setup.wLength;
+
+ if ((Setup.wLength == 0) ||
+ (REQTYPE_GET_DIR(Setup.bmRequestType) == REQTYPE_DIR_TO_HOST)) {
+ // ask installed handler to process request
+ if (!_HandleRequest(&Setup, &iLen, &pbData)) {
+ DBG("_HandleRequest1 failed\n");
+ StallControlPipe(bEPStat);
+ return;
+ }
+ // send smallest of requested and offered length
+ if (iLen < Setup.wLength) {
+ iResidue = iLen;
+ } else {
+ iResidue = Setup.wLength;
+ }
+
+ // send first part (possibly a zero-length status message)
+ DataIn();
+ }
+ } else {
+ if (iResidue > 0) {
+ // store data
+ iChunk = USBHwEPRead(0x00, pbData, iResidue);
+ if (iChunk < 0) {
+ StallControlPipe(bEPStat);
+ return;
+ }
+ pbData += iChunk;
+ iResidue -= iChunk;
+ if (iResidue == 0) {
+ // received all, send data to handler
+ iType = REQTYPE_GET_TYPE(Setup.bmRequestType);
+ pbData = apbDataStore[iType];
+ if (!_HandleRequest(&Setup, &iLen, &pbData)) {
+ DBG("_HandleRequest2 failed\n");
+ StallControlPipe(bEPStat);
+ return;
+ }
+ // send status to host
+ DataIn();
+ }
+ } else {
+ // absorb zero-length status message
+ iChunk = USBHwEPRead(0x00, NULL, 0);
+ DBG(iChunk > 0 ? "?" : "");
+ }
+ }
+ } else if (bEP == 0x80) {
+ // IN transfer
+ // send more data if available (possibly a 0-length packet)
+ DataIn();
+ } else {
+ ASSERT(FALSE);
+ }
+}
+
+
+/**
+ Registers a callback for handling requests
+
+ @param [in] iType Type of request, e.g. REQTYPE_TYPE_STANDARD
+ @param [in] *pfnHandler Callback function pointer
+ @param [in] *pbDataStore Data storage area for this type of request
+ */
+void USBRegisterRequestHandler(int iType, TFnHandleRequest *pfnHandler, unsigned char *pbDataStore)
+{
+ ASSERT(iType >= 0);
+ ASSERT(iType < 4);
+ apfnReqHandlers[iType] = pfnHandler;
+ apbDataStore[iType] = pbDataStore;
+}
+