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/usbstdreq.c b/gyro_board/src/usb/LPCUSB/usbstdreq.c
new file mode 100644
index 0000000..6a3fde5
--- /dev/null
+++ b/gyro_board/src/usb/LPCUSB/usbstdreq.c
@@ -0,0 +1,438 @@
+/*
+	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
+	Standard request handler.
+
+	This modules handles the 'chapter 9' processing, specifically the
+	standard device requests in table 9-3 from the universal serial bus
+	specification revision 2.0
+
+	Specific types of devices may specify additional requests (for example
+	HID devices add a GET_DESCRIPTOR request for interfaces), but they
+	will not be part of this module.
+
+	@todo some requests have to return a request error if device not configured:
+	@todo GET_INTERFACE, GET_STATUS, SET_INTERFACE, SYNCH_FRAME
+	@todo this applies to the following if endpoint != 0:
+	@todo SET_FEATURE, GET_FEATURE
+*/
+
+#include "usbdebug.h"
+#include "usbstruct.h"
+#include "usbapi.h"
+
+#define MAX_DESC_HANDLERS	4		/**< device, interface, endpoint, other */
+
+
+/* general descriptor field offsets */
+#define DESC_bLength					0	/**< length offset */
+#define DESC_bDescriptorType			1	/**< descriptor type offset */
+
+/* config descriptor field offsets */
+#define CONF_DESC_wTotalLength			2	/**< total length offset */
+#define CONF_DESC_bConfigurationValue	5	/**< configuration value offset */
+#define CONF_DESC_bmAttributes			7	/**< configuration characteristics */
+
+/* interface descriptor field offsets */
+#define INTF_DESC_bAlternateSetting		3	/**< alternate setting offset */
+
+/* endpoint descriptor field offsets */
+#define ENDP_DESC_bEndpointAddress		2	/**< endpoint address offset */
+#define ENDP_DESC_wMaxPacketSize		4	/**< maximum packet size offset */
+
+
+/** Currently selected configuration */
+static unsigned char				bConfiguration = 0;
+/** Installed custom request handler */
+static TFnHandleRequest	*pfnHandleCustomReq = NULL;
+/** Pointer to registered descriptors */
+static const unsigned char			*pabDescrip = NULL;
+
+
+/**
+	Registers a pointer to a descriptor block containing all descriptors
+	for the device.
+
+	@param [in]	pabDescriptors	The descriptor byte array
+ */
+void USBRegisterDescriptors(const unsigned char *pabDescriptors)
+{
+	pabDescrip = pabDescriptors;
+}
+
+
+/**
+	Parses the list of installed USB descriptors and attempts to find
+	the specified USB descriptor.
+
+	@param [in]		wTypeIndex	Type and index of the descriptor
+	@param [in]		wLangID		Language ID of the descriptor (currently unused)
+	@param [out]	*piLen		Descriptor length
+	@param [out]	*ppbData	Descriptor data
+
+	@return TRUE if the descriptor was found, FALSE otherwise
+ */
+BOOL USBGetDescriptor(unsigned short wTypeIndex, unsigned short wLangID, int *piLen, unsigned char **ppbData)
+{
+	unsigned char	bType, bIndex;
+	unsigned char	*pab;
+	int iCurIndex;
+
+	ASSERT(pabDescrip != NULL);
+
+	bType = GET_DESC_TYPE(wTypeIndex);
+	bIndex = GET_DESC_INDEX(wTypeIndex);
+
+	pab = (unsigned char *)pabDescrip;
+	iCurIndex = 0;
+
+	while (pab[DESC_bLength] != 0) {
+		if (pab[DESC_bDescriptorType] == bType) {
+			if (iCurIndex == bIndex) {
+				// set data pointer
+				*ppbData = pab;
+				// get length from structure
+				if (bType == DESC_CONFIGURATION) {
+					// configuration descriptor is an exception, length is at offset 2 and 3
+					*piLen =	(pab[CONF_DESC_wTotalLength]) |
+					         (pab[CONF_DESC_wTotalLength + 1] << 8);
+				} else {
+					// normally length is at offset 0
+					*piLen = pab[DESC_bLength];
+				}
+				return TRUE;
+			}
+			iCurIndex++;
+		}
+		// skip to next descriptor
+		pab += pab[DESC_bLength];
+	}
+	// nothing found
+	DBG("Desc %x not found!\n", wTypeIndex);
+	return FALSE;
+}
+
+
+/**
+	Configures the device according to the specified configuration index and
+	alternate setting by parsing the installed USB descriptor list.
+	A configuration index of 0 unconfigures the device.
+
+	@param [in]		bConfigIndex	Configuration index
+	@param [in]		bAltSetting		Alternate setting number
+
+	@todo function always returns TRUE, add stricter checking?
+
+	@return TRUE if successfully configured, FALSE otherwise
+ */
+static BOOL USBSetConfiguration(unsigned char bConfigIndex, unsigned char bAltSetting)
+{
+	unsigned char	*pab;
+	unsigned char	bCurConfig, bCurAltSetting;
+	unsigned char	bEP;
+	unsigned short	wMaxPktSize;
+
+	ASSERT(pabDescrip != NULL);
+
+	if (bConfigIndex == 0) {
+		// unconfigure device
+		USBHwConfigDevice(FALSE);
+	} else {
+		// configure endpoints for this configuration/altsetting
+		pab = (unsigned char *)pabDescrip;
+		bCurConfig = 0xFF;
+		bCurAltSetting = 0xFF;
+
+		while (pab[DESC_bLength] != 0) {
+
+			switch (pab[DESC_bDescriptorType]) {
+
+			case DESC_CONFIGURATION:
+				// remember current configuration index
+				bCurConfig = pab[CONF_DESC_bConfigurationValue];
+				break;
+
+			case DESC_INTERFACE:
+				// remember current alternate setting
+				bCurAltSetting = pab[INTF_DESC_bAlternateSetting];
+				break;
+
+			case DESC_ENDPOINT:
+				if ((bCurConfig == bConfigIndex) &&
+				                (bCurAltSetting == bAltSetting)) {
+					// endpoint found for desired config and alternate setting
+					bEP = pab[ENDP_DESC_bEndpointAddress];
+					wMaxPktSize =	(pab[ENDP_DESC_wMaxPacketSize]) |
+					              (pab[ENDP_DESC_wMaxPacketSize + 1] << 8);
+					// configure endpoint
+					USBHwEPConfig(bEP, wMaxPktSize);
+				}
+				break;
+
+			default:
+				break;
+			}
+			// skip to next descriptor
+			pab += pab[DESC_bLength];
+		}
+
+		// configure device
+		USBHwConfigDevice(TRUE);
+	}
+
+	return TRUE;
+}
+SetConfigHandler *SetConfig_CallBack = NULL;
+void USBHwRegisterSetConfigHandler(SetConfigHandler *handler){
+	SetConfig_CallBack = handler;
+}
+
+
+/**
+	Local function to handle a standard device request
+
+	@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 handled successfully
+ */
+static BOOL HandleStdDeviceReq(TSetupPacket *pSetup, int *piLen, unsigned char **ppbData)
+{
+	unsigned char	*pbData = *ppbData;
+
+	switch (pSetup->bRequest) {
+
+	case REQ_GET_STATUS:
+		// bit 0: self-powered
+		// bit 1: remote wakeup = not supported
+		pbData[0] = 0;
+		pbData[1] = 0;
+		*piLen = 2;
+		break;
+
+	case REQ_SET_ADDRESS:
+		USBHwSetAddress(pSetup->wValue);
+		break;
+
+	case REQ_GET_DESCRIPTOR:
+		DBG("D%x", pSetup->wValue);
+		return USBGetDescriptor(pSetup->wValue, pSetup->wIndex, piLen, ppbData);
+
+	case REQ_GET_CONFIGURATION:
+		// indicate if we are configured
+		pbData[0] = bConfiguration;
+		*piLen = 1;
+		break;
+
+	case REQ_SET_CONFIGURATION:
+		if (!USBSetConfiguration(pSetup->wValue & 0xFF, 0)) {
+			DBG("USBSetConfiguration failed!\n");
+			return FALSE;
+		}
+		// configuration successful, update current configuration
+		bConfiguration = pSetup->wValue & 0xFF;
+		if(SetConfig_CallBack != NULL)
+			SetConfig_CallBack();
+		break;
+
+	case REQ_CLEAR_FEATURE:
+	case REQ_SET_FEATURE:
+		if (pSetup->wValue == FEA_REMOTE_WAKEUP) {
+			// put DEVICE_REMOTE_WAKEUP code here
+		}
+		if (pSetup->wValue == FEA_TEST_MODE) {
+			// put TEST_MODE code here
+		}
+		return FALSE;
+
+	case REQ_SET_DESCRIPTOR:
+		DBG("Device req %d not implemented\n", pSetup->bRequest);
+		return FALSE;
+
+	default:
+		DBG("Illegal device req %d\n", pSetup->bRequest);
+		return FALSE;
+	}
+
+	return TRUE;
+}
+
+
+/**
+	Local function to handle a standard interface request
+
+	@param [in]		pSetup		The setup packet
+	@param [in,out]	*piLen		Pointer to data length
+	@param [in]		ppbData		Data buffer.
+
+	@return TRUE if the request was handled successfully
+ */
+static BOOL HandleStdInterfaceReq(TSetupPacket	*pSetup, int *piLen, unsigned char **ppbData)
+{
+	unsigned char	*pbData = *ppbData;
+
+	switch (pSetup->bRequest) {
+
+	case REQ_GET_STATUS:
+		// no bits specified
+		pbData[0] = 0;
+		pbData[1] = 0;
+		*piLen = 2;
+		break;
+
+	case REQ_CLEAR_FEATURE:
+	case REQ_SET_FEATURE:
+		// not defined for interface
+		return FALSE;
+
+	case REQ_GET_INTERFACE:	// TODO use bNumInterfaces
+		// there is only one interface, return n-1 (= 0)
+		pbData[0] = 0;
+		*piLen = 1;
+		break;
+
+	case REQ_SET_INTERFACE:	// TODO use bNumInterfaces
+		// there is only one interface (= 0)
+		if (pSetup->wValue != 0) {
+			return FALSE;
+		}
+		*piLen = 0;
+		break;
+
+	default:
+		DBG("Illegal interface req %d\n", pSetup->bRequest);
+		return FALSE;
+	}
+
+	return TRUE;
+}
+
+
+/**
+	Local function to handle a standard endpoint request
+
+	@param [in]		pSetup		The setup packet
+	@param [in,out]	*piLen		Pointer to data length
+	@param [in]		ppbData		Data buffer.
+
+	@return TRUE if the request was handled successfully
+ */
+static BOOL HandleStdEndPointReq(TSetupPacket	*pSetup, int *piLen, unsigned char **ppbData)
+{
+	unsigned char	*pbData = *ppbData;
+
+	switch (pSetup->bRequest) {
+	case REQ_GET_STATUS:
+		// bit 0 = endpointed halted or not
+		pbData[0] = (USBHwEPGetStatus(pSetup->wIndex) & EP_STATUS_STALLED) ? 1 : 0;
+		pbData[1] = 0;
+		*piLen = 2;
+		break;
+
+	case REQ_CLEAR_FEATURE:
+		if (pSetup->wValue == FEA_ENDPOINT_HALT) {
+			// clear HALT by unstalling
+			USBHwEPStall(pSetup->wIndex, FALSE);
+			break;
+		}
+		// only ENDPOINT_HALT defined for endpoints
+		return FALSE;
+
+	case REQ_SET_FEATURE:
+		if (pSetup->wValue == FEA_ENDPOINT_HALT) {
+			// set HALT by stalling
+			USBHwEPStall(pSetup->wIndex, TRUE);
+			break;
+		}
+		// only ENDPOINT_HALT defined for endpoints
+		return FALSE;
+
+	case REQ_SYNCH_FRAME:
+		DBG("EP req %d not implemented\n", pSetup->bRequest);
+		return FALSE;
+
+	default:
+		DBG("Illegal EP req %d\n", pSetup->bRequest);
+		return FALSE;
+	}
+
+	return TRUE;
+}
+
+
+/**
+	Default handler for standard ('chapter 9') requests
+
+	If a custom request handler was installed, this handler is called first.
+
+	@param [in]		pSetup		The setup packet
+	@param [in,out]	*piLen		Pointer to data length
+	@param [in]		ppbData		Data buffer.
+
+	@return TRUE if the request was handled successfully
+ */
+BOOL USBHandleStandardRequest(TSetupPacket	*pSetup, int *piLen, unsigned char **ppbData)
+{
+	// try the custom request handler first
+	if ((pfnHandleCustomReq != NULL) && pfnHandleCustomReq(pSetup, piLen, ppbData)) {
+		return TRUE;
+	}
+
+	switch (REQTYPE_GET_RECIP(pSetup->bmRequestType)) {
+	case REQTYPE_RECIP_DEVICE:
+		return HandleStdDeviceReq(pSetup, piLen, ppbData);
+	case REQTYPE_RECIP_INTERFACE:
+		return HandleStdInterfaceReq(pSetup, piLen, ppbData);
+	case REQTYPE_RECIP_ENDPOINT:
+		return HandleStdEndPointReq(pSetup, piLen, ppbData);
+	default:
+		return FALSE;
+	}
+}
+
+
+/**
+	Registers a callback for custom device requests
+
+	In USBHandleStandardRequest, the custom request handler gets a first
+	chance at handling the request before it is handed over to the 'chapter 9'
+	request handler.
+
+	This can be used for example in HID devices, where a REQ_GET_DESCRIPTOR
+	request is sent to an interface, which is not covered by the 'chapter 9'
+	specification.
+
+	@param [in]	pfnHandler	Callback function pointer
+ */
+void USBRegisterCustomReqHandler(TFnHandleRequest *pfnHandler)
+{
+	pfnHandleCustomReq = pfnHandler;
+}
+