aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--doc/protocol5
-rw-r--r--fw/Makefile22
-rw-r--r--fw/fixed_address_memory.h37
-rw-r--r--fw/main.c8
-rw-r--r--fw/system.c (renamed from fw/config.h)0
-rw-r--r--fw/system.h6
-rw-r--r--fw/usb.c170
-rw-r--r--fw/usb.h1
-rwxr-xr-xfw/usb_config.h176
-rwxr-xr-xfw/usb_descriptors.c304
-rw-r--r--fw/usb_device_local.h424
11 files changed, 1145 insertions, 8 deletions
diff --git a/doc/protocol b/doc/protocol
index ea9ecae..2273f40 100644
--- a/doc/protocol
+++ b/doc/protocol
@@ -1,6 +1,11 @@
<command> ::= <opcode> " " <args> "\n"
<response> ::= <retval> "\n"
+Echo:
+<opcode> ::= "e"
+<args> :: <bytes>
+<retval> :: <args>
+
Write EEPROM:
<opcode> ::= "w"
<args> ::= <addr> <bytes>{:pagesize}
diff --git a/fw/Makefile b/fw/Makefile
index b4b0ae9..f7ebebc 100644
--- a/fw/Makefile
+++ b/fw/Makefile
@@ -1,28 +1,34 @@
CC = xc8-cc
-INCLUDES = -I./ -I/home/sam/prog/mla/v2018_11_26/framework/usb/inc
+INCLUDES = -I ./ -I mla_usb/inc
CFLAGS = -mcpu=pic16f1459 -std=c99 $(INCLUDES) -Wall
LDFLAGS =
SYSTEST_DIR = tests/system
-OUT = can_gauge
+HEX = can_gauge.hex
+
SRC = $(shell find . -name "*.c" ! -name "main.c" -maxdepth 1)
+
+OBJ = $(notdir $(SRC:.c=.p1))
HDR = $(wildcard *.h)
-OBJ = $(SRC:.c=.p1)
-HEX = $(OUT).hex
+USB_SRC = mla_usb/src/usb_device.c mla_usb/src/usb_device_cdc.c
+USB_OBJ = $(notdir $(USB_SRC:.c=.p1))
SYSTEST_SRC = $(wildcard $(SYSTEST_DIR)/*.c)
SYSTEST_OBJ = $(notdir $(SYSTEST_SRC:.c=.p1))
SYSTEST_HEX = $(SYSTEST_OBJ:.p1=.hex)
-$(HEX): $(OBJ) main.p1
+$(HEX): $(OBJ) $(USB_OBJ) main.p1
$(CC) $(CFLAGS) $(LDFLAGS) -o $@ $^
%.p1: %.c
$(CC) $(CFLAGS) -c $<
-$(SYSTEST_HEX): %.hex: %.p1 $(OBJ)
+$(USB_OBJ): %.p1: mla_usb/src/%.c
+ $(CC) $(CFLAGS) -c $<
+
+$(SYSTEST_HEX): %.hex: %.p1 $(OBJ) $(USB_OBJ)
$(CC) $(CFLAGS) $(LDFLAGS) -o $@ $^
$(SYSTEST_OBJ): %.p1: $(SYSTEST_DIR)/%.c
@@ -33,6 +39,10 @@ clean:
systest: $(SYSTEST_HEX)
+mla_usb:
+ git submodule init mla_usb
+ git submodule update mla_usb
+
$(OBJ): $(HDR)
.PHONY: clean systest
diff --git a/fw/fixed_address_memory.h b/fw/fixed_address_memory.h
new file mode 100644
index 0000000..c0e6742
--- /dev/null
+++ b/fw/fixed_address_memory.h
@@ -0,0 +1,37 @@
+/*******************************************************************************
+Copyright 2016 Microchip Technology Inc. (www.microchip.com)
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+
+To request to license the code under the MLA license (www.microchip.com/mla_license),
+please contact mla_licensing@microchip.com
+*******************************************************************************/
+
+#ifndef FIXED_MEMORY_ADDRESS_H
+#define FIXED_MEMORY_ADDRESS_H
+
+#define FIXED_ADDRESS_MEMORY
+
+#if(__XC8_VERSION < 2000)
+ #define IN_DATA_BUFFER_ADDRESS_TAG @0x0A0
+ #define OUT_DATA_BUFFER_ADDRESS_TAG @0x120
+ #define CONTROL_BUFFER_ADDRESS_TAG @0x1A0
+ #define DRIVER_DATA_ADDRESS_TAG @0x1A8
+#else
+ #define IN_DATA_BUFFER_ADDRESS_TAG __at(0x0A0)
+ #define OUT_DATA_BUFFER_ADDRESS_TAG __at(0x120)
+ #define CONTROL_BUFFER_ADDRESS_TAG __at(0x1A0)
+ #define DRIVER_DATA_ADDRESS_TAG __at(0x1A8)
+#endif
+
+#endif //FIXED_MEMORY_ADDRESS
diff --git a/fw/main.c b/fw/main.c
index cdc3fc2..3c54179 100644
--- a/fw/main.c
+++ b/fw/main.c
@@ -2,11 +2,13 @@
#include <stdint.h>
+#include <usb_device.h>
+
#include "types.h"
#include "init.h"
#include "spi.h"
#include "eeprom.h"
-#include "config.h"
+#include "usb.h"
void
main(void) {
@@ -14,9 +16,11 @@ main(void) {
pinsInit();
spiInit();
eepromInit();
+ USBDeviceInit();
+ USBDeviceAttach();
for (;;) {
-
+ usbTask();
}
}
diff --git a/fw/config.h b/fw/system.c
index f369673..f369673 100644
--- a/fw/config.h
+++ b/fw/system.c
diff --git a/fw/system.h b/fw/system.h
new file mode 100644
index 0000000..cfb2cfb
--- /dev/null
+++ b/fw/system.h
@@ -0,0 +1,6 @@
+#ifndef SYSTEM_H
+#define SYSTEM_H
+
+#include "fixed_address_memory.h"
+
+#endif // SYSTEM_H
diff --git a/fw/usb.c b/fw/usb.c
new file mode 100644
index 0000000..2992888
--- /dev/null
+++ b/fw/usb.c
@@ -0,0 +1,170 @@
+#include <xc.h>
+
+#include <stdbool.h>
+#include <stdint.h>
+
+#include <usb.h>
+#include <usb_device.h>
+#include <usb_device_cdc.h>
+
+#include "usb.h"
+
+// Line coding
+// See struct USB_CDC_LINE_CODING
+enum {
+ DATA_RATE = 9600, // bps
+ CHAR_FORMAT = NUM_STOP_BITS_1,
+ PARITY_TYPE = PARITY_NONE,
+ DATA_BITS = 8,
+};
+
+// State
+typedef enum {
+ IDLE, // waiting for command
+ CMD_START, // received opcode
+ ECHO,
+ WRITE_EEPROM,
+ READ_EEPROM,
+} State;
+
+static uint8_t readBuf[CDC_DATA_OUT_EP_SIZE];
+static uint8_t writeBuf[CDC_DATA_IN_EP_SIZE];
+static State state = IDLE;
+
+// Handle "e" echo command.
+static void
+echo(void) {
+ static uint8_t readLen = 0u;
+ static uint8_t ri, wi;
+
+ if (!USBUSARTIsTxTrfReady()) {
+ return;
+ }
+
+ if (readLen == 0u) {
+ readLen = getsUSBUSART(readBuf, sizeof(readBuf));
+ ri = 0u;
+ wi = 0u;
+ }
+
+ while (readLen--) {
+ if (wi > sizeof(writeBuf)) {
+ // Overflow; flush
+ putUSBUSART(writeBuf, sizeof(writeBuf));
+ wi = 0u;
+ return; // continue on next call
+ }
+
+ writeBuf[wi] = readBuf[ri];
+ if (readBuf[ri] == '\n') {
+ // End of command
+ putUSBUSART(writeBuf, wi);
+ readLen = 0u;
+ state = IDLE;
+ return;
+ }
+
+ ri++;
+ wi++;
+ }
+}
+
+// Handle "w" write eeprom command.
+static void
+writeEeprom(void) {
+ // TODO
+}
+
+// Handle "r" read eeprom command.
+static void readEeprom(void) {
+ // TODO
+}
+
+static void
+setCmdState(uint8_t opcode) {
+ switch (opcode) {
+ case 'e': // echo
+ state = ECHO;
+ break;
+ case 'w':
+ state = WRITE_EEPROM;
+ break;
+ case 'r':
+ state = READ_EEPROM;
+ break;
+ }
+}
+
+void
+usbTask(void) {
+ static uint8_t opcode = 0u;
+
+ USBDeviceTasks();
+
+ if (USBGetDeviceState() < CONFIGURED_STATE) {
+ return;
+ }
+ if (USBIsDeviceSuspended()) {
+ return;
+ }
+
+ switch (state) {
+ case IDLE:
+ if (getsUSBUSART(&opcode, 1u) > 0) {
+ state = CMD_START;
+ }
+ break;
+ case CMD_START:
+ // Skip space char
+ if (getsUSBUSART(readBuf, 1u) > 0) {
+ setCmdState(opcode);
+ }
+ case ECHO: echo();
+ break;
+ case WRITE_EEPROM: writeEeprom();
+ break;
+ case READ_EEPROM: readEeprom();
+ break;
+ }
+
+ CDCTxService();
+}
+
+static void
+configure(void) {
+ line_coding.dwDTERate = DATA_RATE;
+ line_coding.bCharFormat = CHAR_FORMAT;
+ line_coding.bParityType = PARITY_TYPE;
+ line_coding.bDataBits = DATA_BITS;
+}
+
+bool
+USER_USB_CALLBACK_EVENT_HANDLER(USB_EVENT event, void *pdata, uint16_t size) {
+ switch ((int)event) {
+ case EVENT_TRANSFER:
+ break;
+ case EVENT_SOF:
+ break;
+ case EVENT_SUSPEND:
+ break;
+ case EVENT_RESUME:
+ break;
+ case EVENT_CONFIGURED:
+ CDCInitEP();
+ configure();
+ break;
+ case EVENT_SET_DESCRIPTOR:
+ break;
+ case EVENT_EP0_REQUEST:
+ USBCheckCDCRequest();
+ break;
+ case EVENT_BUS_ERROR:
+ break;
+ case EVENT_TRANSFER_TERMINATED:
+ break;
+ default:
+ break;
+ }
+
+ return true;
+}
diff --git a/fw/usb.h b/fw/usb.h
new file mode 100644
index 0000000..7ceae36
--- /dev/null
+++ b/fw/usb.h
@@ -0,0 +1 @@
+void usbTask(void);
diff --git a/fw/usb_config.h b/fw/usb_config.h
new file mode 100755
index 0000000..1a95468
--- /dev/null
+++ b/fw/usb_config.h
@@ -0,0 +1,176 @@
+/*******************************************************************************
+Copyright 2016 Microchip Technology Inc. (www.microchip.com)
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+
+To request to license the code under the MLA license (www.microchip.com/mla_license),
+please contact mla_licensing@microchip.com
+*******************************************************************************/
+
+/*********************************************************************
+ * Descriptor specific type definitions are defined in: usbd.h
+ ********************************************************************/
+
+#ifndef USBCFG_H
+#define USBCFG_H
+
+/** DEFINITIONS ****************************************************/
+#define USB_EP0_BUFF_SIZE 8 // Valid Options: 8, 16, 32, or 64 bytes.
+ // Using larger options take more SRAM, but
+ // does not provide much advantage in most types
+ // of applications. Exceptions to this, are applications
+ // that use EP0 IN or OUT for sending large amounts of
+ // application related data.
+
+#define USB_MAX_NUM_INT 2 //Set this number to match the maximum interface number used in the descriptors for this firmware project
+#define USB_MAX_EP_NUMBER 2 //Set this number to match the maximum endpoint number used in the descriptors for this firmware project
+
+//Device descriptor - if these two definitions are not defined then
+// a const USB_DEVICE_DESCRIPTOR variable by the exact name of device_dsc
+// must exist.
+#define USB_USER_DEVICE_DESCRIPTOR &device_dsc
+#define USB_USER_DEVICE_DESCRIPTOR_INCLUDE extern const USB_DEVICE_DESCRIPTOR device_dsc
+
+//Configuration descriptors - if these two definitions do not exist then
+// a const uint8_t *const variable named exactly USB_CD_Ptr[] must exist.
+#define USB_USER_CONFIG_DESCRIPTOR USB_CD_Ptr
+#define USB_USER_CONFIG_DESCRIPTOR_INCLUDE extern const uint8_t *const USB_CD_Ptr[]
+
+
+//------------------------------------------------------------------------------
+//Select an endpoint ping-pong bufferring mode. Some microcontrollers only
+//support certain modes. For most applications, it is recommended to use either
+//the USB_PING_PONG__FULL_PING_PONG or USB_PING_PONG__EP0_OUT_ONLY options.
+//The other settings are supported on some devices, but they are not
+//recommended, as they offer inferior control transfer timing performance.
+//See inline code comments in usb_device.c for additional details.
+//Enabling ping pong bufferring on an endpoint generally increases firmware
+//overhead somewhat, but when both buffers are used simultaneously in the
+//firmware, can offer better sustained bandwidth, especially for OUT endpoints.
+//------------------------------------------------------
+//#define USB_PING_PONG_MODE USB_PING_PONG__NO_PING_PONG //Not recommended
+#define USB_PING_PONG_MODE USB_PING_PONG__FULL_PING_PONG //A good all around setting
+//#define USB_PING_PONG_MODE USB_PING_PONG__EP0_OUT_ONLY //Another good setting
+//#define USB_PING_PONG_MODE USB_PING_PONG__ALL_BUT_EP0 //Not recommended
+//------------------------------------------------------------------------------
+
+
+//------------------------------------------------------------------------------
+//Select a USB stack operating mode. In the USB_INTERRUPT mode, the USB stack
+//main task handler gets called only when necessary as an interrupt handler.
+//This can potentially minimize CPU utilization, but adds context saving
+//and restoring overhead associated with interrupts, which can potentially
+//decrease performance.
+//When the USB_POLLING mode is selected, the USB stack main task handler
+//(ex: USBDeviceTasks()) must be called periodically by the application firmware
+//at a minimum rate as described in the inline code comments in usb_device.c.
+//------------------------------------------------------
+#define USB_POLLING
+//#define USB_INTERRUPT
+//------------------------------------------------------------------------------
+
+/* Parameter definitions are defined in usb_device.h */
+#define USB_PULLUP_OPTION USB_PULLUP_ENABLE
+//#define USB_PULLUP_OPTION USB_PULLUP_DISABLED
+
+#define USB_TRANSCEIVER_OPTION USB_INTERNAL_TRANSCEIVER
+//External Transceiver support is not available on all product families. Please
+// refer to the product family datasheet for more information if this feature
+// is available on the target processor.
+//#define USB_TRANSCEIVER_OPTION USB_EXTERNAL_TRANSCEIVER
+
+#define USB_SPEED_OPTION USB_FULL_SPEED
+//#define USB_SPEED_OPTION USB_LOW_SPEED //(this mode is only supported on some microcontrollers)
+
+//------------------------------------------------------------------------------------------------------------------
+//Option to enable auto-arming of the status stage of control transfers, if no
+//"progress" has been made for the USB_STATUS_STAGE_TIMEOUT value.
+//If progress is made (any successful transactions completing on EP0 IN or OUT)
+//the timeout counter gets reset to the USB_STATUS_STAGE_TIMEOUT value.
+//
+//During normal control transfer processing, the USB stack or the application
+//firmware will call USBCtrlEPAllowStatusStage() as soon as the firmware is finished
+//processing the control transfer. Therefore, the status stage completes as
+//quickly as is physically possible. The USB_ENABLE_STATUS_STAGE_TIMEOUTS
+//feature, and the USB_STATUS_STAGE_TIMEOUT value are only relevant, when:
+//1. The application uses the USBDeferStatusStage() API function, but never calls
+// USBCtrlEPAllowStatusStage(). Or:
+//2. The application uses host to device (OUT) control transfers with data stage,
+// and some abnormal error occurs, where the host might try to abort the control
+// transfer, before it has sent all of the data it claimed it was going to send.
+//
+//If the application firmware never uses the USBDeferStatusStage() API function,
+//and it never uses host to device control transfers with data stage, then
+//it is not required to enable the USB_ENABLE_STATUS_STAGE_TIMEOUTS feature.
+
+#define USB_ENABLE_STATUS_STAGE_TIMEOUTS //Comment this out to disable this feature.
+
+//Section 9.2.6 of the USB 2.0 specifications indicate that:
+//1. Control transfers with no data stage: Status stage must complete within
+// 50ms of the start of the control transfer.
+//2. Control transfers with (IN) data stage: Status stage must complete within
+// 50ms of sending the last IN data packet in fullfilment of the data stage.
+//3. Control transfers with (OUT) data stage: No specific status stage timing
+// requirement. However, the total time of the entire control transfer (ex:
+// including the OUT data stage and IN status stage) must not exceed 5 seconds.
+//
+//Therefore, if the USB_ENABLE_STATUS_STAGE_TIMEOUTS feature is used, it is suggested
+//to set the USB_STATUS_STAGE_TIMEOUT value to timeout in less than 50ms. If the
+//USB_ENABLE_STATUS_STAGE_TIMEOUTS feature is not enabled, then the USB_STATUS_STAGE_TIMEOUT
+//parameter is not relevant.
+
+#define USB_STATUS_STAGE_TIMEOUT (uint8_t)45 //Approximate timeout in milliseconds, except when
+ //USB_POLLING mode is used, and USBDeviceTasks() is called at < 1kHz
+ //In this special case, the timeout becomes approximately:
+//Timeout(in milliseconds) = ((1000 * (USB_STATUS_STAGE_TIMEOUT - 1)) / (USBDeviceTasks() polling frequency in Hz))
+//------------------------------------------------------------------------------------------------------------------
+
+#define USB_SUPPORT_DEVICE
+
+#define USB_NUM_STRING_DESCRIPTORS 3 //Set this number to match the total number of string descriptors that are implemented in the usb_descriptors.c file
+
+/*******************************************************************
+ * Event disable options
+ * Enable a definition to suppress a specific event. By default
+ * all events are sent.
+ *******************************************************************/
+//#define USB_DISABLE_SUSPEND_HANDLER
+//#define USB_DISABLE_WAKEUP_FROM_SUSPEND_HANDLER
+//#define USB_DISABLE_SOF_HANDLER
+//#define USB_DISABLE_TRANSFER_TERMINATED_HANDLER
+//#define USB_DISABLE_ERROR_HANDLER
+//#define USB_DISABLE_NONSTANDARD_EP0_REQUEST_HANDLER
+//#define USB_DISABLE_SET_DESCRIPTOR_HANDLER
+//#define USB_DISABLE_SET_CONFIGURATION_HANDLER
+//#define USB_DISABLE_TRANSFER_COMPLETE_HANDLER
+
+/** DEVICE CLASS USAGE *********************************************/
+#define USB_USE_CDC
+
+/** ENDPOINTS ALLOCATION *******************************************/
+
+/* CDC */
+#define CDC_COMM_INTF_ID 0x0
+#define CDC_COMM_EP 1
+#define CDC_COMM_IN_EP_SIZE 10
+
+#define CDC_DATA_INTF_ID 0x01
+#define CDC_DATA_EP 2
+#define CDC_DATA_OUT_EP_SIZE 64
+#define CDC_DATA_IN_EP_SIZE 64
+
+//#define USB_CDC_SUPPORT_ABSTRACT_CONTROL_MANAGEMENT_CAPABILITIES_D2 //Send_Break command
+#define USB_CDC_SUPPORT_ABSTRACT_CONTROL_MANAGEMENT_CAPABILITIES_D1 //Set_Line_Coding, Set_Control_Line_State, Get_Line_Coding, and Serial_State commands
+/** DEFINITIONS ****************************************************/
+
+#endif //USBCFG_H
diff --git a/fw/usb_descriptors.c b/fw/usb_descriptors.c
new file mode 100755
index 0000000..ebc2c06
--- /dev/null
+++ b/fw/usb_descriptors.c
@@ -0,0 +1,304 @@
+/*******************************************************************************
+Copyright 2016 Microchip Technology Inc. (www.microchip.com)
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+
+To request to license the code under the MLA license (www.microchip.com/mla_license),
+please contact mla_licensing@microchip.com
+*******************************************************************************/
+
+/********************************************************************
+-usb_descriptors.c-
+-------------------------------------------------------------------
+Filling in the descriptor values in the usb_descriptors.c file:
+-------------------------------------------------------------------
+
+[Device Descriptors]
+The device descriptor is defined as a USB_DEVICE_DESCRIPTOR type.
+This type is defined in usb_ch9.h Each entry into this structure
+needs to be the correct length for the data type of the entry.
+
+[Configuration Descriptors]
+The configuration descriptor was changed in v2.x from a structure
+to a uint8_t array. Given that the configuration is now a byte array
+each byte of multi-byte fields must be listed individually. This
+means that for fields like the total size of the configuration where
+the field is a 16-bit value "64,0," is the correct entry for a
+configuration that is only 64 bytes long and not "64," which is one
+too few bytes.
+
+The configuration attribute must always have the _DEFAULT
+definition at the minimum. Additional options can be ORed
+to the _DEFAULT attribute. Available options are _SELF and _RWU.
+These definitions are defined in the usb_device.h file. The
+_SELF tells the USB host that this device is self-powered. The
+_RWU tells the USB host that this device supports Remote Wakeup.
+
+[Endpoint Descriptors]
+Like the configuration descriptor, the endpoint descriptors were
+changed in v2.x of the stack from a structure to a uint8_t array. As
+endpoint descriptors also has a field that are multi-byte entities,
+please be sure to specify both bytes of the field. For example, for
+the endpoint size an endpoint that is 64 bytes needs to have the size
+defined as "64,0," instead of "64,"
+
+Take the following example:
+ // Endpoint Descriptor //
+ 0x07, //the size of this descriptor //
+ USB_DESCRIPTOR_ENDPOINT, //Endpoint Descriptor
+ _EP02_IN, //EndpointAddress
+ _INT, //Attributes
+ 0x08,0x00, //size (note: 2 bytes)
+ 0x02, //Interval
+
+The first two parameters are self-explanatory. They specify the
+length of this endpoint descriptor (7) and the descriptor type.
+The next parameter identifies the endpoint, the definitions are
+defined in usb_device.h and has the following naming
+convention:
+_EP<##>_<dir>
+where ## is the endpoint number and dir is the direction of
+transfer. The dir has the value of either 'OUT' or 'IN'.
+The next parameter identifies the type of the endpoint. Available
+options are _BULK, _INT, _ISO, and _CTRL. The _CTRL is not
+typically used because the default control transfer endpoint is
+not defined in the USB descriptors. When _ISO option is used,
+addition options can be ORed to _ISO. Example:
+_ISO|_AD|_FE
+This describes the endpoint as an isochronous pipe with adaptive
+and feedback attributes. See usb_device.h and the USB
+specification for details. The next parameter defines the size of
+the endpoint. The last parameter in the polling interval.
+
+-------------------------------------------------------------------
+Adding a USB String
+-------------------------------------------------------------------
+A string descriptor array should have the following format:
+
+rom struct{byte bLength;byte bDscType;word string[size];}sdxxx={
+sizeof(sdxxx),DSC_STR,<text>};
+
+The above structure provides a means for the C compiler to
+calculate the length of string descriptor sdxxx, where xxx is the
+index number. The first two bytes of the descriptor are descriptor
+length and type. The rest <text> are string texts which must be
+in the unicode format. The unicode format is achieved by declaring
+each character as a word type. The whole text string is declared
+as a word array with the number of characters equals to <size>.
+<size> has to be manually counted and entered into the array
+declaration. Let's study this through an example:
+if the string is "USB" , then the string descriptor should be:
+(Using index 02)
+rom struct{byte bLength;byte bDscType;word string[3];}sd002={
+sizeof(sd002),DSC_STR,'U','S','B'};
+
+A USB project may have multiple strings and the firmware supports
+the management of multiple strings through a look-up table.
+The look-up table is defined as:
+rom const unsigned char *rom USB_SD_Ptr[]={&sd000,&sd001,&sd002};
+
+The above declaration has 3 strings, sd000, sd001, and sd002.
+Strings can be removed or added. sd000 is a specialized string
+descriptor. It defines the language code, usually this is
+US English (0x0409). The index of the string must match the index
+position of the USB_SD_Ptr array, &sd000 must be in position
+USB_SD_Ptr[0], &sd001 must be in position USB_SD_Ptr[1] and so on.
+The look-up table USB_SD_Ptr is used by the get string handler
+function.
+
+-------------------------------------------------------------------
+
+The look-up table scheme also applies to the configuration
+descriptor. A USB device may have multiple configuration
+descriptors, i.e. CFG01, CFG02, etc. To add a configuration
+descriptor, user must implement a structure similar to CFG01.
+The next step is to add the configuration descriptor name, i.e.
+cfg01, cfg02,.., to the look-up table USB_CD_Ptr. USB_CD_Ptr[0]
+is a dummy place holder since configuration 0 is the un-configured
+state according to the definition in the USB specification.
+
+********************************************************************/
+
+/*********************************************************************
+ * Descriptor specific type definitions are defined in:
+ * usb_device.h
+ *
+ * Configuration options are defined in:
+ * usb_config.h
+ ********************************************************************/
+#ifndef __USB_DESCRIPTORS_C
+#define __USB_DESCRIPTORS_C
+
+/** INCLUDES *******************************************************/
+#include "usb.h"
+#include "usb_device_cdc.h"
+
+/** CONSTANTS ******************************************************/
+#if defined(__18CXX)
+#pragma romdata
+#endif
+
+/* Device Descriptor */
+const USB_DEVICE_DESCRIPTOR device_dsc=
+{
+ 0x12, // Size of this descriptor in bytes
+ USB_DESCRIPTOR_DEVICE, // DEVICE descriptor type
+ 0x0200, // USB Spec Release Number in BCD format
+ CDC_DEVICE, // Class Code
+ 0x00, // Subclass code
+ 0x00, // Protocol code
+ USB_EP0_BUFF_SIZE, // Max packet size for EP0, see usb_config.h
+ 0x04D8, // Vendor ID
+ 0x000A, // Product ID: CDC RS-232 Emulation Demo
+ 0x0100, // Device release number in BCD format
+ 0x01, // Manufacturer string index
+ 0x02, // Product string index
+ 0x00, // Device serial number string index
+ 0x01 // Number of possible configurations
+};
+
+/* Configuration 1 Descriptor */
+const uint8_t configDescriptor1[]={
+ /* Configuration Descriptor */
+ 0x09,//sizeof(USB_CFG_DSC), // Size of this descriptor in bytes
+ USB_DESCRIPTOR_CONFIGURATION, // CONFIGURATION descriptor type
+ 67,0, // Total length of data for this cfg
+ 2, // Number of interfaces in this cfg
+ 1, // Index value of this configuration
+ 0, // Configuration string index
+ _DEFAULT | _SELF, // Attributes, see usb_device.h
+ 50, // Max power consumption (2X mA)
+
+ /* Interface Descriptor */
+ 9,//sizeof(USB_INTF_DSC), // Size of this descriptor in bytes
+ USB_DESCRIPTOR_INTERFACE, // INTERFACE descriptor type
+ 0, // Interface Number
+ 0, // Alternate Setting Number
+ 1, // Number of endpoints in this intf
+ COMM_INTF, // Class code
+ ABSTRACT_CONTROL_MODEL, // Subclass code
+ V25TER, // Protocol code
+ 0, // Interface string index
+
+ /* CDC Class-Specific Descriptors */
+ sizeof(USB_CDC_HEADER_FN_DSC),
+ CS_INTERFACE,
+ DSC_FN_HEADER,
+ 0x10,0x01,
+
+ sizeof(USB_CDC_ACM_FN_DSC),
+ CS_INTERFACE,
+ DSC_FN_ACM,
+ USB_CDC_ACM_FN_DSC_VAL,
+
+ sizeof(USB_CDC_UNION_FN_DSC),
+ CS_INTERFACE,
+ DSC_FN_UNION,
+ CDC_COMM_INTF_ID,
+ CDC_DATA_INTF_ID,
+
+ sizeof(USB_CDC_CALL_MGT_FN_DSC),
+ CS_INTERFACE,
+ DSC_FN_CALL_MGT,
+ 0x00,
+ CDC_DATA_INTF_ID,
+
+ /* Endpoint Descriptor */
+ //sizeof(USB_EP_DSC),DSC_EP,_EP02_IN,_INT,CDC_INT_EP_SIZE,0x02,
+ 0x07,/*sizeof(USB_EP_DSC)*/
+ USB_DESCRIPTOR_ENDPOINT, //Endpoint Descriptor
+ _EP01_IN, //EndpointAddress
+ _INTERRUPT, //Attributes
+ 0x0A,0x00, //size
+ 0x02, //Interval
+
+ /* Interface Descriptor */
+ 9,//sizeof(USB_INTF_DSC), // Size of this descriptor in bytes
+ USB_DESCRIPTOR_INTERFACE, // INTERFACE descriptor type
+ 1, // Interface Number
+ 0, // Alternate Setting Number
+ 2, // Number of endpoints in this intf
+ DATA_INTF, // Class code
+ 0, // Subclass code
+ NO_PROTOCOL, // Protocol code
+ 0, // Interface string index
+
+ /* Endpoint Descriptor */
+ //sizeof(USB_EP_DSC),DSC_EP,_EP03_OUT,_BULK,CDC_BULK_OUT_EP_SIZE,0x00,
+ 0x07,/*sizeof(USB_EP_DSC)*/
+ USB_DESCRIPTOR_ENDPOINT, //Endpoint Descriptor
+ _EP02_OUT, //EndpointAddress
+ _BULK, //Attributes
+ 0x40,0x00, //size
+ 0x00, //Interval
+
+ /* Endpoint Descriptor */
+ //sizeof(USB_EP_DSC),DSC_EP,_EP03_IN,_BULK,CDC_BULK_IN_EP_SIZE,0x00
+ 0x07,/*sizeof(USB_EP_DSC)*/
+ USB_DESCRIPTOR_ENDPOINT, //Endpoint Descriptor
+ _EP02_IN, //EndpointAddress
+ _BULK, //Attributes
+ 0x40,0x00, //size
+ 0x00, //Interval
+};
+
+
+//Language code string descriptor
+const struct{uint8_t bLength;uint8_t bDscType;uint16_t string[1];}sd000={
+sizeof(sd000),USB_DESCRIPTOR_STRING,{0x0409}};
+
+//Manufacturer string descriptor
+const struct{uint8_t bLength;uint8_t bDscType;uint16_t string[25];}sd001={
+sizeof(sd001),USB_DESCRIPTOR_STRING,
+{'M','i','c','r','o','c','h','i','p',' ',
+'T','e','c','h','n','o','l','o','g','y',' ','I','n','c','.'
+}};
+
+//Product string descriptor
+const struct{uint8_t bLength;uint8_t bDscType;uint16_t string[25];}sd002={
+sizeof(sd002),USB_DESCRIPTOR_STRING,
+{'C','D','C',' ','R','S','-','2','3','2',' ',
+'E','m','u','l','a','t','i','o','n',' ','D','e','m','o'}
+};
+
+//Serial number string descriptor. If a serial number string is implemented,
+//it should be unique for every single device coming off the production assembly
+//line. Plugging two devices with the same serial number into a computer
+//simultaneously will cause problems (in extreme cases BSOD).
+//Note: Common OSes put restrictions on the possible values that are allowed.
+//For best OS compatibility, the serial number string should only consist
+//of UNICODE encoded numbers 0 through 9 and capital letters A through F.
+//ROM struct{BYTE bLength;BYTE bDscType;WORD string[10];}sd003={
+//sizeof(sd003),USB_DESCRIPTOR_STRING,
+//{'0','1','2','3','4','5','6','7','8','9'}};
+
+//Array of configuration descriptors
+const uint8_t *const USB_CD_Ptr[]=
+{
+ (const uint8_t *const)&configDescriptor1
+};
+//Array of string descriptors
+const uint8_t *const USB_SD_Ptr[USB_NUM_STRING_DESCRIPTORS]=
+{
+ (const uint8_t *const)&sd000,
+ (const uint8_t *const)&sd001,
+ (const uint8_t *const)&sd002
+ //(const uint8_t *const)&sd003 //uncomment if implementing a serial number string descriptor named sd003
+};
+
+#if defined(__18CXX)
+ #pragma code
+#endif
+
+#endif
+/** EOF usb_descriptors.c ****************************************************/
diff --git a/fw/usb_device_local.h b/fw/usb_device_local.h
new file mode 100644
index 0000000..f74ed1d
--- /dev/null
+++ b/fw/usb_device_local.h
@@ -0,0 +1,424 @@
+// DOM-IGNORE-BEGIN
+/*******************************************************************************
+Copyright 2015 Microchip Technology Inc. (www.microchip.com)
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+
+To request to license the code under the MLA license (www.microchip.com/mla_license),
+please contact mla_licensing@microchip.com
+*******************************************************************************/
+//DOM-IGNORE-END
+
+#include "usb_config.h"
+
+/* Short Packet States - Used by Control Transfer Read - CTRL_TRF_TX */
+#define SHORT_PKT_NOT_USED 0
+#define SHORT_PKT_PENDING 1
+#define SHORT_PKT_SENT 2
+
+/* Control Transfer States */
+#define WAIT_SETUP 0
+#define CTRL_TRF_TX 1
+#define CTRL_TRF_RX 2
+
+
+typedef union
+{
+ struct
+ {
+ unsigned char ping_pong_state :1;
+ unsigned char transfer_terminated :1;
+ } bits;
+ uint8_t Val;
+} EP_STATUS;
+
+#if (USB_PING_PONG_MODE == USB_PING_PONG__NO_PING_PONG)
+ #define USB_NEXT_EP0_OUT_PING_PONG 0x0000 // Used in USB Device Mode only
+ #define USB_NEXT_EP0_IN_PING_PONG 0x0000 // Used in USB Device Mode only
+ #define USB_NEXT_PING_PONG 0x0000 // Used in USB Device Mode only
+ #define EP0_OUT_EVEN 0 // Used in USB Device Mode only
+ #define EP0_OUT_ODD 0 // Used in USB Device Mode only
+ #define EP0_IN_EVEN 1 // Used in USB Device Mode only
+ #define EP0_IN_ODD 1 // Used in USB Device Mode only
+ #define EP1_OUT_EVEN 2 // Used in USB Device Mode only
+ #define EP1_OUT_ODD 2 // Used in USB Device Mode only
+ #define EP1_IN_EVEN 3 // Used in USB Device Mode only
+ #define EP1_IN_ODD 3 // Used in USB Device Mode only
+ #define EP2_OUT_EVEN 4 // Used in USB Device Mode only
+ #define EP2_OUT_ODD 4 // Used in USB Device Mode only
+ #define EP2_IN_EVEN 5 // Used in USB Device Mode only
+ #define EP2_IN_ODD 5 // Used in USB Device Mode only
+ #define EP3_OUT_EVEN 6 // Used in USB Device Mode only
+ #define EP3_OUT_ODD 6 // Used in USB Device Mode only
+ #define EP3_IN_EVEN 7 // Used in USB Device Mode only
+ #define EP3_IN_ODD 7 // Used in USB Device Mode only
+ #define EP4_OUT_EVEN 8 // Used in USB Device Mode only
+ #define EP4_OUT_ODD 8 // Used in USB Device Mode only
+ #define EP4_IN_EVEN 9 // Used in USB Device Mode only
+ #define EP4_IN_ODD 9 // Used in USB Device Mode only
+ #define EP5_OUT_EVEN 10 // Used in USB Device Mode only
+ #define EP5_OUT_ODD 10 // Used in USB Device Mode only
+ #define EP5_IN_EVEN 11 // Used in USB Device Mode only
+ #define EP5_IN_ODD 11 // Used in USB Device Mode only
+ #define EP6_OUT_EVEN 12 // Used in USB Device Mode only
+ #define EP6_OUT_ODD 12 // Used in USB Device Mode only
+ #define EP6_IN_EVEN 13 // Used in USB Device Mode only
+ #define EP6_IN_ODD 13 // Used in USB Device Mode only
+ #define EP7_OUT_EVEN 14 // Used in USB Device Mode only
+ #define EP7_OUT_ODD 14 // Used in USB Device Mode only
+ #define EP7_IN_EVEN 15 // Used in USB Device Mode only
+ #define EP7_IN_ODD 15 // Used in USB Device Mode only
+ #define EP8_OUT_EVEN 16 // Used in USB Device Mode only
+ #define EP8_OUT_ODD 16 // Used in USB Device Mode only
+ #define EP8_IN_EVEN 17 // Used in USB Device Mode only
+ #define EP8_IN_ODD 17 // Used in USB Device Mode only
+ #define EP9_OUT_EVEN 18 // Used in USB Device Mode only
+ #define EP9_OUT_ODD 18 // Used in USB Device Mode only
+ #define EP9_IN_EVEN 19 // Used in USB Device Mode only
+ #define EP9_IN_ODD 19 // Used in USB Device Mode only
+ #define EP10_OUT_EVEN 20 // Used in USB Device Mode only
+ #define EP10_OUT_ODD 20 // Used in USB Device Mode only
+ #define EP10_IN_EVEN 21 // Used in USB Device Mode only
+ #define EP10_IN_ODD 21 // Used in USB Device Mode only
+ #define EP11_OUT_EVEN 22 // Used in USB Device Mode only
+ #define EP11_OUT_ODD 22 // Used in USB Device Mode only
+ #define EP11_IN_EVEN 23 // Used in USB Device Mode only
+ #define EP11_IN_ODD 23 // Used in USB Device Mode only
+ #define EP12_OUT_EVEN 24 // Used in USB Device Mode only
+ #define EP12_OUT_ODD 24 // Used in USB Device Mode only
+ #define EP12_IN_EVEN 25 // Used in USB Device Mode only
+ #define EP12_IN_ODD 25 // Used in USB Device Mode only
+ #define EP13_OUT_EVEN 26 // Used in USB Device Mode only
+ #define EP13_OUT_ODD 26 // Used in USB Device Mode only
+ #define EP13_IN_EVEN 27 // Used in USB Device Mode only
+ #define EP13_IN_ODD 27 // Used in USB Device Mode only
+ #define EP14_OUT_EVEN 28 // Used in USB Device Mode only
+ #define EP14_OUT_ODD 28 // Used in USB Device Mode only
+ #define EP14_IN_EVEN 29 // Used in USB Device Mode only
+ #define EP14_IN_ODD 29 // Used in USB Device Mode only
+ #define EP15_OUT_EVEN 30 // Used in USB Device Mode only
+ #define EP15_OUT_ODD 30 // Used in USB Device Mode only
+ #define EP15_IN_EVEN 31 // Used in USB Device Mode only
+ #define EP15_IN_ODD 31 // Used in USB Device Mode only
+
+ #define EP(ep,dir,pp) (2*ep+dir) // Used in USB Device Mode only
+ #define BD(ep,dir,pp) ((8 * ep) + (4 * dir)) // Used in USB Device Mode only
+
+#elif (USB_PING_PONG_MODE == USB_PING_PONG__EP0_OUT_ONLY)
+ #define USB_NEXT_EP0_OUT_PING_PONG 0x0004
+ #define USB_NEXT_EP0_IN_PING_PONG 0x0000
+ #define USB_NEXT_PING_PONG 0x0000
+ #define EP0_OUT_EVEN 0
+ #define EP0_OUT_ODD 1
+ #define EP0_IN_EVEN 2
+ #define EP0_IN_ODD 2
+ #define EP1_OUT_EVEN 3
+ #define EP1_OUT_ODD 3
+ #define EP1_IN_EVEN 4
+ #define EP1_IN_ODD 4
+ #define EP2_OUT_EVEN 5
+ #define EP2_OUT_ODD 5
+ #define EP2_IN_EVEN 6
+ #define EP2_IN_ODD 6
+ #define EP3_OUT_EVEN 7
+ #define EP3_OUT_ODD 7
+ #define EP3_IN_EVEN 8
+ #define EP3_IN_ODD 8
+ #define EP4_OUT_EVEN 9
+ #define EP4_OUT_ODD 9
+ #define EP4_IN_EVEN 10
+ #define EP4_IN_ODD 10
+ #define EP5_OUT_EVEN 11
+ #define EP5_OUT_ODD 11
+ #define EP5_IN_EVEN 12
+ #define EP5_IN_ODD 12
+ #define EP6_OUT_EVEN 13
+ #define EP6_OUT_ODD 13
+ #define EP6_IN_EVEN 14
+ #define EP6_IN_ODD 14
+ #define EP7_OUT_EVEN 15
+ #define EP7_OUT_ODD 15
+ #define EP7_IN_EVEN 16
+ #define EP7_IN_ODD 16
+ #define EP8_OUT_EVEN 17
+ #define EP8_OUT_ODD 17
+ #define EP8_IN_EVEN 18
+ #define EP8_IN_ODD 18
+ #define EP9_OUT_EVEN 19
+ #define EP9_OUT_ODD 19
+ #define EP9_IN_EVEN 20
+ #define EP9_IN_ODD 20
+ #define EP10_OUT_EVEN 21
+ #define EP10_OUT_ODD 21
+ #define EP10_IN_EVEN 22
+ #define EP10_IN_ODD 22
+ #define EP11_OUT_EVEN 23
+ #define EP11_OUT_ODD 23
+ #define EP11_IN_EVEN 24
+ #define EP11_IN_ODD 24
+ #define EP12_OUT_EVEN 25
+ #define EP12_OUT_ODD 25
+ #define EP12_IN_EVEN 26
+ #define EP12_IN_ODD 26
+ #define EP13_OUT_EVEN 27
+ #define EP13_OUT_ODD 27
+ #define EP13_IN_EVEN 28
+ #define EP13_IN_ODD 28
+ #define EP14_OUT_EVEN 29
+ #define EP14_OUT_ODD 29
+ #define EP14_IN_EVEN 30
+ #define EP14_IN_ODD 30
+ #define EP15_OUT_EVEN 31
+ #define EP15_OUT_ODD 31
+ #define EP15_IN_EVEN 32
+ #define EP15_IN_ODD 32
+
+ #define EP(ep,dir,pp) (2u*ep+dir+(((ep==0)&&(dir==0))?pp:1))
+ #define BD(ep,dir,pp) (4u*((2u*ep)+dir+(((ep==0)&&(dir==0))?pp:1)))
+
+#elif (USB_PING_PONG_MODE == USB_PING_PONG__FULL_PING_PONG)
+#if defined (__18CXX) || defined(__C30__) || defined __XC16__ || defined(__XC8)
+ #if (defined (__dsPIC33E__) || defined (__PIC24E__))
+ #define USB_NEXT_EP0_OUT_PING_PONG 0x0008
+ #define USB_NEXT_EP0_IN_PING_PONG 0x0008
+ #define USB_NEXT_PING_PONG 0x0008
+ #else
+ #define USB_NEXT_EP0_OUT_PING_PONG 0x0004
+ #define USB_NEXT_EP0_IN_PING_PONG 0x0004
+ #define USB_NEXT_PING_PONG 0x0004
+ #endif
+ #elif defined(__C32__)
+ #define USB_NEXT_EP0_OUT_PING_PONG 0x0008
+ #define USB_NEXT_EP0_IN_PING_PONG 0x0008
+ #define USB_NEXT_PING_PONG 0x0008
+ #else
+ #error "Not defined for this compiler"
+ #endif
+ #define EP0_OUT_EVEN 0
+ #define EP0_OUT_ODD 1
+ #define EP0_IN_EVEN 2
+ #define EP0_IN_ODD 3
+ #define EP1_OUT_EVEN 4
+ #define EP1_OUT_ODD 5
+ #define EP1_IN_EVEN 6
+ #define EP1_IN_ODD 7
+ #define EP2_OUT_EVEN 8
+ #define EP2_OUT_ODD 9
+ #define EP2_IN_EVEN 10
+ #define EP2_IN_ODD 11
+ #define EP3_OUT_EVEN 12
+ #define EP3_OUT_ODD 13
+ #define EP3_IN_EVEN 14
+ #define EP3_IN_ODD 15
+ #define EP4_OUT_EVEN 16
+ #define EP4_OUT_ODD 17
+ #define EP4_IN_EVEN 18
+ #define EP4_IN_ODD 19
+ #define EP5_OUT_EVEN 20
+ #define EP5_OUT_ODD 21
+ #define EP5_IN_EVEN 22
+ #define EP5_IN_ODD 23
+ #define EP6_OUT_EVEN 24
+ #define EP6_OUT_ODD 25
+ #define EP6_IN_EVEN 26
+ #define EP6_IN_ODD 27
+ #define EP7_OUT_EVEN 28
+ #define EP7_OUT_ODD 29
+ #define EP7_IN_EVEN 30
+ #define EP7_IN_ODD 31
+ #define EP8_OUT_EVEN 32
+ #define EP8_OUT_ODD 33
+ #define EP8_IN_EVEN 34
+ #define EP8_IN_ODD 35
+ #define EP9_OUT_EVEN 36
+ #define EP9_OUT_ODD 37
+ #define EP9_IN_EVEN 38
+ #define EP9_IN_ODD 39
+ #define EP10_OUT_EVEN 40
+ #define EP10_OUT_ODD 41
+ #define EP10_IN_EVEN 42
+ #define EP10_IN_ODD 43
+ #define EP11_OUT_EVEN 44
+ #define EP11_OUT_ODD 45
+ #define EP11_IN_EVEN 46
+ #define EP11_IN_ODD 47
+ #define EP12_OUT_EVEN 48
+ #define EP12_OUT_ODD 49
+ #define EP12_IN_EVEN 50
+ #define EP12_IN_ODD 51
+ #define EP13_OUT_EVEN 52
+ #define EP13_OUT_ODD 53
+ #define EP13_IN_EVEN 54
+ #define EP13_IN_ODD 55
+ #define EP14_OUT_EVEN 56
+ #define EP14_OUT_ODD 57
+ #define EP14_IN_EVEN 58
+ #define EP14_IN_ODD 59
+ #define EP15_OUT_EVEN 60
+ #define EP15_OUT_ODD 61
+ #define EP15_IN_EVEN 62
+ #define EP15_IN_ODD 63
+
+ #define EP(ep,dir,pp) (4*ep+2*dir+pp)
+
+ #if defined (__18CXX) || defined(__C30__) || defined __XC16__ || (__XC8)
+ #if (defined(__dsPIC33E__) || defined (__PIC24E__))
+ #define BD(ep,dir,pp) (8*(4*ep+2*dir+pp))
+ #else
+ #define BD(ep,dir,pp) (4*(4*ep+2*dir+pp))
+ #endif
+ #elif defined(__C32__)
+ #define BD(ep,dir,pp) (8*(4*ep+2*dir+pp))
+ #else
+ #error "Not defined for this compiler"
+ #endif
+
+#elif (USB_PING_PONG_MODE == USB_PING_PONG__ALL_BUT_EP0)
+ #define USB_NEXT_EP0_OUT_PING_PONG 0x0000
+ #define USB_NEXT_EP0_IN_PING_PONG 0x0000
+ #define USB_NEXT_PING_PONG 0x0004
+ #define EP0_OUT_EVEN 0
+ #define EP0_OUT_ODD 0
+ #define EP0_IN_EVEN 1
+ #define EP0_IN_ODD 1
+ #define EP1_OUT_EVEN 2
+ #define EP1_OUT_ODD 3
+ #define EP1_IN_EVEN 4
+ #define EP1_IN_ODD 5
+ #define EP2_OUT_EVEN 6
+ #define EP2_OUT_ODD 7
+ #define EP2_IN_EVEN 8
+ #define EP2_IN_ODD 9
+ #define EP3_OUT_EVEN 10
+ #define EP3_OUT_ODD 11
+ #define EP3_IN_EVEN 12
+ #define EP3_IN_ODD 13
+ #define EP4_OUT_EVEN 14
+ #define EP4_OUT_ODD 15
+ #define EP4_IN_EVEN 16
+ #define EP4_IN_ODD 17
+ #define EP5_OUT_EVEN 18
+ #define EP5_OUT_ODD 19
+ #define EP5_IN_EVEN 20
+ #define EP5_IN_ODD 21
+ #define EP6_OUT_EVEN 22
+ #define EP6_OUT_ODD 23
+ #define EP6_IN_EVEN 24
+ #define EP6_IN_ODD 25
+ #define EP7_OUT_EVEN 26
+ #define EP7_OUT_ODD 27
+ #define EP7_IN_EVEN 28
+ #define EP7_IN_ODD 29
+ #define EP8_OUT_EVEN 30
+ #define EP8_OUT_ODD 31
+ #define EP8_IN_EVEN 32
+ #define EP8_IN_ODD 33
+ #define EP9_OUT_EVEN 34
+ #define EP9_OUT_ODD 35
+ #define EP9_IN_EVEN 36
+ #define EP9_IN_ODD 37
+ #define EP10_OUT_EVEN 38
+ #define EP10_OUT_ODD 39
+ #define EP10_IN_EVEN 40
+ #define EP10_IN_ODD 41
+ #define EP11_OUT_EVEN 42
+ #define EP11_OUT_ODD 43
+ #define EP11_IN_EVEN 44
+ #define EP11_IN_ODD 45
+ #define EP12_OUT_EVEN 46
+ #define EP12_OUT_ODD 47
+ #define EP12_IN_EVEN 48
+ #define EP12_IN_ODD 49
+ #define EP13_OUT_EVEN 50
+ #define EP13_OUT_ODD 51
+ #define EP13_IN_EVEN 52
+ #define EP13_IN_ODD 53
+ #define EP14_OUT_EVEN 54
+ #define EP14_OUT_ODD 55
+ #define EP14_IN_EVEN 56
+ #define EP14_IN_ODD 57
+ #define EP15_OUT_EVEN 58
+ #define EP15_OUT_ODD 59
+ #define EP15_IN_EVEN 60
+ #define EP15_IN_ODD 61
+
+ #define EP(ep,dir,pp) (4*ep+2*dir+((ep==0)?0:(pp-2)))
+ #define BD(ep,dir,pp) (4*(4*ep+2*dir+((ep==0)?0:(pp-2))))
+
+#else
+ #error "No ping pong mode defined."
+#endif
+
+/****** Event callback enabling/disabling macros ********************
+ This section of code is used to disable specific USB events that may not be
+ desired by the user. This can save code size and increase throughput and
+ decrease CPU utiliazation.
+********************************************************************/
+#if defined USB_DISABLE_SUSPEND_HANDLER
+ #define USB_SUSPEND_HANDLER(event,pointer,size)
+
+ #warning "Disabling the suspend handler is not recommended. Proper suspend handling is required to create a compliant USB device."
+#else
+ #define USB_SUSPEND_HANDLER(event,pointer,size) USER_USB_CALLBACK_EVENT_HANDLER((USB_EVENT)event,pointer,size)
+#endif
+
+#if defined USB_DISABLE_WAKEUP_FROM_SUSPEND_HANDLER
+ #define USB_WAKEUP_FROM_SUSPEND_HANDLER(event,pointer,size)
+
+ #warning "Disabling the wake from suspend handler is not recommended. Proper suspend handling is required to create a compliant USB device."
+#else
+ #define USB_WAKEUP_FROM_SUSPEND_HANDLER(event,pointer,size) USER_USB_CALLBACK_EVENT_HANDLER((USB_EVENT)event,pointer,size)
+#endif
+
+#if defined USB_DISABLE_SOF_HANDLER
+ #define USB_SOF_HANDLER(event,pointer,size)
+#else
+ #define USB_SOF_HANDLER(event,pointer,size) USER_USB_CALLBACK_EVENT_HANDLER((USB_EVENT)event,pointer,size)
+#endif
+
+#if defined USB_DISABLE_TRANSFER_TERMINATED_HANDLER
+ #define USB_TRANSFER_TERMINATED_HANDLER(event,pointer,size)
+#else
+ #define USB_TRANSFER_TERMINATED_HANDLER(event,pointer,size) USER_USB_CALLBACK_EVENT_HANDLER((USB_EVENT)event,pointer,size)
+#endif
+
+#if defined USB_DISABLE_ERROR_HANDLER
+ #define USB_ERROR_HANDLER(event,pointer,size)
+#else
+ #define USB_ERROR_HANDLER(event,pointer,size) USER_USB_CALLBACK_EVENT_HANDLER((USB_EVENT)event,pointer,size)
+#endif
+
+#if defined USB_DISABLE_NONSTANDARD_EP0_REQUEST_HANDLER
+ #define USB_NONSTANDARD_EP0_REQUEST_HANDLER(event,pointer,size)
+#else
+ #define USB_NONSTANDARD_EP0_REQUEST_HANDLER(event,pointer,size) USER_USB_CALLBACK_EVENT_HANDLER((USB_EVENT)event,pointer,size)
+#endif
+
+#if defined USB_DISABLE_SET_DESCRIPTOR_HANDLER
+ #define USB_SET_DESCRIPTOR_HANDLER(event,pointer,size)
+#else
+ #define USB_SET_DESCRIPTOR_HANDLER(event,pointer,size) USER_USB_CALLBACK_EVENT_HANDLER((USB_EVENT)event,pointer,size)
+#endif
+
+#if defined USB_DISABLE_SET_CONFIGURATION_HANDLER
+ #define USB_SET_CONFIGURATION_HANDLER(event,pointer,size)
+#else
+ #define USB_SET_CONFIGURATION_HANDLER(event,pointer,size) USER_USB_CALLBACK_EVENT_HANDLER((USB_EVENT)event,pointer,size)
+#endif
+
+#if defined USB_DISABLE_TRANSFER_COMPLETE_HANDLER
+ #define USB_TRANSFER_COMPLETE_HANDLER(event,pointer,size)
+#else
+ #define USB_TRANSFER_COMPLETE_HANDLER(event,pointer,size) USER_USB_CALLBACK_EVENT_HANDLER((USB_EVENT)event,pointer,size)
+#endif
+