From ba6fb7522c7333b3a9081a823f2b93a425b36022 Mon Sep 17 00:00:00 2001 From: Sam Anthony Date: Thu, 4 Sep 2025 19:05:46 -0400 Subject: fw: usb --- fw/Makefile | 22 ++- fw/config.h | 21 --- fw/fixed_address_memory.h | 37 ++++ fw/main.c | 8 +- fw/system.c | 21 +++ fw/system.h | 6 + fw/usb.c | 170 +++++++++++++++++++ fw/usb.h | 1 + fw/usb_config.h | 176 +++++++++++++++++++ fw/usb_descriptors.c | 304 +++++++++++++++++++++++++++++++++ fw/usb_device_local.h | 424 ++++++++++++++++++++++++++++++++++++++++++++++ 11 files changed, 1161 insertions(+), 29 deletions(-) delete mode 100644 fw/config.h create mode 100644 fw/fixed_address_memory.h create mode 100644 fw/system.c create mode 100644 fw/system.h create mode 100644 fw/usb.c create mode 100644 fw/usb.h create mode 100755 fw/usb_config.h create mode 100755 fw/usb_descriptors.c create mode 100644 fw/usb_device_local.h (limited to 'fw') 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/config.h b/fw/config.h deleted file mode 100644 index f369673..0000000 --- a/fw/config.h +++ /dev/null @@ -1,21 +0,0 @@ -// CONFIG1 -#pragma config FOSC = INTOSC // Oscillator Selection Bits (INTOSC oscillator: I/O function on CLKIN pin) -#pragma config WDTE = OFF // Watchdog Timer Enable (WDT disabled) -#pragma config PWRTE = OFF // Power-up Timer Enable (PWRT disabled) -#pragma config MCLRE = ON // MCLR Pin Function Select (MCLR pin is MCLR) -#pragma config CP = OFF // Flash Program Memory Code Protection (Program memory code protection is disabled) -#pragma config BOREN = ON // Brown-out Reset Enable (Brown-out Reset enabled) -#pragma config CLKOUTEN = OFF // Clock Out Enable (CLKOUT function is disabled. I/O or oscillator function on the CLKOUT pin) -#pragma config IESO = OFF // Internal/External Switchover Mode (Internal/External Switchover Mode is disabled) -#pragma config FCMEN = OFF // Fail-Safe Clock Monitor Enable (Fail-Safe Clock Monitor is disabled) - -// CONFIG2 -#pragma config WRT = OFF // Flash Memory Self-Write Protection (Write protection off) -#pragma config CPUDIV = NOCLKDIV// CPU System Clock Selection Bit (NO CPU system divide) -#pragma config USBLSCLK = 48MHz // USB Low SPeed Clock Selection bit (System clock expects 48 MHz, FS/LS USB CLKENs divide-by is set to 8.) -#pragma config PLLMULT = 3x // PLL Multipler Selection Bit (3x Output Frequency Selected) -#pragma config PLLEN = ENABLED // PLL Enable Bit (3x or 4x PLL Enabled) -#pragma config STVREN = ON // Stack Overflow/Underflow Reset Enable (Stack Overflow or Underflow will cause a Reset) -#pragma config BORV = LO // Brown-out Reset Voltage Selection (Brown-out Reset Voltage (Vbor), low trip point selected.) -#pragma config LPBOR = OFF // Low-Power Brown Out Reset (Low-Power BOR is disabled) -#pragma config LVP = ON // Low-Voltage Programming Enable 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 +#include + #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/system.c b/fw/system.c new file mode 100644 index 0000000..f369673 --- /dev/null +++ b/fw/system.c @@ -0,0 +1,21 @@ +// CONFIG1 +#pragma config FOSC = INTOSC // Oscillator Selection Bits (INTOSC oscillator: I/O function on CLKIN pin) +#pragma config WDTE = OFF // Watchdog Timer Enable (WDT disabled) +#pragma config PWRTE = OFF // Power-up Timer Enable (PWRT disabled) +#pragma config MCLRE = ON // MCLR Pin Function Select (MCLR pin is MCLR) +#pragma config CP = OFF // Flash Program Memory Code Protection (Program memory code protection is disabled) +#pragma config BOREN = ON // Brown-out Reset Enable (Brown-out Reset enabled) +#pragma config CLKOUTEN = OFF // Clock Out Enable (CLKOUT function is disabled. I/O or oscillator function on the CLKOUT pin) +#pragma config IESO = OFF // Internal/External Switchover Mode (Internal/External Switchover Mode is disabled) +#pragma config FCMEN = OFF // Fail-Safe Clock Monitor Enable (Fail-Safe Clock Monitor is disabled) + +// CONFIG2 +#pragma config WRT = OFF // Flash Memory Self-Write Protection (Write protection off) +#pragma config CPUDIV = NOCLKDIV// CPU System Clock Selection Bit (NO CPU system divide) +#pragma config USBLSCLK = 48MHz // USB Low SPeed Clock Selection bit (System clock expects 48 MHz, FS/LS USB CLKENs divide-by is set to 8.) +#pragma config PLLMULT = 3x // PLL Multipler Selection Bit (3x Output Frequency Selected) +#pragma config PLLEN = ENABLED // PLL Enable Bit (3x or 4x PLL Enabled) +#pragma config STVREN = ON // Stack Overflow/Underflow Reset Enable (Stack Overflow or Underflow will cause a Reset) +#pragma config BORV = LO // Brown-out Reset Voltage Selection (Brown-out Reset Voltage (Vbor), low trip point selected.) +#pragma config LPBOR = OFF // Low-Power Brown Out Reset (Low-Power BOR is disabled) +#pragma config LVP = ON // Low-Voltage Programming Enable 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 + +#include +#include + +#include +#include +#include + +#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<##>_ +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,}; + +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 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 . + 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 + -- cgit v1.2.3