diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..6e952e7 --- /dev/null +++ b/.gitignore @@ -0,0 +1,4 @@ +/build/ +/debug/ +/dist/ +/nbproject/private/ \ No newline at end of file diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..fca8e2c --- /dev/null +++ b/Makefile @@ -0,0 +1,113 @@ +# +# There exist several targets which are by default empty and which can be +# used for execution of your targets. These targets are usually executed +# before and after some main targets. They are: +# +# .build-pre: called before 'build' target +# .build-post: called after 'build' target +# .clean-pre: called before 'clean' target +# .clean-post: called after 'clean' target +# .clobber-pre: called before 'clobber' target +# .clobber-post: called after 'clobber' target +# .all-pre: called before 'all' target +# .all-post: called after 'all' target +# .help-pre: called before 'help' target +# .help-post: called after 'help' target +# +# Targets beginning with '.' are not intended to be called on their own. +# +# Main targets can be executed directly, and they are: +# +# build build a specific configuration +# clean remove built files from a configuration +# clobber remove all built files +# all build all configurations +# help print help mesage +# +# Targets .build-impl, .clean-impl, .clobber-impl, .all-impl, and +# .help-impl are implemented in nbproject/makefile-impl.mk. +# +# Available make variables: +# +# CND_BASEDIR base directory for relative paths +# CND_DISTDIR default top distribution directory (build artifacts) +# CND_BUILDDIR default top build directory (object files, ...) +# CONF name of current configuration +# CND_ARTIFACT_DIR_${CONF} directory of build artifact (current configuration) +# CND_ARTIFACT_NAME_${CONF} name of build artifact (current configuration) +# CND_ARTIFACT_PATH_${CONF} path to build artifact (current configuration) +# CND_PACKAGE_DIR_${CONF} directory of package (current configuration) +# CND_PACKAGE_NAME_${CONF} name of package (current configuration) +# CND_PACKAGE_PATH_${CONF} path to package (current configuration) +# +# NOCDDL + + +# Environment +MKDIR=mkdir +CP=cp +CCADMIN=CCadmin +RANLIB=ranlib + + +# build +build: .build-post + +.build-pre: +# Add your pre 'build' code here... + +.build-post: .build-impl +# Add your post 'build' code here... + + +# clean +clean: .clean-post + +.clean-pre: +# Add your pre 'clean' code here... +# WARNING: the IDE does not call this target since it takes a long time to +# simply run make. Instead, the IDE removes the configuration directories +# under build and dist directly without calling make. +# This target is left here so people can do a clean when running a clean +# outside the IDE. + +.clean-post: .clean-impl +# Add your post 'clean' code here... + + +# clobber +clobber: .clobber-post + +.clobber-pre: +# Add your pre 'clobber' code here... + +.clobber-post: .clobber-impl +# Add your post 'clobber' code here... + + +# all +all: .all-post + +.all-pre: +# Add your pre 'all' code here... + +.all-post: .all-impl +# Add your post 'all' code here... + + +# help +help: .help-post + +.help-pre: +# Add your pre 'help' code here... + +.help-post: .help-impl +# Add your post 'help' code here... + + + +# include project implementation makefile +include nbproject/Makefile-impl.mk + +# include project make variables +include nbproject/Makefile-variables.mk diff --git a/inc/app_button_matrix.h b/inc/app_button_matrix.h new file mode 100644 index 0000000..57c2e3a --- /dev/null +++ b/inc/app_button_matrix.h @@ -0,0 +1,13 @@ +#ifndef APP_BUTTON_MATRIX_H +#define APP_BUTTON_MATRIX_H + +#include "mcc.h" + +#define APP_BUTTON_MATRIX_SIZE 9 + +int8_t APP_ButtonMatrixGetIndex(); +void APP_ButtonMatrixScan(void); +void APP_ButtonMatrixInit(void); + +#endif /* APP_BUTTON_MATRIX_H */ + diff --git a/inc/app_device_keyboard.h b/inc/app_device_keyboard.h new file mode 100644 index 0000000..7fcc901 --- /dev/null +++ b/inc/app_device_keyboard.h @@ -0,0 +1,26 @@ +/******************************************************************************* +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 KEYBOARD_H +#define KEYBOARD_H + +void APP_KeyboardInit(void); +void APP_KeyboardTasks(void); + +#endif diff --git a/inc/app_page_selector.h b/inc/app_page_selector.h new file mode 100644 index 0000000..5828dbc --- /dev/null +++ b/inc/app_page_selector.h @@ -0,0 +1,13 @@ +#ifndef APP_PAGE_SELECTOR_H +#define APP_PAGE_SELECTOR_H + +#include "mcc.h" + +#define APP_PAGE_COUNT 4 + +uint8_t APP_PageSelectorGetIndex(); +void APP_PageSelectorUpdate(void); +void APP_PageSelectorInit(void); + +#endif /* APP_PAGE_SELECTOR_H */ + diff --git a/inc/fixed_address_memory.h b/inc/fixed_address_memory.h new file mode 100644 index 0000000..ba40f84 --- /dev/null +++ b/inc/fixed_address_memory.h @@ -0,0 +1,28 @@ +/******************************************************************************* +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 + +#define KEYBOARD_INPUT_REPORT_DATA_BUFFER_ADDRESS_TAG @0x240 +#define KEYBOARD_OUTPUT_REPORT_DATA_BUFFER_ADDRESS_TAG @0x248 + +#endif //FIXED_MEMORY_ADDRESS \ No newline at end of file diff --git a/inc/io_mapping.h b/inc/io_mapping.h new file mode 100644 index 0000000..ab71c21 --- /dev/null +++ b/inc/io_mapping.h @@ -0,0 +1,29 @@ +/******************************************************************************* +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 +*******************************************************************************/ +#include "system.h" + +/* Demo I/O options. */ +#define LED_USB_DEVICE_STATE LED_D1 +#define LED_USB_DEVICE_HID_KEYBOARD_CAPS_LOCK LED_D2 + +#define BUTTON_USB_DEVICE_HID_KEYBOARD_KEY BUTTON_S1 +#define BUTTON_USB_DEVICE_REMOTE_WAKEUP BUTTON_S1 + +/* USB Stack I/O options. */ +#define self_power 0 diff --git a/inc/mcc.h b/inc/mcc.h new file mode 100644 index 0000000..aba8135 --- /dev/null +++ b/inc/mcc.h @@ -0,0 +1,86 @@ +/** + @Generated PIC10 / PIC12 / PIC16 / PIC18 MCUs Header File + + @Company: + Microchip Technology Inc. + + @File Name: + mcc.h + + @Summary: + This is the mcc.h file generated using PIC10 / PIC12 / PIC16 / PIC18 MCUs + + @Description: + This header file provides implementations for driver APIs for all modules selected in the GUI. + Generation Information : + Product Revision : PIC10 / PIC12 / PIC16 / PIC18 MCUs - 1.65.2 + Device : PIC18F14K50 + Driver Version : 2.00 + The generated drivers are tested against the following: + Compiler : XC8 1.45 or later + MPLAB : MPLAB X 4.15 +*/ + +/* + (c) 2018 Microchip Technology Inc. and its subsidiaries. + + Subject to your compliance with these terms, you may use Microchip software and any + derivatives exclusively with Microchip products. It is your responsibility to comply with third party + license terms applicable to your use of third party software (including open source software) that + may accompany Microchip software. + + THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES, WHETHER + EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE, INCLUDING ANY + IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY, AND FITNESS + FOR A PARTICULAR PURPOSE. + + IN NO EVENT WILL MICROCHIP BE LIABLE FOR ANY INDIRECT, SPECIAL, PUNITIVE, + INCIDENTAL OR CONSEQUENTIAL LOSS, DAMAGE, COST OR EXPENSE OF ANY KIND + WHATSOEVER RELATED TO THE SOFTWARE, HOWEVER CAUSED, EVEN IF MICROCHIP + HAS BEEN ADVISED OF THE POSSIBILITY OR THE DAMAGES ARE FORESEEABLE. TO + THE FULLEST EXTENT ALLOWED BY LAW, MICROCHIP'S TOTAL LIABILITY ON ALL + CLAIMS IN ANY WAY RELATED TO THIS SOFTWARE WILL NOT EXCEED THE AMOUNT + OF FEES, IF ANY, THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR THIS + SOFTWARE. +*/ + +#ifndef MCC_H +#define MCC_H +#include +#include "pin_manager.h" +#include +#include + +#define _XTAL_FREQ 48000000 + + +/** + * @Param + none + * @Returns + none + * @Description + Initializes the device to the default states configured in the + * MCC GUI + * @Example + SYSTEM_Initialize(void); + */ +void SYSTEM_Initialize(void); + +/** + * @Param + none + * @Returns + none + * @Description + Initializes the oscillator to the default states configured in the + * MCC GUI + * @Example + OSCILLATOR_Initialize(void); + */ +void OSCILLATOR_Initialize(void); + +#endif /* MCC_H */ +/** + End of File +*/ \ No newline at end of file diff --git a/inc/pin_manager.h b/inc/pin_manager.h new file mode 100644 index 0000000..d484571 --- /dev/null +++ b/inc/pin_manager.h @@ -0,0 +1,245 @@ +/** + @Generated Pin Manager Header File + + @Company: + Microchip Technology Inc. + + @File Name: + pin_manager.h + + @Summary: + This is the Pin Manager file generated using PIC10 / PIC12 / PIC16 / PIC18 MCUs + + @Description + This header file provides APIs for driver for . + Generation Information : + Product Revision : PIC10 / PIC12 / PIC16 / PIC18 MCUs - 1.65.2 + Device : PIC18F14K50 + Driver Version : 2.01 + The generated drivers are tested against the following: + Compiler : XC8 1.45 + MPLAB : MPLAB X 4.15 +*/ + +/* + (c) 2018 Microchip Technology Inc. and its subsidiaries. + + Subject to your compliance with these terms, you may use Microchip software and any + derivatives exclusively with Microchip products. It is your responsibility to comply with third party + license terms applicable to your use of third party software (including open source software) that + may accompany Microchip software. + + THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES, WHETHER + EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE, INCLUDING ANY + IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY, AND FITNESS + FOR A PARTICULAR PURPOSE. + + IN NO EVENT WILL MICROCHIP BE LIABLE FOR ANY INDIRECT, SPECIAL, PUNITIVE, + INCIDENTAL OR CONSEQUENTIAL LOSS, DAMAGE, COST OR EXPENSE OF ANY KIND + WHATSOEVER RELATED TO THE SOFTWARE, HOWEVER CAUSED, EVEN IF MICROCHIP + HAS BEEN ADVISED OF THE POSSIBILITY OR THE DAMAGES ARE FORESEEABLE. TO + THE FULLEST EXTENT ALLOWED BY LAW, MICROCHIP'S TOTAL LIABILITY ON ALL + CLAIMS IN ANY WAY RELATED TO THIS SOFTWARE WILL NOT EXCEED THE AMOUNT + OF FEES, IF ANY, THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR THIS + SOFTWARE. +*/ + +#ifndef PIN_MANAGER_H +#define PIN_MANAGER_H + +#define INPUT 1 +#define OUTPUT 0 + +#define HIGH 1 +#define LOW 0 + +#define ANALOG 1 +#define DIGITAL 0 + +#define PULL_UP_ENABLED 1 +#define PULL_UP_DISABLED 0 + +// get/set BTN_COL_1 aliases +#define BTN_COL_1_TRIS TRISBbits.TRISB4 +#define BTN_COL_1_LAT LATBbits.LATB4 +#define BTN_COL_1_PORT PORTBbits.RB4 +#define BTN_COL_1_WPU WPUBbits.WPUB4 +#define BTN_COL_1_ANS ANSELHbits.ANS10 +#define BTN_COL_1_SetHigh() do { LATBbits.LATB4 = 1; } while(0) +#define BTN_COL_1_SetLow() do { LATBbits.LATB4 = 0; } while(0) +#define BTN_COL_1_Toggle() do { LATBbits.LATB4 = ~LATBbits.LATB4; } while(0) +#define BTN_COL_1_GetValue() PORTBbits.RB4 +#define BTN_COL_1_SetDigitalInput() do { TRISBbits.TRISB4 = 1; } while(0) +#define BTN_COL_1_SetDigitalOutput() do { TRISBbits.TRISB4 = 0; } while(0) +#define BTN_COL_1_SetPullup() do { WPUBbits.WPUB4 = 1; } while(0) +#define BTN_COL_1_ResetPullup() do { WPUBbits.WPUB4 = 0; } while(0) +#define BTN_COL_1_SetAnalogMode() do { ANSELHbits.ANS10 = 1; } while(0) +#define BTN_COL_1_SetDigitalMode() do { ANSELHbits.ANS10 = 0; } while(0) + +// get/set BTN_COL_2 aliases +#define BTN_COL_2_TRIS TRISBbits.TRISB5 +#define BTN_COL_2_LAT LATBbits.LATB5 +#define BTN_COL_2_PORT PORTBbits.RB5 +#define BTN_COL_2_WPU WPUBbits.WPUB5 +#define BTN_COL_2_ANS ANSELHbits.ANS11 +#define BTN_COL_2_SetHigh() do { LATBbits.LATB5 = 1; } while(0) +#define BTN_COL_2_SetLow() do { LATBbits.LATB5 = 0; } while(0) +#define BTN_COL_2_Toggle() do { LATBbits.LATB5 = ~LATBbits.LATB5; } while(0) +#define BTN_COL_2_GetValue() PORTBbits.RB5 +#define BTN_COL_2_SetDigitalInput() do { TRISBbits.TRISB5 = 1; } while(0) +#define BTN_COL_2_SetDigitalOutput() do { TRISBbits.TRISB5 = 0; } while(0) +#define BTN_COL_2_SetPullup() do { WPUBbits.WPUB5 = 1; } while(0) +#define BTN_COL_2_ResetPullup() do { WPUBbits.WPUB5 = 0; } while(0) +#define BTN_COL_2_SetAnalogMode() do { ANSELHbits.ANS11 = 1; } while(0) +#define BTN_COL_2_SetDigitalMode() do { ANSELHbits.ANS11 = 0; } while(0) + +// get/set BTN_COL_3 aliases +#define BTN_COL_3_TRIS TRISBbits.TRISB6 +#define BTN_COL_3_LAT LATBbits.LATB6 +#define BTN_COL_3_PORT PORTBbits.RB6 +#define BTN_COL_3_WPU WPUBbits.WPUB6 +#define BTN_COL_3_SetHigh() do { LATBbits.LATB6 = 1; } while(0) +#define BTN_COL_3_SetLow() do { LATBbits.LATB6 = 0; } while(0) +#define BTN_COL_3_Toggle() do { LATBbits.LATB6 = ~LATBbits.LATB6; } while(0) +#define BTN_COL_3_GetValue() PORTBbits.RB6 +#define BTN_COL_3_SetDigitalInput() do { TRISBbits.TRISB6 = 1; } while(0) +#define BTN_COL_3_SetDigitalOutput() do { TRISBbits.TRISB6 = 0; } while(0) +#define BTN_COL_3_SetPullup() do { WPUBbits.WPUB6 = 1; } while(0) +#define BTN_COL_3_ResetPullup() do { WPUBbits.WPUB6 = 0; } while(0) + +// get/set SWT_IN aliases +#define SWT_IN_TRIS TRISBbits.TRISB7 +#define SWT_IN_LAT LATBbits.LATB7 +#define SWT_IN_PORT PORTBbits.RB7 +#define SWT_IN_WPU WPUBbits.WPUB7 +#define SWT_IN_SetHigh() do { LATBbits.LATB7 = 1; } while(0) +#define SWT_IN_SetLow() do { LATBbits.LATB7 = 0; } while(0) +#define SWT_IN_Toggle() do { LATBbits.LATB7 = ~LATBbits.LATB7; } while(0) +#define SWT_IN_GetValue() PORTBbits.RB7 +#define SWT_IN_SetDigitalInput() do { TRISBbits.TRISB7 = 1; } while(0) +#define SWT_IN_SetDigitalOutput() do { TRISBbits.TRISB7 = 0; } while(0) +#define SWT_IN_SetPullup() do { WPUBbits.WPUB7 = 1; } while(0) +#define SWT_IN_ResetPullup() do { WPUBbits.WPUB7 = 0; } while(0) + +// get/set BTN_ROW_1 aliases +#define BTN_ROW_1_TRIS TRISCbits.TRISC0 +#define BTN_ROW_1_LAT LATCbits.LATC0 +#define BTN_ROW_1_PORT PORTCbits.RC0 +#define BTN_ROW_1_ANS ANSELbits.ANS4 +#define BTN_ROW_1_SetHigh() do { LATCbits.LATC0 = 1; } while(0) +#define BTN_ROW_1_SetLow() do { LATCbits.LATC0 = 0; } while(0) +#define BTN_ROW_1_Toggle() do { LATCbits.LATC0 = ~LATCbits.LATC0; } while(0) +#define BTN_ROW_1_GetValue() PORTCbits.RC0 +#define BTN_ROW_1_SetDigitalInput() do { TRISCbits.TRISC0 = 1; } while(0) +#define BTN_ROW_1_SetDigitalOutput() do { TRISCbits.TRISC0 = 0; } while(0) +#define BTN_ROW_1_SetAnalogMode() do { ANSELbits.ANS4 = 1; } while(0) +#define BTN_ROW_1_SetDigitalMode() do { ANSELbits.ANS4 = 0; } while(0) + +// get/set BTN_ROW_2 aliases +#define BTN_ROW_2_TRIS TRISCbits.TRISC1 +#define BTN_ROW_2_LAT LATCbits.LATC1 +#define BTN_ROW_2_PORT PORTCbits.RC1 +#define BTN_ROW_2_ANS ANSELbits.ANS5 +#define BTN_ROW_2_SetHigh() do { LATCbits.LATC1 = 1; } while(0) +#define BTN_ROW_2_SetLow() do { LATCbits.LATC1 = 0; } while(0) +#define BTN_ROW_2_Toggle() do { LATCbits.LATC1 = ~LATCbits.LATC1; } while(0) +#define BTN_ROW_2_GetValue() PORTCbits.RC1 +#define BTN_ROW_2_SetDigitalInput() do { TRISCbits.TRISC1 = 1; } while(0) +#define BTN_ROW_2_SetDigitalOutput() do { TRISCbits.TRISC1 = 0; } while(0) +#define BTN_ROW_2_SetAnalogMode() do { ANSELbits.ANS5 = 1; } while(0) +#define BTN_ROW_2_SetDigitalMode() do { ANSELbits.ANS5 = 0; } while(0) + +// get/set BTN_ROW_3 aliases +#define BTN_ROW_3_TRIS TRISCbits.TRISC2 +#define BTN_ROW_3_LAT LATCbits.LATC2 +#define BTN_ROW_3_PORT PORTCbits.RC2 +#define BTN_ROW_3_ANS ANSELbits.ANS6 +#define BTN_ROW_3_SetHigh() do { LATCbits.LATC2 = 1; } while(0) +#define BTN_ROW_3_SetLow() do { LATCbits.LATC2 = 0; } while(0) +#define BTN_ROW_3_Toggle() do { LATCbits.LATC2 = ~LATCbits.LATC2; } while(0) +#define BTN_ROW_3_GetValue() PORTCbits.RC2 +#define BTN_ROW_3_SetDigitalInput() do { TRISCbits.TRISC2 = 1; } while(0) +#define BTN_ROW_3_SetDigitalOutput() do { TRISCbits.TRISC2 = 0; } while(0) +#define BTN_ROW_3_SetAnalogMode() do { ANSELbits.ANS6 = 1; } while(0) +#define BTN_ROW_3_SetDigitalMode() do { ANSELbits.ANS6 = 0; } while(0) + +// get/set LED_4 aliases +#define LED_4_TRIS TRISCbits.TRISC3 +#define LED_4_LAT LATCbits.LATC3 +#define LED_4_PORT PORTCbits.RC3 +#define LED_4_ANS ANSELbits.ANS7 +#define LED_4_SetHigh() do { LATCbits.LATC3 = 1; } while(0) +#define LED_4_SetLow() do { LATCbits.LATC3 = 0; } while(0) +#define LED_4_Toggle() do { LATCbits.LATC3 = ~LATCbits.LATC3; } while(0) +#define LED_4_GetValue() PORTCbits.RC3 +#define LED_4_SetDigitalInput() do { TRISCbits.TRISC3 = 1; } while(0) +#define LED_4_SetDigitalOutput() do { TRISCbits.TRISC3 = 0; } while(0) +#define LED_4_SetAnalogMode() do { ANSELbits.ANS7 = 1; } while(0) +#define LED_4_SetDigitalMode() do { ANSELbits.ANS7 = 0; } while(0) + +// get/set LED_3 aliases +#define LED_3_TRIS TRISCbits.TRISC4 +#define LED_3_LAT LATCbits.LATC4 +#define LED_3_PORT PORTCbits.RC4 +#define LED_3_SetHigh() do { LATCbits.LATC4 = 1; } while(0) +#define LED_3_SetLow() do { LATCbits.LATC4 = 0; } while(0) +#define LED_3_Toggle() do { LATCbits.LATC4 = ~LATCbits.LATC4; } while(0) +#define LED_3_GetValue() PORTCbits.RC4 +#define LED_3_SetDigitalInput() do { TRISCbits.TRISC4 = 1; } while(0) +#define LED_3_SetDigitalOutput() do { TRISCbits.TRISC4 = 0; } while(0) + +// get/set SWT_OUT aliases +#define SWT_OUT_TRIS TRISCbits.TRISC5 +#define SWT_OUT_LAT LATCbits.LATC5 +#define SWT_OUT_PORT PORTCbits.RC5 +#define SWT_OUT_SetHigh() do { LATCbits.LATC5 = 1; } while(0) +#define SWT_OUT_SetLow() do { LATCbits.LATC5 = 0; } while(0) +#define SWT_OUT_Toggle() do { LATCbits.LATC5 = ~LATCbits.LATC5; } while(0) +#define SWT_OUT_GetValue() PORTCbits.RC5 +#define SWT_OUT_SetDigitalInput() do { TRISCbits.TRISC5 = 1; } while(0) +#define SWT_OUT_SetDigitalOutput() do { TRISCbits.TRISC5 = 0; } while(0) + +// get/set LED_2 aliases +#define LED_2_TRIS TRISCbits.TRISC6 +#define LED_2_LAT LATCbits.LATC6 +#define LED_2_PORT PORTCbits.RC6 +#define LED_2_ANS ANSELHbits.ANS8 +#define LED_2_SetHigh() do { LATCbits.LATC6 = 1; } while(0) +#define LED_2_SetLow() do { LATCbits.LATC6 = 0; } while(0) +#define LED_2_Toggle() do { LATCbits.LATC6 = ~LATCbits.LATC6; } while(0) +#define LED_2_GetValue() PORTCbits.RC6 +#define LED_2_SetDigitalInput() do { TRISCbits.TRISC6 = 1; } while(0) +#define LED_2_SetDigitalOutput() do { TRISCbits.TRISC6 = 0; } while(0) +#define LED_2_SetAnalogMode() do { ANSELHbits.ANS8 = 1; } while(0) +#define LED_2_SetDigitalMode() do { ANSELHbits.ANS8 = 0; } while(0) + +// get/set LED_1 aliases +#define LED_1_TRIS TRISCbits.TRISC7 +#define LED_1_LAT LATCbits.LATC7 +#define LED_1_PORT PORTCbits.RC7 +#define LED_1_ANS ANSELHbits.ANS9 +#define LED_1_SetHigh() do { LATCbits.LATC7 = 1; } while(0) +#define LED_1_SetLow() do { LATCbits.LATC7 = 0; } while(0) +#define LED_1_Toggle() do { LATCbits.LATC7 = ~LATCbits.LATC7; } while(0) +#define LED_1_GetValue() PORTCbits.RC7 +#define LED_1_SetDigitalInput() do { TRISCbits.TRISC7 = 1; } while(0) +#define LED_1_SetDigitalOutput() do { TRISCbits.TRISC7 = 0; } while(0) +#define LED_1_SetAnalogMode() do { ANSELHbits.ANS9 = 1; } while(0) +#define LED_1_SetDigitalMode() do { ANSELHbits.ANS9 = 0; } while(0) + +/** + @Param + none + @Returns + none + @Description + GPIO and peripheral I/O initialization + @Example + PIN_MANAGER_Initialize(); + */ +void PIN_MANAGER_Initialize(void); + +#endif // PIN_MANAGER_H +/** + End of File +*/ \ No newline at end of file diff --git a/inc/system_config.h b/inc/system_config.h new file mode 100644 index 0000000..dcfee0e --- /dev/null +++ b/inc/system_config.h @@ -0,0 +1,20 @@ +/******************************************************************************* +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 +*******************************************************************************/ + +#include "usb_config.h" diff --git a/inc/usb_config.h b/inc/usb_config.h new file mode 100644 index 0000000..cecd612 --- /dev/null +++ b/inc/usb_config.h @@ -0,0 +1,171 @@ +/******************************************************************************* +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 + +#include "usb_ch9.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 1 //Set this number to match the maximum interface number used in the descriptors for this firmware project +#define USB_MAX_EP_NUMBER 1 //Set this number to match the maximum endpoint number used in the descriptors for this firmware project + +//------------------------------------------------------------------------------ +//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) + +#define MY_VID 0x1209 +#define MY_PID 0x0BAD + +//------------------------------------------------------------------------------------------------------------------ +//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_HID + +/** ENDPOINTS ALLOCATION *******************************************/ + +/* HID */ +#define HID_INTF_ID 0x00 +#define HID_EP 1 +#define HID_INT_OUT_EP_SIZE 1 +#define HID_INT_IN_EP_SIZE 8 +#define HID_NUM_OF_DSC 1 +#define HID_RPT01_SIZE 63 +//#define USER_GET_REPORT_HANDLER USBHIDCBGetReportHandler +#define USER_SET_REPORT_HANDLER USBHIDCBSetReportHandler +#define USB_DEVICE_HID_IDLE_RATE_CALLBACK(reportID, newIdleRate) USBHIDCBSetIdleRateHandler(reportID, newIdleRate) + +#define CDC_COMM_IN_EP_SIZE 255 //TODO: check if needed + +/** DEFINITIONS ****************************************************/ + +#endif //USBCFG_H diff --git a/nbproject/Makefile-default.mk b/nbproject/Makefile-default.mk new file mode 100644 index 0000000..3cceb50 --- /dev/null +++ b/nbproject/Makefile-default.mk @@ -0,0 +1,327 @@ +# +# Generated Makefile - do not edit! +# +# Edit the Makefile in the project folder instead (../Makefile). Each target +# has a -pre and a -post target defined where you can add customized code. +# +# This makefile implements configuration specific macros and targets. + + +# Include project Makefile +ifeq "${IGNORE_LOCAL}" "TRUE" +# do not include local makefile. User is passing all local related variables already +else +include Makefile +# Include makefile containing local settings +ifeq "$(wildcard nbproject/Makefile-local-default.mk)" "nbproject/Makefile-local-default.mk" +include nbproject/Makefile-local-default.mk +endif +endif + +# Environment +MKDIR=gnumkdir -p +RM=rm -f +MV=mv +CP=cp + +# Macros +CND_CONF=default +ifeq ($(TYPE_IMAGE), DEBUG_RUN) +IMAGE_TYPE=debug +OUTPUT_SUFFIX=elf +DEBUGGABLE_SUFFIX=elf +FINAL_IMAGE=dist/${CND_CONF}/${IMAGE_TYPE}/palette.X.${IMAGE_TYPE}.${OUTPUT_SUFFIX} +else +IMAGE_TYPE=production +OUTPUT_SUFFIX=hex +DEBUGGABLE_SUFFIX=elf +FINAL_IMAGE=dist/${CND_CONF}/${IMAGE_TYPE}/palette.X.${IMAGE_TYPE}.${OUTPUT_SUFFIX} +endif + +ifeq ($(COMPARE_BUILD), true) +COMPARISON_BUILD=-mafrlcsj +else +COMPARISON_BUILD= +endif + +ifdef SUB_IMAGE_ADDRESS + +else +SUB_IMAGE_ADDRESS_COMMAND= +endif + +# Object Directory +OBJECTDIR=build/${CND_CONF}/${IMAGE_TYPE} + +# Distribution Directory +DISTDIR=dist/${CND_CONF}/${IMAGE_TYPE} + +# Source Files Quoted if spaced +SOURCEFILES_QUOTED_IF_SPACED=src/app_device_keyboard.c src/main.c src/usb_descriptors.c src/usb_events.c usb/src/app_button_matrix.c usb/src/app_page_selector.c usb/src/usb_device.c usb/src/usb_device_cdc.c usb/src/usb_device_generic.c usb/src/usb_device_hid.c src/device_config.c src/mcc.c src/pin_manager.c + +# Object Files Quoted if spaced +OBJECTFILES_QUOTED_IF_SPACED=${OBJECTDIR}/src/app_device_keyboard.p1 ${OBJECTDIR}/src/main.p1 ${OBJECTDIR}/src/usb_descriptors.p1 ${OBJECTDIR}/src/usb_events.p1 ${OBJECTDIR}/usb/src/app_button_matrix.p1 ${OBJECTDIR}/usb/src/app_page_selector.p1 ${OBJECTDIR}/usb/src/usb_device.p1 ${OBJECTDIR}/usb/src/usb_device_cdc.p1 ${OBJECTDIR}/usb/src/usb_device_generic.p1 ${OBJECTDIR}/usb/src/usb_device_hid.p1 ${OBJECTDIR}/src/device_config.p1 ${OBJECTDIR}/src/mcc.p1 ${OBJECTDIR}/src/pin_manager.p1 +POSSIBLE_DEPFILES=${OBJECTDIR}/src/app_device_keyboard.p1.d ${OBJECTDIR}/src/main.p1.d ${OBJECTDIR}/src/usb_descriptors.p1.d ${OBJECTDIR}/src/usb_events.p1.d ${OBJECTDIR}/usb/src/app_button_matrix.p1.d ${OBJECTDIR}/usb/src/app_page_selector.p1.d ${OBJECTDIR}/usb/src/usb_device.p1.d ${OBJECTDIR}/usb/src/usb_device_cdc.p1.d ${OBJECTDIR}/usb/src/usb_device_generic.p1.d ${OBJECTDIR}/usb/src/usb_device_hid.p1.d ${OBJECTDIR}/src/device_config.p1.d ${OBJECTDIR}/src/mcc.p1.d ${OBJECTDIR}/src/pin_manager.p1.d + +# Object Files +OBJECTFILES=${OBJECTDIR}/src/app_device_keyboard.p1 ${OBJECTDIR}/src/main.p1 ${OBJECTDIR}/src/usb_descriptors.p1 ${OBJECTDIR}/src/usb_events.p1 ${OBJECTDIR}/usb/src/app_button_matrix.p1 ${OBJECTDIR}/usb/src/app_page_selector.p1 ${OBJECTDIR}/usb/src/usb_device.p1 ${OBJECTDIR}/usb/src/usb_device_cdc.p1 ${OBJECTDIR}/usb/src/usb_device_generic.p1 ${OBJECTDIR}/usb/src/usb_device_hid.p1 ${OBJECTDIR}/src/device_config.p1 ${OBJECTDIR}/src/mcc.p1 ${OBJECTDIR}/src/pin_manager.p1 + +# Source Files +SOURCEFILES=src/app_device_keyboard.c src/main.c src/usb_descriptors.c src/usb_events.c usb/src/app_button_matrix.c usb/src/app_page_selector.c usb/src/usb_device.c usb/src/usb_device_cdc.c usb/src/usb_device_generic.c usb/src/usb_device_hid.c src/device_config.c src/mcc.c src/pin_manager.c + + +CFLAGS= +ASFLAGS= +LDLIBSOPTIONS= + +############# Tool locations ########################################## +# If you copy a project from one host to another, the path where the # +# compiler is installed may be different. # +# If you open this project with MPLAB X in the new host, this # +# makefile will be regenerated and the paths will be corrected. # +####################################################################### +# fixDeps replaces a bunch of sed/cat/printf statements that slow down the build +FIXDEPS=fixDeps + +.build-conf: ${BUILD_SUBPROJECTS} +ifneq ($(INFORMATION_MESSAGE), ) + @echo $(INFORMATION_MESSAGE) +endif + ${MAKE} -f nbproject/Makefile-default.mk dist/${CND_CONF}/${IMAGE_TYPE}/palette.X.${IMAGE_TYPE}.${OUTPUT_SUFFIX} + +MP_PROCESSOR_OPTION=18F14K50 +# ------------------------------------------------------------------------------------ +# Rules for buildStep: compile +ifeq ($(TYPE_IMAGE), DEBUG_RUN) +${OBJECTDIR}/src/app_device_keyboard.p1: src/app_device_keyboard.c nbproject/Makefile-${CND_CONF}.mk + @${MKDIR} "${OBJECTDIR}/src" + @${RM} ${OBJECTDIR}/src/app_device_keyboard.p1.d + @${RM} ${OBJECTDIR}/src/app_device_keyboard.p1 + ${MP_CC} $(MP_EXTRA_CC_PRE) -mcpu=$(MP_PROCESSOR_OPTION) -c -D__DEBUG=1 -fno-short-double -fno-short-float -memi=wordwrite -O0 -fasmfile -maddrqual=ignore -xassembler-with-cpp -I"usb/inc" -I"inc" -I"mcc_generated_files" -Wa,-a -DXPRJ_default=$(CND_CONF) -msummary=-psect,-class,+mem,-hex,-file -ginhx032 -Wl,--data-init -mno-keep-startup -mno-download -mdefault-config-bits $(COMPARISON_BUILD) -std=c90 -gdwarf-3 -mstack=compiled:auto:auto:auto -o ${OBJECTDIR}/src/app_device_keyboard.p1 src/app_device_keyboard.c + @${FIXDEPS} ${OBJECTDIR}/src/app_device_keyboard.p1.d $(SILENT) -rsi ${MP_CC_DIR}../ + +${OBJECTDIR}/src/main.p1: src/main.c nbproject/Makefile-${CND_CONF}.mk + @${MKDIR} "${OBJECTDIR}/src" + @${RM} ${OBJECTDIR}/src/main.p1.d + @${RM} ${OBJECTDIR}/src/main.p1 + ${MP_CC} $(MP_EXTRA_CC_PRE) -mcpu=$(MP_PROCESSOR_OPTION) -c -D__DEBUG=1 -fno-short-double -fno-short-float -memi=wordwrite -O0 -fasmfile -maddrqual=ignore -xassembler-with-cpp -I"usb/inc" -I"inc" -I"mcc_generated_files" -Wa,-a -DXPRJ_default=$(CND_CONF) -msummary=-psect,-class,+mem,-hex,-file -ginhx032 -Wl,--data-init -mno-keep-startup -mno-download -mdefault-config-bits $(COMPARISON_BUILD) -std=c90 -gdwarf-3 -mstack=compiled:auto:auto:auto -o ${OBJECTDIR}/src/main.p1 src/main.c + @${FIXDEPS} ${OBJECTDIR}/src/main.p1.d $(SILENT) -rsi ${MP_CC_DIR}../ + +${OBJECTDIR}/src/usb_descriptors.p1: src/usb_descriptors.c nbproject/Makefile-${CND_CONF}.mk + @${MKDIR} "${OBJECTDIR}/src" + @${RM} ${OBJECTDIR}/src/usb_descriptors.p1.d + @${RM} ${OBJECTDIR}/src/usb_descriptors.p1 + ${MP_CC} $(MP_EXTRA_CC_PRE) -mcpu=$(MP_PROCESSOR_OPTION) -c -D__DEBUG=1 -fno-short-double -fno-short-float -memi=wordwrite -O0 -fasmfile -maddrqual=ignore -xassembler-with-cpp -I"usb/inc" -I"inc" -I"mcc_generated_files" -Wa,-a -DXPRJ_default=$(CND_CONF) -msummary=-psect,-class,+mem,-hex,-file -ginhx032 -Wl,--data-init -mno-keep-startup -mno-download -mdefault-config-bits $(COMPARISON_BUILD) -std=c90 -gdwarf-3 -mstack=compiled:auto:auto:auto -o ${OBJECTDIR}/src/usb_descriptors.p1 src/usb_descriptors.c + @${FIXDEPS} ${OBJECTDIR}/src/usb_descriptors.p1.d $(SILENT) -rsi ${MP_CC_DIR}../ + +${OBJECTDIR}/src/usb_events.p1: src/usb_events.c nbproject/Makefile-${CND_CONF}.mk + @${MKDIR} "${OBJECTDIR}/src" + @${RM} ${OBJECTDIR}/src/usb_events.p1.d + @${RM} ${OBJECTDIR}/src/usb_events.p1 + ${MP_CC} $(MP_EXTRA_CC_PRE) -mcpu=$(MP_PROCESSOR_OPTION) -c -D__DEBUG=1 -fno-short-double -fno-short-float -memi=wordwrite -O0 -fasmfile -maddrqual=ignore -xassembler-with-cpp -I"usb/inc" -I"inc" -I"mcc_generated_files" -Wa,-a -DXPRJ_default=$(CND_CONF) -msummary=-psect,-class,+mem,-hex,-file -ginhx032 -Wl,--data-init -mno-keep-startup -mno-download -mdefault-config-bits $(COMPARISON_BUILD) -std=c90 -gdwarf-3 -mstack=compiled:auto:auto:auto -o ${OBJECTDIR}/src/usb_events.p1 src/usb_events.c + @${FIXDEPS} ${OBJECTDIR}/src/usb_events.p1.d $(SILENT) -rsi ${MP_CC_DIR}../ + +${OBJECTDIR}/usb/src/app_button_matrix.p1: usb/src/app_button_matrix.c nbproject/Makefile-${CND_CONF}.mk + @${MKDIR} "${OBJECTDIR}/usb/src" + @${RM} ${OBJECTDIR}/usb/src/app_button_matrix.p1.d + @${RM} ${OBJECTDIR}/usb/src/app_button_matrix.p1 + ${MP_CC} $(MP_EXTRA_CC_PRE) -mcpu=$(MP_PROCESSOR_OPTION) -c -D__DEBUG=1 -fno-short-double -fno-short-float -memi=wordwrite -O0 -fasmfile -maddrqual=ignore -xassembler-with-cpp -I"usb/inc" -I"inc" -I"mcc_generated_files" -Wa,-a -DXPRJ_default=$(CND_CONF) -msummary=-psect,-class,+mem,-hex,-file -ginhx032 -Wl,--data-init -mno-keep-startup -mno-download -mdefault-config-bits $(COMPARISON_BUILD) -std=c90 -gdwarf-3 -mstack=compiled:auto:auto:auto -o ${OBJECTDIR}/usb/src/app_button_matrix.p1 usb/src/app_button_matrix.c + @${FIXDEPS} ${OBJECTDIR}/usb/src/app_button_matrix.p1.d $(SILENT) -rsi ${MP_CC_DIR}../ + +${OBJECTDIR}/usb/src/app_page_selector.p1: usb/src/app_page_selector.c nbproject/Makefile-${CND_CONF}.mk + @${MKDIR} "${OBJECTDIR}/usb/src" + @${RM} ${OBJECTDIR}/usb/src/app_page_selector.p1.d + @${RM} ${OBJECTDIR}/usb/src/app_page_selector.p1 + ${MP_CC} $(MP_EXTRA_CC_PRE) -mcpu=$(MP_PROCESSOR_OPTION) -c -D__DEBUG=1 -fno-short-double -fno-short-float -memi=wordwrite -O0 -fasmfile -maddrqual=ignore -xassembler-with-cpp -I"usb/inc" -I"inc" -I"mcc_generated_files" -Wa,-a -DXPRJ_default=$(CND_CONF) -msummary=-psect,-class,+mem,-hex,-file -ginhx032 -Wl,--data-init -mno-keep-startup -mno-download -mdefault-config-bits $(COMPARISON_BUILD) -std=c90 -gdwarf-3 -mstack=compiled:auto:auto:auto -o ${OBJECTDIR}/usb/src/app_page_selector.p1 usb/src/app_page_selector.c + @${FIXDEPS} ${OBJECTDIR}/usb/src/app_page_selector.p1.d $(SILENT) -rsi ${MP_CC_DIR}../ + +${OBJECTDIR}/usb/src/usb_device.p1: usb/src/usb_device.c nbproject/Makefile-${CND_CONF}.mk + @${MKDIR} "${OBJECTDIR}/usb/src" + @${RM} ${OBJECTDIR}/usb/src/usb_device.p1.d + @${RM} ${OBJECTDIR}/usb/src/usb_device.p1 + ${MP_CC} $(MP_EXTRA_CC_PRE) -mcpu=$(MP_PROCESSOR_OPTION) -c -D__DEBUG=1 -fno-short-double -fno-short-float -memi=wordwrite -O0 -fasmfile -maddrqual=ignore -xassembler-with-cpp -I"usb/inc" -I"inc" -I"mcc_generated_files" -Wa,-a -DXPRJ_default=$(CND_CONF) -msummary=-psect,-class,+mem,-hex,-file -ginhx032 -Wl,--data-init -mno-keep-startup -mno-download -mdefault-config-bits $(COMPARISON_BUILD) -std=c90 -gdwarf-3 -mstack=compiled:auto:auto:auto -o ${OBJECTDIR}/usb/src/usb_device.p1 usb/src/usb_device.c + @${FIXDEPS} ${OBJECTDIR}/usb/src/usb_device.p1.d $(SILENT) -rsi ${MP_CC_DIR}../ + +${OBJECTDIR}/usb/src/usb_device_cdc.p1: usb/src/usb_device_cdc.c nbproject/Makefile-${CND_CONF}.mk + @${MKDIR} "${OBJECTDIR}/usb/src" + @${RM} ${OBJECTDIR}/usb/src/usb_device_cdc.p1.d + @${RM} ${OBJECTDIR}/usb/src/usb_device_cdc.p1 + ${MP_CC} $(MP_EXTRA_CC_PRE) -mcpu=$(MP_PROCESSOR_OPTION) -c -D__DEBUG=1 -fno-short-double -fno-short-float -memi=wordwrite -O0 -fasmfile -maddrqual=ignore -xassembler-with-cpp -I"usb/inc" -I"inc" -I"mcc_generated_files" -Wa,-a -DXPRJ_default=$(CND_CONF) -msummary=-psect,-class,+mem,-hex,-file -ginhx032 -Wl,--data-init -mno-keep-startup -mno-download -mdefault-config-bits $(COMPARISON_BUILD) -std=c90 -gdwarf-3 -mstack=compiled:auto:auto:auto -o ${OBJECTDIR}/usb/src/usb_device_cdc.p1 usb/src/usb_device_cdc.c + @${FIXDEPS} ${OBJECTDIR}/usb/src/usb_device_cdc.p1.d $(SILENT) -rsi ${MP_CC_DIR}../ + +${OBJECTDIR}/usb/src/usb_device_generic.p1: usb/src/usb_device_generic.c nbproject/Makefile-${CND_CONF}.mk + @${MKDIR} "${OBJECTDIR}/usb/src" + @${RM} ${OBJECTDIR}/usb/src/usb_device_generic.p1.d + @${RM} ${OBJECTDIR}/usb/src/usb_device_generic.p1 + ${MP_CC} $(MP_EXTRA_CC_PRE) -mcpu=$(MP_PROCESSOR_OPTION) -c -D__DEBUG=1 -fno-short-double -fno-short-float -memi=wordwrite -O0 -fasmfile -maddrqual=ignore -xassembler-with-cpp -I"usb/inc" -I"inc" -I"mcc_generated_files" -Wa,-a -DXPRJ_default=$(CND_CONF) -msummary=-psect,-class,+mem,-hex,-file -ginhx032 -Wl,--data-init -mno-keep-startup -mno-download -mdefault-config-bits $(COMPARISON_BUILD) -std=c90 -gdwarf-3 -mstack=compiled:auto:auto:auto -o ${OBJECTDIR}/usb/src/usb_device_generic.p1 usb/src/usb_device_generic.c + @${FIXDEPS} ${OBJECTDIR}/usb/src/usb_device_generic.p1.d $(SILENT) -rsi ${MP_CC_DIR}../ + +${OBJECTDIR}/usb/src/usb_device_hid.p1: usb/src/usb_device_hid.c nbproject/Makefile-${CND_CONF}.mk + @${MKDIR} "${OBJECTDIR}/usb/src" + @${RM} ${OBJECTDIR}/usb/src/usb_device_hid.p1.d + @${RM} ${OBJECTDIR}/usb/src/usb_device_hid.p1 + ${MP_CC} $(MP_EXTRA_CC_PRE) -mcpu=$(MP_PROCESSOR_OPTION) -c -D__DEBUG=1 -fno-short-double -fno-short-float -memi=wordwrite -O0 -fasmfile -maddrqual=ignore -xassembler-with-cpp -I"usb/inc" -I"inc" -I"mcc_generated_files" -Wa,-a -DXPRJ_default=$(CND_CONF) -msummary=-psect,-class,+mem,-hex,-file -ginhx032 -Wl,--data-init -mno-keep-startup -mno-download -mdefault-config-bits $(COMPARISON_BUILD) -std=c90 -gdwarf-3 -mstack=compiled:auto:auto:auto -o ${OBJECTDIR}/usb/src/usb_device_hid.p1 usb/src/usb_device_hid.c + @${FIXDEPS} ${OBJECTDIR}/usb/src/usb_device_hid.p1.d $(SILENT) -rsi ${MP_CC_DIR}../ + +${OBJECTDIR}/src/device_config.p1: src/device_config.c nbproject/Makefile-${CND_CONF}.mk + @${MKDIR} "${OBJECTDIR}/src" + @${RM} ${OBJECTDIR}/src/device_config.p1.d + @${RM} ${OBJECTDIR}/src/device_config.p1 + ${MP_CC} $(MP_EXTRA_CC_PRE) -mcpu=$(MP_PROCESSOR_OPTION) -c -D__DEBUG=1 -fno-short-double -fno-short-float -memi=wordwrite -O0 -fasmfile -maddrqual=ignore -xassembler-with-cpp -I"usb/inc" -I"inc" -I"mcc_generated_files" -Wa,-a -DXPRJ_default=$(CND_CONF) -msummary=-psect,-class,+mem,-hex,-file -ginhx032 -Wl,--data-init -mno-keep-startup -mno-download -mdefault-config-bits $(COMPARISON_BUILD) -std=c90 -gdwarf-3 -mstack=compiled:auto:auto:auto -o ${OBJECTDIR}/src/device_config.p1 src/device_config.c + @${FIXDEPS} ${OBJECTDIR}/src/device_config.p1.d $(SILENT) -rsi ${MP_CC_DIR}../ + +${OBJECTDIR}/src/mcc.p1: src/mcc.c nbproject/Makefile-${CND_CONF}.mk + @${MKDIR} "${OBJECTDIR}/src" + @${RM} ${OBJECTDIR}/src/mcc.p1.d + @${RM} ${OBJECTDIR}/src/mcc.p1 + ${MP_CC} $(MP_EXTRA_CC_PRE) -mcpu=$(MP_PROCESSOR_OPTION) -c -D__DEBUG=1 -fno-short-double -fno-short-float -memi=wordwrite -O0 -fasmfile -maddrqual=ignore -xassembler-with-cpp -I"usb/inc" -I"inc" -I"mcc_generated_files" -Wa,-a -DXPRJ_default=$(CND_CONF) -msummary=-psect,-class,+mem,-hex,-file -ginhx032 -Wl,--data-init -mno-keep-startup -mno-download -mdefault-config-bits $(COMPARISON_BUILD) -std=c90 -gdwarf-3 -mstack=compiled:auto:auto:auto -o ${OBJECTDIR}/src/mcc.p1 src/mcc.c + @${FIXDEPS} ${OBJECTDIR}/src/mcc.p1.d $(SILENT) -rsi ${MP_CC_DIR}../ + +${OBJECTDIR}/src/pin_manager.p1: src/pin_manager.c nbproject/Makefile-${CND_CONF}.mk + @${MKDIR} "${OBJECTDIR}/src" + @${RM} ${OBJECTDIR}/src/pin_manager.p1.d + @${RM} ${OBJECTDIR}/src/pin_manager.p1 + ${MP_CC} $(MP_EXTRA_CC_PRE) -mcpu=$(MP_PROCESSOR_OPTION) -c -D__DEBUG=1 -fno-short-double -fno-short-float -memi=wordwrite -O0 -fasmfile -maddrqual=ignore -xassembler-with-cpp -I"usb/inc" -I"inc" -I"mcc_generated_files" -Wa,-a -DXPRJ_default=$(CND_CONF) -msummary=-psect,-class,+mem,-hex,-file -ginhx032 -Wl,--data-init -mno-keep-startup -mno-download -mdefault-config-bits $(COMPARISON_BUILD) -std=c90 -gdwarf-3 -mstack=compiled:auto:auto:auto -o ${OBJECTDIR}/src/pin_manager.p1 src/pin_manager.c + @${FIXDEPS} ${OBJECTDIR}/src/pin_manager.p1.d $(SILENT) -rsi ${MP_CC_DIR}../ + +else +${OBJECTDIR}/src/app_device_keyboard.p1: src/app_device_keyboard.c nbproject/Makefile-${CND_CONF}.mk + @${MKDIR} "${OBJECTDIR}/src" + @${RM} ${OBJECTDIR}/src/app_device_keyboard.p1.d + @${RM} ${OBJECTDIR}/src/app_device_keyboard.p1 + ${MP_CC} $(MP_EXTRA_CC_PRE) -mcpu=$(MP_PROCESSOR_OPTION) -c -fno-short-double -fno-short-float -memi=wordwrite -O0 -fasmfile -maddrqual=ignore -xassembler-with-cpp -I"usb/inc" -I"inc" -I"mcc_generated_files" -Wa,-a -DXPRJ_default=$(CND_CONF) -msummary=-psect,-class,+mem,-hex,-file -ginhx032 -Wl,--data-init -mno-keep-startup -mno-download -mdefault-config-bits $(COMPARISON_BUILD) -std=c90 -gdwarf-3 -mstack=compiled:auto:auto:auto -o ${OBJECTDIR}/src/app_device_keyboard.p1 src/app_device_keyboard.c + @${FIXDEPS} ${OBJECTDIR}/src/app_device_keyboard.p1.d $(SILENT) -rsi ${MP_CC_DIR}../ + +${OBJECTDIR}/src/main.p1: src/main.c nbproject/Makefile-${CND_CONF}.mk + @${MKDIR} "${OBJECTDIR}/src" + @${RM} ${OBJECTDIR}/src/main.p1.d + @${RM} ${OBJECTDIR}/src/main.p1 + ${MP_CC} $(MP_EXTRA_CC_PRE) -mcpu=$(MP_PROCESSOR_OPTION) -c -fno-short-double -fno-short-float -memi=wordwrite -O0 -fasmfile -maddrqual=ignore -xassembler-with-cpp -I"usb/inc" -I"inc" -I"mcc_generated_files" -Wa,-a -DXPRJ_default=$(CND_CONF) -msummary=-psect,-class,+mem,-hex,-file -ginhx032 -Wl,--data-init -mno-keep-startup -mno-download -mdefault-config-bits $(COMPARISON_BUILD) -std=c90 -gdwarf-3 -mstack=compiled:auto:auto:auto -o ${OBJECTDIR}/src/main.p1 src/main.c + @${FIXDEPS} ${OBJECTDIR}/src/main.p1.d $(SILENT) -rsi ${MP_CC_DIR}../ + +${OBJECTDIR}/src/usb_descriptors.p1: src/usb_descriptors.c nbproject/Makefile-${CND_CONF}.mk + @${MKDIR} "${OBJECTDIR}/src" + @${RM} ${OBJECTDIR}/src/usb_descriptors.p1.d + @${RM} ${OBJECTDIR}/src/usb_descriptors.p1 + ${MP_CC} $(MP_EXTRA_CC_PRE) -mcpu=$(MP_PROCESSOR_OPTION) -c -fno-short-double -fno-short-float -memi=wordwrite -O0 -fasmfile -maddrqual=ignore -xassembler-with-cpp -I"usb/inc" -I"inc" -I"mcc_generated_files" -Wa,-a -DXPRJ_default=$(CND_CONF) -msummary=-psect,-class,+mem,-hex,-file -ginhx032 -Wl,--data-init -mno-keep-startup -mno-download -mdefault-config-bits $(COMPARISON_BUILD) -std=c90 -gdwarf-3 -mstack=compiled:auto:auto:auto -o ${OBJECTDIR}/src/usb_descriptors.p1 src/usb_descriptors.c + @${FIXDEPS} ${OBJECTDIR}/src/usb_descriptors.p1.d $(SILENT) -rsi ${MP_CC_DIR}../ + +${OBJECTDIR}/src/usb_events.p1: src/usb_events.c nbproject/Makefile-${CND_CONF}.mk + @${MKDIR} "${OBJECTDIR}/src" + @${RM} ${OBJECTDIR}/src/usb_events.p1.d + @${RM} ${OBJECTDIR}/src/usb_events.p1 + ${MP_CC} $(MP_EXTRA_CC_PRE) -mcpu=$(MP_PROCESSOR_OPTION) -c -fno-short-double -fno-short-float -memi=wordwrite -O0 -fasmfile -maddrqual=ignore -xassembler-with-cpp -I"usb/inc" -I"inc" -I"mcc_generated_files" -Wa,-a -DXPRJ_default=$(CND_CONF) -msummary=-psect,-class,+mem,-hex,-file -ginhx032 -Wl,--data-init -mno-keep-startup -mno-download -mdefault-config-bits $(COMPARISON_BUILD) -std=c90 -gdwarf-3 -mstack=compiled:auto:auto:auto -o ${OBJECTDIR}/src/usb_events.p1 src/usb_events.c + @${FIXDEPS} ${OBJECTDIR}/src/usb_events.p1.d $(SILENT) -rsi ${MP_CC_DIR}../ + +${OBJECTDIR}/usb/src/app_button_matrix.p1: usb/src/app_button_matrix.c nbproject/Makefile-${CND_CONF}.mk + @${MKDIR} "${OBJECTDIR}/usb/src" + @${RM} ${OBJECTDIR}/usb/src/app_button_matrix.p1.d + @${RM} ${OBJECTDIR}/usb/src/app_button_matrix.p1 + ${MP_CC} $(MP_EXTRA_CC_PRE) -mcpu=$(MP_PROCESSOR_OPTION) -c -fno-short-double -fno-short-float -memi=wordwrite -O0 -fasmfile -maddrqual=ignore -xassembler-with-cpp -I"usb/inc" -I"inc" -I"mcc_generated_files" -Wa,-a -DXPRJ_default=$(CND_CONF) -msummary=-psect,-class,+mem,-hex,-file -ginhx032 -Wl,--data-init -mno-keep-startup -mno-download -mdefault-config-bits $(COMPARISON_BUILD) -std=c90 -gdwarf-3 -mstack=compiled:auto:auto:auto -o ${OBJECTDIR}/usb/src/app_button_matrix.p1 usb/src/app_button_matrix.c + @${FIXDEPS} ${OBJECTDIR}/usb/src/app_button_matrix.p1.d $(SILENT) -rsi ${MP_CC_DIR}../ + +${OBJECTDIR}/usb/src/app_page_selector.p1: usb/src/app_page_selector.c nbproject/Makefile-${CND_CONF}.mk + @${MKDIR} "${OBJECTDIR}/usb/src" + @${RM} ${OBJECTDIR}/usb/src/app_page_selector.p1.d + @${RM} ${OBJECTDIR}/usb/src/app_page_selector.p1 + ${MP_CC} $(MP_EXTRA_CC_PRE) -mcpu=$(MP_PROCESSOR_OPTION) -c -fno-short-double -fno-short-float -memi=wordwrite -O0 -fasmfile -maddrqual=ignore -xassembler-with-cpp -I"usb/inc" -I"inc" -I"mcc_generated_files" -Wa,-a -DXPRJ_default=$(CND_CONF) -msummary=-psect,-class,+mem,-hex,-file -ginhx032 -Wl,--data-init -mno-keep-startup -mno-download -mdefault-config-bits $(COMPARISON_BUILD) -std=c90 -gdwarf-3 -mstack=compiled:auto:auto:auto -o ${OBJECTDIR}/usb/src/app_page_selector.p1 usb/src/app_page_selector.c + @${FIXDEPS} ${OBJECTDIR}/usb/src/app_page_selector.p1.d $(SILENT) -rsi ${MP_CC_DIR}../ + +${OBJECTDIR}/usb/src/usb_device.p1: usb/src/usb_device.c nbproject/Makefile-${CND_CONF}.mk + @${MKDIR} "${OBJECTDIR}/usb/src" + @${RM} ${OBJECTDIR}/usb/src/usb_device.p1.d + @${RM} ${OBJECTDIR}/usb/src/usb_device.p1 + ${MP_CC} $(MP_EXTRA_CC_PRE) -mcpu=$(MP_PROCESSOR_OPTION) -c -fno-short-double -fno-short-float -memi=wordwrite -O0 -fasmfile -maddrqual=ignore -xassembler-with-cpp -I"usb/inc" -I"inc" -I"mcc_generated_files" -Wa,-a -DXPRJ_default=$(CND_CONF) -msummary=-psect,-class,+mem,-hex,-file -ginhx032 -Wl,--data-init -mno-keep-startup -mno-download -mdefault-config-bits $(COMPARISON_BUILD) -std=c90 -gdwarf-3 -mstack=compiled:auto:auto:auto -o ${OBJECTDIR}/usb/src/usb_device.p1 usb/src/usb_device.c + @${FIXDEPS} ${OBJECTDIR}/usb/src/usb_device.p1.d $(SILENT) -rsi ${MP_CC_DIR}../ + +${OBJECTDIR}/usb/src/usb_device_cdc.p1: usb/src/usb_device_cdc.c nbproject/Makefile-${CND_CONF}.mk + @${MKDIR} "${OBJECTDIR}/usb/src" + @${RM} ${OBJECTDIR}/usb/src/usb_device_cdc.p1.d + @${RM} ${OBJECTDIR}/usb/src/usb_device_cdc.p1 + ${MP_CC} $(MP_EXTRA_CC_PRE) -mcpu=$(MP_PROCESSOR_OPTION) -c -fno-short-double -fno-short-float -memi=wordwrite -O0 -fasmfile -maddrqual=ignore -xassembler-with-cpp -I"usb/inc" -I"inc" -I"mcc_generated_files" -Wa,-a -DXPRJ_default=$(CND_CONF) -msummary=-psect,-class,+mem,-hex,-file -ginhx032 -Wl,--data-init -mno-keep-startup -mno-download -mdefault-config-bits $(COMPARISON_BUILD) -std=c90 -gdwarf-3 -mstack=compiled:auto:auto:auto -o ${OBJECTDIR}/usb/src/usb_device_cdc.p1 usb/src/usb_device_cdc.c + @${FIXDEPS} ${OBJECTDIR}/usb/src/usb_device_cdc.p1.d $(SILENT) -rsi ${MP_CC_DIR}../ + +${OBJECTDIR}/usb/src/usb_device_generic.p1: usb/src/usb_device_generic.c nbproject/Makefile-${CND_CONF}.mk + @${MKDIR} "${OBJECTDIR}/usb/src" + @${RM} ${OBJECTDIR}/usb/src/usb_device_generic.p1.d + @${RM} ${OBJECTDIR}/usb/src/usb_device_generic.p1 + ${MP_CC} $(MP_EXTRA_CC_PRE) -mcpu=$(MP_PROCESSOR_OPTION) -c -fno-short-double -fno-short-float -memi=wordwrite -O0 -fasmfile -maddrqual=ignore -xassembler-with-cpp -I"usb/inc" -I"inc" -I"mcc_generated_files" -Wa,-a -DXPRJ_default=$(CND_CONF) -msummary=-psect,-class,+mem,-hex,-file -ginhx032 -Wl,--data-init -mno-keep-startup -mno-download -mdefault-config-bits $(COMPARISON_BUILD) -std=c90 -gdwarf-3 -mstack=compiled:auto:auto:auto -o ${OBJECTDIR}/usb/src/usb_device_generic.p1 usb/src/usb_device_generic.c + @${FIXDEPS} ${OBJECTDIR}/usb/src/usb_device_generic.p1.d $(SILENT) -rsi ${MP_CC_DIR}../ + +${OBJECTDIR}/usb/src/usb_device_hid.p1: usb/src/usb_device_hid.c nbproject/Makefile-${CND_CONF}.mk + @${MKDIR} "${OBJECTDIR}/usb/src" + @${RM} ${OBJECTDIR}/usb/src/usb_device_hid.p1.d + @${RM} ${OBJECTDIR}/usb/src/usb_device_hid.p1 + ${MP_CC} $(MP_EXTRA_CC_PRE) -mcpu=$(MP_PROCESSOR_OPTION) -c -fno-short-double -fno-short-float -memi=wordwrite -O0 -fasmfile -maddrqual=ignore -xassembler-with-cpp -I"usb/inc" -I"inc" -I"mcc_generated_files" -Wa,-a -DXPRJ_default=$(CND_CONF) -msummary=-psect,-class,+mem,-hex,-file -ginhx032 -Wl,--data-init -mno-keep-startup -mno-download -mdefault-config-bits $(COMPARISON_BUILD) -std=c90 -gdwarf-3 -mstack=compiled:auto:auto:auto -o ${OBJECTDIR}/usb/src/usb_device_hid.p1 usb/src/usb_device_hid.c + @${FIXDEPS} ${OBJECTDIR}/usb/src/usb_device_hid.p1.d $(SILENT) -rsi ${MP_CC_DIR}../ + +${OBJECTDIR}/src/device_config.p1: src/device_config.c nbproject/Makefile-${CND_CONF}.mk + @${MKDIR} "${OBJECTDIR}/src" + @${RM} ${OBJECTDIR}/src/device_config.p1.d + @${RM} ${OBJECTDIR}/src/device_config.p1 + ${MP_CC} $(MP_EXTRA_CC_PRE) -mcpu=$(MP_PROCESSOR_OPTION) -c -fno-short-double -fno-short-float -memi=wordwrite -O0 -fasmfile -maddrqual=ignore -xassembler-with-cpp -I"usb/inc" -I"inc" -I"mcc_generated_files" -Wa,-a -DXPRJ_default=$(CND_CONF) -msummary=-psect,-class,+mem,-hex,-file -ginhx032 -Wl,--data-init -mno-keep-startup -mno-download -mdefault-config-bits $(COMPARISON_BUILD) -std=c90 -gdwarf-3 -mstack=compiled:auto:auto:auto -o ${OBJECTDIR}/src/device_config.p1 src/device_config.c + @${FIXDEPS} ${OBJECTDIR}/src/device_config.p1.d $(SILENT) -rsi ${MP_CC_DIR}../ + +${OBJECTDIR}/src/mcc.p1: src/mcc.c nbproject/Makefile-${CND_CONF}.mk + @${MKDIR} "${OBJECTDIR}/src" + @${RM} ${OBJECTDIR}/src/mcc.p1.d + @${RM} ${OBJECTDIR}/src/mcc.p1 + ${MP_CC} $(MP_EXTRA_CC_PRE) -mcpu=$(MP_PROCESSOR_OPTION) -c -fno-short-double -fno-short-float -memi=wordwrite -O0 -fasmfile -maddrqual=ignore -xassembler-with-cpp -I"usb/inc" -I"inc" -I"mcc_generated_files" -Wa,-a -DXPRJ_default=$(CND_CONF) -msummary=-psect,-class,+mem,-hex,-file -ginhx032 -Wl,--data-init -mno-keep-startup -mno-download -mdefault-config-bits $(COMPARISON_BUILD) -std=c90 -gdwarf-3 -mstack=compiled:auto:auto:auto -o ${OBJECTDIR}/src/mcc.p1 src/mcc.c + @${FIXDEPS} ${OBJECTDIR}/src/mcc.p1.d $(SILENT) -rsi ${MP_CC_DIR}../ + +${OBJECTDIR}/src/pin_manager.p1: src/pin_manager.c nbproject/Makefile-${CND_CONF}.mk + @${MKDIR} "${OBJECTDIR}/src" + @${RM} ${OBJECTDIR}/src/pin_manager.p1.d + @${RM} ${OBJECTDIR}/src/pin_manager.p1 + ${MP_CC} $(MP_EXTRA_CC_PRE) -mcpu=$(MP_PROCESSOR_OPTION) -c -fno-short-double -fno-short-float -memi=wordwrite -O0 -fasmfile -maddrqual=ignore -xassembler-with-cpp -I"usb/inc" -I"inc" -I"mcc_generated_files" -Wa,-a -DXPRJ_default=$(CND_CONF) -msummary=-psect,-class,+mem,-hex,-file -ginhx032 -Wl,--data-init -mno-keep-startup -mno-download -mdefault-config-bits $(COMPARISON_BUILD) -std=c90 -gdwarf-3 -mstack=compiled:auto:auto:auto -o ${OBJECTDIR}/src/pin_manager.p1 src/pin_manager.c + @${FIXDEPS} ${OBJECTDIR}/src/pin_manager.p1.d $(SILENT) -rsi ${MP_CC_DIR}../ + +endif + +# ------------------------------------------------------------------------------------ +# Rules for buildStep: assemble +ifeq ($(TYPE_IMAGE), DEBUG_RUN) +else +endif + +# ------------------------------------------------------------------------------------ +# Rules for buildStep: assembleWithPreprocess +ifeq ($(TYPE_IMAGE), DEBUG_RUN) +else +endif + +# ------------------------------------------------------------------------------------ +# Rules for buildStep: link +ifeq ($(TYPE_IMAGE), DEBUG_RUN) +dist/${CND_CONF}/${IMAGE_TYPE}/palette.X.${IMAGE_TYPE}.${OUTPUT_SUFFIX}: ${OBJECTFILES} nbproject/Makefile-${CND_CONF}.mk + @${MKDIR} dist/${CND_CONF}/${IMAGE_TYPE} + ${MP_CC} $(MP_EXTRA_LD_PRE) -mcpu=$(MP_PROCESSOR_OPTION) -Wl,-Map=dist/${CND_CONF}/${IMAGE_TYPE}/palette.X.${IMAGE_TYPE}.map -D__DEBUG=1 -DXPRJ_default=$(CND_CONF) -Wl,--defsym=__MPLAB_BUILD=1 -fno-short-double -fno-short-float -memi=wordwrite -O0 -fasmfile -maddrqual=ignore -xassembler-with-cpp -I"usb/inc" -I"inc" -I"mcc_generated_files" -Wa,-a -msummary=-psect,-class,+mem,-hex,-file -ginhx032 -Wl,--data-init -mno-keep-startup -mno-download -mdefault-config-bits -std=c90 -gdwarf-3 -mstack=compiled:auto:auto:auto --rom=default,-3e00-3fff $(COMPARISON_BUILD) -Wl,--memorysummary,dist/${CND_CONF}/${IMAGE_TYPE}/memoryfile.xml -o dist/${CND_CONF}/${IMAGE_TYPE}/palette.X.${IMAGE_TYPE}.${DEBUGGABLE_SUFFIX} ${OBJECTFILES_QUOTED_IF_SPACED} + @${RM} dist/${CND_CONF}/${IMAGE_TYPE}/palette.X.${IMAGE_TYPE}.hex + +else +dist/${CND_CONF}/${IMAGE_TYPE}/palette.X.${IMAGE_TYPE}.${OUTPUT_SUFFIX}: ${OBJECTFILES} nbproject/Makefile-${CND_CONF}.mk + @${MKDIR} dist/${CND_CONF}/${IMAGE_TYPE} + ${MP_CC} $(MP_EXTRA_LD_PRE) -mcpu=$(MP_PROCESSOR_OPTION) -Wl,-Map=dist/${CND_CONF}/${IMAGE_TYPE}/palette.X.${IMAGE_TYPE}.map -DXPRJ_default=$(CND_CONF) -Wl,--defsym=__MPLAB_BUILD=1 -fno-short-double -fno-short-float -memi=wordwrite -O0 -fasmfile -maddrqual=ignore -xassembler-with-cpp -I"usb/inc" -I"inc" -I"mcc_generated_files" -Wa,-a -msummary=-psect,-class,+mem,-hex,-file -ginhx032 -Wl,--data-init -mno-keep-startup -mno-download -mdefault-config-bits -std=c90 -gdwarf-3 -mstack=compiled:auto:auto:auto $(COMPARISON_BUILD) -Wl,--memorysummary,dist/${CND_CONF}/${IMAGE_TYPE}/memoryfile.xml -o dist/${CND_CONF}/${IMAGE_TYPE}/palette.X.${IMAGE_TYPE}.${DEBUGGABLE_SUFFIX} ${OBJECTFILES_QUOTED_IF_SPACED} + +endif + + +# Subprojects +.build-subprojects: + + +# Subprojects +.clean-subprojects: + +# Clean Targets +.clean-conf: ${CLEAN_SUBPROJECTS} + ${RM} -r build/default + ${RM} -r dist/default + +# Enable dependency checking +.dep.inc: .depcheck-impl + +DEPFILES=$(shell mplabwildcard ${POSSIBLE_DEPFILES}) +ifneq (${DEPFILES},) +include ${DEPFILES} +endif diff --git a/nbproject/Makefile-genesis.properties b/nbproject/Makefile-genesis.properties new file mode 100644 index 0000000..f006f5f --- /dev/null +++ b/nbproject/Makefile-genesis.properties @@ -0,0 +1,9 @@ +# +#Wed Aug 15 10:14:59 MSK 2018 +default.languagetoolchain.dir=C\:\\Program Files (x86)\\Microchip\\xc8\\v2.00\\bin +configurations-xml=30b686f7f4464e77d8bcdf38fbebc77c +com-microchip-mplab-nbide-embedded-makeproject-MakeProject.md5=9d53b989b6ed2b6446aae58c2779ca87 +default.languagetoolchain.version=2.00 +host.platform=windows +conf.ids=default +default.com-microchip-mplab-nbide-toolchainXC8-XC8LanguageToolchain.md5=d0b8fdc2be6cb87257c6731763a65529 diff --git a/nbproject/Makefile-impl.mk b/nbproject/Makefile-impl.mk new file mode 100644 index 0000000..e28a734 --- /dev/null +++ b/nbproject/Makefile-impl.mk @@ -0,0 +1,69 @@ +# +# Generated Makefile - do not edit! +# +# Edit the Makefile in the project folder instead (../Makefile). Each target +# has a pre- and a post- target defined where you can add customization code. +# +# This makefile implements macros and targets common to all configurations. +# +# NOCDDL + + +# Building and Cleaning subprojects are done by default, but can be controlled with the SUB +# macro. If SUB=no, subprojects will not be built or cleaned. The following macro +# statements set BUILD_SUB-CONF and CLEAN_SUB-CONF to .build-reqprojects-conf +# and .clean-reqprojects-conf unless SUB has the value 'no' +SUB_no=NO +SUBPROJECTS=${SUB_${SUB}} +BUILD_SUBPROJECTS_=.build-subprojects +BUILD_SUBPROJECTS_NO= +BUILD_SUBPROJECTS=${BUILD_SUBPROJECTS_${SUBPROJECTS}} +CLEAN_SUBPROJECTS_=.clean-subprojects +CLEAN_SUBPROJECTS_NO= +CLEAN_SUBPROJECTS=${CLEAN_SUBPROJECTS_${SUBPROJECTS}} + + +# Project Name +PROJECTNAME=palette.X + +# Active Configuration +DEFAULTCONF=default +CONF=${DEFAULTCONF} + +# All Configurations +ALLCONFS=default + + +# build +.build-impl: .build-pre + ${MAKE} -f nbproject/Makefile-${CONF}.mk SUBPROJECTS=${SUBPROJECTS} .build-conf + + +# clean +.clean-impl: .clean-pre + ${MAKE} -f nbproject/Makefile-${CONF}.mk SUBPROJECTS=${SUBPROJECTS} .clean-conf + +# clobber +.clobber-impl: .clobber-pre .depcheck-impl + ${MAKE} SUBPROJECTS=${SUBPROJECTS} CONF=default clean + + + +# all +.all-impl: .all-pre .depcheck-impl + ${MAKE} SUBPROJECTS=${SUBPROJECTS} CONF=default build + + + +# dependency checking support +.depcheck-impl: +# @echo "# This code depends on make tool being used" >.dep.inc +# @if [ -n "${MAKE_VERSION}" ]; then \ +# echo "DEPFILES=\$$(wildcard \$$(addsuffix .d, \$${OBJECTFILES}))" >>.dep.inc; \ +# echo "ifneq (\$${DEPFILES},)" >>.dep.inc; \ +# echo "include \$${DEPFILES}" >>.dep.inc; \ +# echo "endif" >>.dep.inc; \ +# else \ +# echo ".KEEP_STATE:" >>.dep.inc; \ +# echo ".KEEP_STATE_FILE:.make.state.\$${CONF}" >>.dep.inc; \ +# fi diff --git a/nbproject/Makefile-local-default.mk b/nbproject/Makefile-local-default.mk new file mode 100644 index 0000000..57649d4 --- /dev/null +++ b/nbproject/Makefile-local-default.mk @@ -0,0 +1,37 @@ +# +# Generated Makefile - do not edit! +# +# +# This file contains information about the location of compilers and other tools. +# If you commmit this file into your revision control server, you will be able to +# to checkout the project and build it from the command line with make. However, +# if more than one person works on the same project, then this file might show +# conflicts since different users are bound to have compilers in different places. +# In that case you might choose to not commit this file and let MPLAB X recreate this file +# for each user. The disadvantage of not commiting this file is that you must run MPLAB X at +# least once so the file gets created and the project can be built. Finally, you can also +# avoid using this file at all if you are only building from the command line with make. +# You can invoke make with the values of the macros: +# $ makeMP_CC="/opt/microchip/mplabc30/v3.30c/bin/pic30-gcc" ... +# +SHELL=cmd.exe +PATH_TO_IDE_BIN=C:/Program Files (x86)/Microchip/MPLABX/v5.00/mplab_platform/platform/../mplab_ide/modules/../../bin/ +# Adding MPLAB X bin directory to path. +PATH:=C:/Program Files (x86)/Microchip/MPLABX/v5.00/mplab_platform/platform/../mplab_ide/modules/../../bin/:$(PATH) +# Path to java used to run MPLAB X when this makefile was created +MP_JAVA_PATH="C:\Program Files (x86)\Microchip\MPLABX\v5.00\sys\java\jre1.8.0_144/bin/" +OS_CURRENT="$(shell uname -s)" +MP_CC="C:\Program Files (x86)\Microchip\xc8\v2.00\bin\xc8-cc.exe" +# MP_CPPC is not defined +# MP_BC is not defined +MP_AS="C:\Program Files (x86)\Microchip\xc8\v2.00\bin\xc8-cc.exe" +MP_LD="C:\Program Files (x86)\Microchip\xc8\v2.00\bin\xc8-cc.exe" +MP_AR="C:\Program Files (x86)\Microchip\xc8\v2.00\bin\xc8-ar.exe" +DEP_GEN=${MP_JAVA_PATH}java -jar "C:/Program Files (x86)/Microchip/MPLABX/v5.00/mplab_platform/platform/../mplab_ide/modules/../../bin/extractobjectdependencies.jar" +MP_CC_DIR="C:\Program Files (x86)\Microchip\xc8\v2.00\bin" +# MP_CPPC_DIR is not defined +# MP_BC_DIR is not defined +MP_AS_DIR="C:\Program Files (x86)\Microchip\xc8\v2.00\bin" +MP_LD_DIR="C:\Program Files (x86)\Microchip\xc8\v2.00\bin" +MP_AR_DIR="C:\Program Files (x86)\Microchip\xc8\v2.00\bin" +# MP_BC_DIR is not defined diff --git a/nbproject/Makefile-variables.mk b/nbproject/Makefile-variables.mk new file mode 100644 index 0000000..d72956b --- /dev/null +++ b/nbproject/Makefile-variables.mk @@ -0,0 +1,13 @@ +# +# Generated - do not edit! +# +# NOCDDL +# +CND_BASEDIR=`pwd` +# default configuration +CND_ARTIFACT_DIR_default=dist/default/production +CND_ARTIFACT_NAME_default=palette.X.production.hex +CND_ARTIFACT_PATH_default=dist/default/production/palette.X.production.hex +CND_PACKAGE_DIR_default=${CND_DISTDIR}/default/package +CND_PACKAGE_NAME_default=palette.x.tar +CND_PACKAGE_PATH_default=${CND_DISTDIR}/default/package/palette.x.tar diff --git a/nbproject/Package-default.bash b/nbproject/Package-default.bash new file mode 100644 index 0000000..0f55a14 --- /dev/null +++ b/nbproject/Package-default.bash @@ -0,0 +1,73 @@ +#!/bin/bash -x + +# +# Generated - do not edit! +# + +# Macros +TOP=`pwd` +CND_CONF=default +CND_DISTDIR=dist +TMPDIR=build/${CND_CONF}/${IMAGE_TYPE}/tmp-packaging +TMPDIRNAME=tmp-packaging +OUTPUT_PATH=dist/${CND_CONF}/${IMAGE_TYPE}/palette.X.${IMAGE_TYPE}.${OUTPUT_SUFFIX} +OUTPUT_BASENAME=palette.X.${IMAGE_TYPE}.${OUTPUT_SUFFIX} +PACKAGE_TOP_DIR=palette.x/ + +# Functions +function checkReturnCode +{ + rc=$? + if [ $rc != 0 ] + then + exit $rc + fi +} +function makeDirectory +# $1 directory path +# $2 permission (optional) +{ + mkdir -p "$1" + checkReturnCode + if [ "$2" != "" ] + then + chmod $2 "$1" + checkReturnCode + fi +} +function copyFileToTmpDir +# $1 from-file path +# $2 to-file path +# $3 permission +{ + cp "$1" "$2" + checkReturnCode + if [ "$3" != "" ] + then + chmod $3 "$2" + checkReturnCode + fi +} + +# Setup +cd "${TOP}" +mkdir -p ${CND_DISTDIR}/${CND_CONF}/package +rm -rf ${TMPDIR} +mkdir -p ${TMPDIR} + +# Copy files and create directories and links +cd "${TOP}" +makeDirectory ${TMPDIR}/palette.x/bin +copyFileToTmpDir "${OUTPUT_PATH}" "${TMPDIR}/${PACKAGE_TOP_DIR}bin/${OUTPUT_BASENAME}" 0755 + + +# Generate tar file +cd "${TOP}" +rm -f ${CND_DISTDIR}/${CND_CONF}/package/palette.x.tar +cd ${TMPDIR} +tar -vcf ../../../../${CND_DISTDIR}/${CND_CONF}/package/palette.x.tar * +checkReturnCode + +# Cleanup +cd "${TOP}" +rm -rf ${TMPDIR} diff --git a/nbproject/configurations.xml b/nbproject/configurations.xml new file mode 100644 index 0000000..534dc3e --- /dev/null +++ b/nbproject/configurations.xml @@ -0,0 +1,236 @@ + + + + + + inc/app_button_matrix.h + inc/app_device_keyboard.h + inc/app_page_selector.h + inc/fixed_address_memory.h + inc/io_mapping.h + inc/mcc.h + inc/pin_manager.h + inc/system_config.h + inc/usb_config.h + + + usb/inc/usb.h + usb/inc/usb_ch9.h + usb/inc/usb_common.h + usb/inc/usb_device.h + usb/inc/usb_device_cdc.h + usb/inc/usb_device_generic.h + usb/inc/usb_device_hid.h + usb/inc/usb_device_local.h + usb/inc/usb_device_midi.h + usb/inc/usb_hal.h + usb/inc/usb_hal_local.h + usb/inc/usb_hal_pic18.h + usb/inc/usb_hid.h + usb/inc/usb_pic18_local.h + usb/inc/usb_struct_queue.h + + + + + + + src/app_device_keyboard.c + src/main.c + src/usb_descriptors.c + src/usb_events.c + usb/src/app_button_matrix.c + usb/src/app_page_selector.c + src/device_config.c + src/mcc.c + src/pin_manager.c + + + usb/src/usb_device.c + usb/src/usb_device_cdc.c + usb/src/usb_device_generic.c + usb/src/usb_device_hid.c + + + + Makefile + + + Makefile + + + + localhost + PIC18F14K50 + + + PICkit3PlatformTool + XC8 + 2.00 + 3 + + + + + + + + + + + + + false + false + + + + + + + false + + false + + false + false + false + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/nbproject/project.xml b/nbproject/project.xml new file mode 100644 index 0000000..a885ca7 --- /dev/null +++ b/nbproject/project.xml @@ -0,0 +1,17 @@ + + + com.microchip.mplab.nbide.embedded.makeproject + + + palette + 5e5f87e9-f999-44c1-a33d-5f6d342cf452 + 0 + c + + h + + UTF-8 + + + + diff --git a/src/app_device_keyboard.c b/src/app_device_keyboard.c new file mode 100644 index 0000000..de24621 --- /dev/null +++ b/src/app_device_keyboard.c @@ -0,0 +1,506 @@ +/******************************************************************************* +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 +*******************************************************************************/ + +// ***************************************************************************** +// ***************************************************************************** +// Section: Included Files +// ***************************************************************************** +// ***************************************************************************** +#include +#include + +#include "usb.h" +#include "usb_device_hid.h" + +#include "app_button_matrix.h" +#include "app_page_selector.h" + +// ***************************************************************************** +// ***************************************************************************** +// Section: File Scope or Global Constants +// ***************************************************************************** +// ***************************************************************************** + +//Class specific descriptor - HID Keyboard +const struct{uint8_t report[HID_RPT01_SIZE];}hid_rpt01={ +{ 0x05, 0x01, // USAGE_PAGE (Generic Desktop) + 0x09, 0x06, // USAGE (Keyboard) + 0xa1, 0x01, // COLLECTION (Application) + 0x05, 0x07, // USAGE_PAGE (Keyboard) + 0x19, 0xe0, // USAGE_MINIMUM (Keyboard LeftControl) + 0x29, 0xe7, // USAGE_MAXIMUM (Keyboard Right GUI) + 0x15, 0x00, // LOGICAL_MINIMUM (0) + 0x25, 0x01, // LOGICAL_MAXIMUM (1) + 0x75, 0x01, // REPORT_SIZE (1) + 0x95, 0x08, // REPORT_COUNT (8) + 0x81, 0x02, // INPUT (Data,Var,Abs) + 0x95, 0x01, // REPORT_COUNT (1) + 0x75, 0x08, // REPORT_SIZE (8) + 0x81, 0x03, // INPUT (Cnst,Var,Abs) + 0x95, 0x05, // REPORT_COUNT (5) + 0x75, 0x01, // REPORT_SIZE (1) + 0x05, 0x08, // USAGE_PAGE (LEDs) + 0x19, 0x01, // USAGE_MINIMUM (Num Lock) + 0x29, 0x05, // USAGE_MAXIMUM (Kana) + 0x91, 0x02, // OUTPUT (Data,Var,Abs) + 0x95, 0x01, // REPORT_COUNT (1) + 0x75, 0x03, // REPORT_SIZE (3) + 0x91, 0x03, // OUTPUT (Cnst,Var,Abs) + 0x95, 0x06, // REPORT_COUNT (6) + 0x75, 0x08, // REPORT_SIZE (8) + 0x15, 0x00, // LOGICAL_MINIMUM (0) + 0x25, 0x65, // LOGICAL_MAXIMUM (101) + 0x05, 0x07, // USAGE_PAGE (Keyboard) + 0x19, 0x00, // USAGE_MINIMUM (Reserved (no event indicated)) + 0x29, 0x65, // USAGE_MAXIMUM (Keyboard Application) + 0x81, 0x00, // INPUT (Data,Ary,Abs) + 0xc0} // End Collection +}; + + +// ***************************************************************************** +// ***************************************************************************** +// Section: File Scope Data Types +// ***************************************************************************** +// ***************************************************************************** + +/* This typedef defines the only INPUT report found in the HID report + * descriptor and gives an easy way to create the OUTPUT report. */ +typedef struct __attribute__((packed)) +{ + /* The union below represents the first byte of the INPUT report. It is + * formed by the following HID report items: + * + * 0x19, 0xe0, // USAGE_MINIMUM (Keyboard LeftControl) + * 0x29, 0xe7, // USAGE_MAXIMUM (Keyboard Right GUI) + * 0x15, 0x00, // LOGICAL_MINIMUM (0) + * 0x25, 0x01, // LOGICAL_MAXIMUM (1) + * 0x75, 0x01, // REPORT_SIZE (1) + * 0x95, 0x08, // REPORT_COUNT (8) + * 0x81, 0x02, // INPUT (Data,Var,Abs) + * + * The report size is 1 specifying 1 bit per entry. + * The report count is 8 specifying there are 8 entries. + * These entries represent the Usage items between Left Control (the usage + * minimum) and Right GUI (the usage maximum). + */ + union __attribute__((packed)) + { + uint8_t value; + struct __attribute__((packed)) + { + unsigned leftControl :1; + unsigned leftShift :1; + unsigned leftAlt :1; + unsigned leftGUI :1; + unsigned rightControl :1; + unsigned rightShift :1; + unsigned rightAlt :1; + unsigned rightGUI :1; + } bits; + } modifiers; + + /* There is one byte of constant data/padding that is specified in the + * input report: + * + * 0x95, 0x01, // REPORT_COUNT (1) + * 0x75, 0x08, // REPORT_SIZE (8) + * 0x81, 0x03, // INPUT (Cnst,Var,Abs) + */ + unsigned :8; + + /* The last INPUT item in the INPUT report is an array type. This array + * contains an entry for each of the keys that are currently pressed until + * the array limit, in this case 6 concurent key presses. + * + * 0x95, 0x06, // REPORT_COUNT (6) + * 0x75, 0x08, // REPORT_SIZE (8) + * 0x15, 0x00, // LOGICAL_MINIMUM (0) + * 0x25, 0x65, // LOGICAL_MAXIMUM (101) + * 0x05, 0x07, // USAGE_PAGE (Keyboard) + * 0x19, 0x00, // USAGE_MINIMUM (Reserved (no event indicated)) + * 0x29, 0x65, // USAGE_MAXIMUM (Keyboard Application) + * + * Report count is 6 indicating that the array has 6 total entries. + * Report size is 8 indicating each entry in the array is one byte. + * The usage minimum indicates the lowest key value (Reserved/no event) + * The usage maximum indicates the highest key value (Application button) + * The logical minimum indicates the remapped value for the usage minimum: + * No Event has a logical value of 0. + * The logical maximum indicates the remapped value for the usage maximum: + * Application button has a logical value of 101. + * + * In this case the logical min/max match the usage min/max so the logical + * remapping doesn't actually change the values. + * + * To send a report with the 'a' key pressed (usage value of 0x04, logical + * value in this example of 0x04 as well), then the array input would be the + * following: + * + * LSB [0x04][0x00][0x00][0x00][0x00][0x00] MSB + * + * If the 'b' button was then pressed with the 'a' button still held down, + * the report would then look like this: + * + * LSB [0x04][0x05][0x00][0x00][0x00][0x00] MSB + * + * If the 'a' button was then released with the 'b' button still held down, + * the resulting array would be the following: + * + * LSB [0x05][0x00][0x00][0x00][0x00][0x00] MSB + * + * The 'a' key was removed from the array and all other items in the array + * were shifted down. */ + uint8_t keys[6]; +} KEYBOARD_INPUT_REPORT; + + +/* This typedef defines the only OUTPUT report found in the HID report + * descriptor and gives an easy way to parse the OUTPUT report. */ +typedef union __attribute__((packed)) +{ + /* The OUTPUT report is comprised of only one byte of data. */ + uint8_t value; + struct + { + /* There are two report items that form the one byte of OUTPUT report + * data. The first report item defines 5 LED indicators: + * + * 0x95, 0x05, // REPORT_COUNT (5) + * 0x75, 0x01, // REPORT_SIZE (1) + * 0x05, 0x08, // USAGE_PAGE (LEDs) + * 0x19, 0x01, // USAGE_MINIMUM (Num Lock) + * 0x29, 0x05, // USAGE_MAXIMUM (Kana) + * 0x91, 0x02, // OUTPUT (Data,Var,Abs) + * + * The report count indicates there are 5 entries. + * The report size is 1 indicating each entry is just one bit. + * These items are located on the LED usage page + * These items are all of the usages between Num Lock (the usage + * minimum) and Kana (the usage maximum). + */ + unsigned numLock :1; + unsigned capsLock :1; + unsigned scrollLock :1; + unsigned compose :1; + unsigned kana :1; + + /* The second OUTPUT report item defines 3 bits of constant data + * (padding) used to make a complete byte: + * + * 0x95, 0x01, // REPORT_COUNT (1) + * 0x75, 0x03, // REPORT_SIZE (3) + * 0x91, 0x03, // OUTPUT (Cnst,Var,Abs) + * + * Report count of 1 indicates that there is one entry + * Report size of 3 indicates the entry is 3 bits long. */ + unsigned :3; + } leds; +} KEYBOARD_OUTPUT_REPORT; + + +/* This creates a storage type for all of the information required to track the + * current state of the keyboard. */ +typedef struct +{ + USB_HANDLE lastINTransmission; + USB_HANDLE lastOUTTransmission; + int8_t oldKeyIndex; + int8_t keyIndex; +} KEYBOARD; + +// ***************************************************************************** +// ***************************************************************************** +// Section: File Scope or Global Variables +// ***************************************************************************** +// ***************************************************************************** +static KEYBOARD keyboard; + +#if !defined(KEYBOARD_INPUT_REPORT_DATA_BUFFER_ADDRESS_TAG) + #define KEYBOARD_INPUT_REPORT_DATA_BUFFER_ADDRESS_TAG +#endif +static KEYBOARD_INPUT_REPORT inputReport KEYBOARD_INPUT_REPORT_DATA_BUFFER_ADDRESS_TAG; + +#if !defined(KEYBOARD_OUTPUT_REPORT_DATA_BUFFER_ADDRESS_TAG) + #define KEYBOARD_OUTPUT_REPORT_DATA_BUFFER_ADDRESS_TAG +#endif +static volatile KEYBOARD_OUTPUT_REPORT outputReport KEYBOARD_OUTPUT_REPORT_DATA_BUFFER_ADDRESS_TAG; + +static uint8_t emptyReport[8] = { 0, 0, 0, 0, 0, 0, 0, 0 }; +static uint8_t storedReports[APP_PAGE_COUNT][APP_BUTTON_MATRIX_SIZE][8] = { + { + {0x40, 0, 0xe6, 0x56, 0, 0, 0, 0 }, // alt - + {0x40, 0, 0xe6, 0x57, 0, 0, 0, 0 }, // alt + + {0, 0, 0x1b, 0, 0, 0, 0, 0 }, // x + {0, 0, 0x2f, 0, 0, 0, 0, 0 }, //[ + {0, 0, 0x30, 0, 0, 0, 0, 0 }, // ] + {0x04, 0, 0xe2, 0, 0, 0, 0, 0 }, // alt + {0, 0, 0x5, 0, 0, 0, 0, 0 }, // b + {0, 0, 0xd, 0, 0, 0, 0, 0 }, // j + {0, 0, 0x16, 0, 0, 0, 0, 0 }, // s + }, + { + {0, 0, 0, 0, 0, 0, 0, 0 }, + {0, 0, 0, 0, 0, 0, 0, 0 }, + {0, 0, 0, 0, 0, 0, 0, 0 }, + {0, 0, 0, 0, 0, 0, 0, 0 }, + {0, 0, 0, 0, 0, 0, 0, 0 }, + {0, 0, 0, 0, 0, 0, 0, 0 }, + {0, 0, 0, 0, 0, 0, 0, 0 }, + {0, 0, 0, 0, 0, 0, 0, 0 }, + {0, 0, 0, 0, 0, 0, 0, 0 }, + }, + { + {0, 0, 0, 0, 0, 0, 0, 0 }, + {0, 0, 0, 0, 0, 0, 0, 0 }, + {0, 0, 0, 0, 0, 0, 0, 0 }, + {0, 0, 0, 0, 0, 0, 0, 0 }, + {0, 0, 0, 0, 0, 0, 0, 0 }, + {0, 0, 0, 0, 0, 0, 0, 0 }, + {0, 0, 0, 0, 0, 0, 0, 0 }, + {0, 0, 0, 0, 0, 0, 0, 0 }, + {0, 0, 0, 0, 0, 0, 0, 0 }, + }, + { + {0, 0, 0, 0, 0, 0, 0, 0 }, + {0, 0, 0, 0, 0, 0, 0, 0 }, + {0, 0, 0, 0, 0, 0, 0, 0 }, + {0, 0, 0, 0, 0, 0, 0, 0 }, + {0, 0, 0, 0, 0, 0, 0, 0 }, + {0, 0, 0, 0, 0, 0, 0, 0 }, + {0, 0, 0, 0, 0, 0, 0, 0 }, + {0, 0, 0, 0, 0, 0, 0, 0 }, + {0, 0, 0, 0, 0, 0, 0, 0 }, + } +}; + + + +// ***************************************************************************** +// ***************************************************************************** +// Section: Private Prototypes +// ***************************************************************************** +// ***************************************************************************** +static void APP_KeyboardProcessOutputReport(void); + + +//Exteranl variables declared in other .c files +extern volatile signed int SOFCounter; + + +//Application variables that need wide scope +signed int keyboardIdleRate; +signed int LocalSOFCount; +static signed int OldSOFCount; + + + + +// ***************************************************************************** +// ***************************************************************************** +// Section: Macros or Functions +// ***************************************************************************** +// ***************************************************************************** + +static uint8_t* APP_KeyboardGetReport() { + if (keyboard.keyIndex < 0) { + return emptyReport; + } else { + return storedReports[APP_PageSelectorGetIndex()][(uint8_t) keyboard.keyIndex]; + } +} + +void APP_KeyboardInit(void) +{ + //initialize the variable holding the handle for the last + // transmission + keyboard.lastINTransmission = 0; + + keyboard.keyIndex = -1; + keyboard.oldKeyIndex = -1; + + //Set the default idle rate to 500ms (until the host sends a SET_IDLE request to change it to a new value) + keyboardIdleRate = 500; + + //Copy the (possibly) interrupt context SOFCounter value into a local variable. + //Using a while() loop to do this since the SOFCounter isn't necessarily atomically + //updated and therefore we need to read it a minimum of twice to ensure we captured the correct value. + while(OldSOFCount != SOFCounter) + { + OldSOFCount = SOFCounter; + } + + //enable the HID endpoint + USBEnableEndpoint(HID_EP, USB_IN_ENABLED|USB_OUT_ENABLED|USB_HANDSHAKE_ENABLED|USB_DISALLOW_SETUP); + + //Arm OUT endpoint so we can receive caps lock, num lock, etc. info from host + keyboard.lastOUTTransmission = HIDRxPacket(HID_EP,(uint8_t*)&outputReport, sizeof(outputReport) ); +} + +void APP_KeyboardTasks(void) +{ + signed int TimeDeltaMilliseconds; + unsigned char i; + bool needToSendNewReportPacket; + + /* If the USB device isn't configured yet, we can't really do anything + * else since we don't have a host to talk to. So jump back to the + * top of the while loop. */ + if( USBGetDeviceState() < CONFIGURED_STATE ) + { + return; + } + + /* If we are currently suspended, then we need to see if we need to + * issue a remote wakeup. In either case, we shouldn't process any + * keyboard commands since we aren't currently communicating to the host + * thus just continue back to the start of the while loop. */ + if( USBIsDeviceSuspended() == true ) + { + //Check if we should assert a remote wakeup request to the USB host, + //when the user presses the pushbutton. + + return; + } + + //Copy the (possibly) interrupt context SOFCounter value into a local variable. + //Using a while() loop to do this since the SOFCounter isn't necessarily atomically + //updated and we need to read it a minimum of twice to ensure we captured the correct value. + while(LocalSOFCount != SOFCounter) + { + LocalSOFCount = SOFCounter; + } + + //Compute the elapsed time since the last input report was sent (we need + //this info for properly obeying the HID idle rate set by the host). + TimeDeltaMilliseconds = LocalSOFCount - OldSOFCount; + //Check for negative value due to count wraparound back to zero. + if(TimeDeltaMilliseconds < 0) + { + TimeDeltaMilliseconds = (32767 - OldSOFCount) + LocalSOFCount; + } + //Check if the TimeDelay is quite large. If the idle rate is == 0 (which represents "infinity"), + //then the TimeDeltaMilliseconds could also become infinity (which would cause overflow) + //if there is no recent button presses or other changes occurring on the keyboard. + //Therefore, saturate the TimeDeltaMilliseconds if it gets too large, by virtue + //of updating the OldSOFCount, even if we haven't actually sent a packet recently. + if(TimeDeltaMilliseconds > 5000) + { + OldSOFCount = LocalSOFCount - 5000; + } + + + /* Check if the IN endpoint is busy, and if it isn't check if we want to send + * keystroke data to the host. */ + if(HIDTxHandleBusy(keyboard.lastINTransmission) == false) + { + keyboard.keyIndex = APP_ButtonMatrixGetIndex(); + + //Check to see if the new packet contents are somehow different from the most + //recently sent packet contents. + needToSendNewReportPacket = (bool) (keyboard.keyIndex != keyboard.oldKeyIndex); + + //Check if the host has set the idle rate to something other than 0 (which is effectively "infinite"). + //If the idle rate is non-infinite, check to see if enough time has elapsed since + //the last packet was sent, and it is time to send a new repeated packet or not. + if(keyboardIdleRate != 0) + { + //Check if the idle rate time limit is met. If so, need to send another HID input report packet to the host + if(TimeDeltaMilliseconds >= keyboardIdleRate) + { + needToSendNewReportPacket = true; + } + } + + //Now send the new input report packet, if it is appropriate to do so (ex: new data is + //present or the idle rate limit was met). + if(needToSendNewReportPacket == true) + { + //Save the old input report packet contents. We do this so we can detect changes in report packet content + //useful for determining when something has changed and needs to get re-sent to the host when using + //infinite idle rate setting. + keyboard.oldKeyIndex = keyboard.keyIndex; + + memcpy(&inputReport, APP_KeyboardGetReport(), sizeof(inputReport)); + + /* Send the 8 byte packet over USB to the host. */ + keyboard.lastINTransmission = HIDTxPacket(HID_EP, (uint8_t*)&inputReport, sizeof(inputReport)); + OldSOFCount = LocalSOFCount; //Save the current time, so we know when to send the next packet (which depends in part on the idle rate setting) + } + + }//if(HIDTxHandleBusy(keyboard.lastINTransmission) == false) + + + /* Check if any data was sent from the PC to the keyboard device. Report + * descriptor allows host to send 1 byte of data. Bits 0-4 are LED states, + * bits 5-7 are unused pad bits. The host can potentially send this OUT + * report data through the HID OUT endpoint (EP1 OUT), or, alternatively, + * the host may try to send LED state information by sending a SET_REPORT + * control transfer on EP0. See the USBHIDCBSetReportHandler() function. */ + if(HIDRxHandleBusy(keyboard.lastOUTTransmission) == false) + { + APP_KeyboardProcessOutputReport(); + + keyboard.lastOUTTransmission = HIDRxPacket(HID_EP,(uint8_t*)&outputReport,sizeof(outputReport)); + } + + return; +} + +static void APP_KeyboardProcessOutputReport(void) +{ + +} + +static void USBHIDCBSetReportComplete(void) +{ + /* 1 byte of LED state data should now be in the CtrlTrfData buffer. Copy + * it to the OUTPUT report buffer for processing */ + outputReport.value = CtrlTrfData[0]; + + /* Process the OUTPUT report. */ + APP_KeyboardProcessOutputReport(); +} + +void USBHIDCBSetReportHandler(void) +{ + /* Prepare to receive the keyboard LED state data through a SET_REPORT + * control transfer on endpoint 0. The host should only send 1 byte, + * since this is all that the report descriptor allows it to send. */ + USBEP0Receive((uint8_t*)&CtrlTrfData, USB_EP0_BUFF_SIZE, USBHIDCBSetReportComplete); +} + + +//Callback function called by the USB stack, whenever the host sends a new SET_IDLE +//command. +void USBHIDCBSetIdleRateHandler(uint8_t reportID, uint8_t newIdleRate) +{ + //Make sure the report ID matches the keyboard input report id number. + //If however the firmware doesn't implement/use report ID numbers, + //then it should be == 0. + if(reportID == 0) + { + keyboardIdleRate = newIdleRate; + } +} + + +/******************************************************************************* + End of File +*/ diff --git a/src/device_config.c b/src/device_config.c new file mode 100644 index 0000000..3d53811 --- /dev/null +++ b/src/device_config.c @@ -0,0 +1,102 @@ +/** + @Generated PIC10 / PIC12 / PIC16 / PIC18 MCUs Source File + + @Company: + Microchip Technology Inc. + + @File Name: + mcc.c + + @Summary: + This is the mcc.c file generated using PIC10 / PIC12 / PIC16 / PIC18 MCUs + + @Description: + This header file provides implementations for driver APIs for all modules selected in the GUI. + Generation Information : + Product Revision : PIC10 / PIC12 / PIC16 / PIC18 MCUs - 1.65.2 + Device : PIC18F14K50 + Driver Version : 2.00 + The generated drivers are tested against the following: + Compiler : XC8 1.45 or later + MPLAB : MPLAB X 4.15 +*/ + +/* + (c) 2018 Microchip Technology Inc. and its subsidiaries. + + Subject to your compliance with these terms, you may use Microchip software and any + derivatives exclusively with Microchip products. It is your responsibility to comply with third party + license terms applicable to your use of third party software (including open source software) that + may accompany Microchip software. + + THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES, WHETHER + EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE, INCLUDING ANY + IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY, AND FITNESS + FOR A PARTICULAR PURPOSE. + + IN NO EVENT WILL MICROCHIP BE LIABLE FOR ANY INDIRECT, SPECIAL, PUNITIVE, + INCIDENTAL OR CONSEQUENTIAL LOSS, DAMAGE, COST OR EXPENSE OF ANY KIND + WHATSOEVER RELATED TO THE SOFTWARE, HOWEVER CAUSED, EVEN IF MICROCHIP + HAS BEEN ADVISED OF THE POSSIBILITY OR THE DAMAGES ARE FORESEEABLE. TO + THE FULLEST EXTENT ALLOWED BY LAW, MICROCHIP'S TOTAL LIABILITY ON ALL + CLAIMS IN ANY WAY RELATED TO THIS SOFTWARE WILL NOT EXCEED THE AMOUNT + OF FEES, IF ANY, THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR THIS + SOFTWARE. +*/ + +// Configuration bits: selected in the GUI + +// CONFIG1L +#pragma config CPUDIV = NOCLKDIV // CPU System Clock Selection bits->No CPU System Clock divide +#pragma config USBDIV = OFF // USB Clock Selection bit->USB clock comes directly from the OSC1/OSC2 oscillator block; no divide + +// CONFIG1H +#pragma config FOSC = HS // Oscillator Selection bits->HS oscillator +#pragma config PLLEN = ON // 4 X PLL Enable bit->Oscillator multiplied by 4 +#pragma config PCLKEN = ON // Primary Clock Enable bit->Primary clock enabled +#pragma config FCMEN = OFF // Fail-Safe Clock Monitor Enable->Fail-Safe Clock Monitor disabled +#pragma config IESO = OFF // Internal/External Oscillator Switchover bit->Oscillator Switchover mode disabled + +// CONFIG2L +#pragma config PWRTEN = OFF // Power-up Timer Enable bit->PWRT disabled +#pragma config BOREN = OFF // Brown-out Reset Enable bits->Brown-out Reset disabled in hardware and software +#pragma config BORV = 30 // Brown-out Reset Voltage bits->VBOR set to 3.0 V nominal + +// CONFIG2H +#pragma config WDTEN = OFF // Watchdog Timer Enable bit->WDT is controlled by SWDTEN bit of the WDTCON register +#pragma config WDTPS = 32768 // Watchdog Timer Postscale Select bits->1:32768 + +// CONFIG3H +#pragma config HFOFST = OFF // HFINTOSC Fast Start-up bit->The system clock is held off until the HFINTOSC is stable. +#pragma config MCLRE = ON // MCLR Pin Enable bit->MCLR pin enabled; RA3 input pin disabled + +// CONFIG4L +#pragma config STVREN = ON // Stack Full/Underflow Reset Enable bit->Stack full/underflow will cause Reset +#pragma config LVP = OFF // Single-Supply ICSP Enable bit->Single-Supply ICSP disabled +#pragma config BBSIZ = OFF // Boot Block Size Select bit->1kW boot block size +#pragma config XINST = OFF // Extended Instruction Set Enable bit->Instruction set extension and Indexed Addressing mode disabled (Legacy mode) +#pragma config DEBUG = OFF // Background Debugger Enable bit->Background debugger disabled, RA0 and RA1 configured as general purpose I/O pins + +// CONFIG5L +#pragma config CP0 = OFF // Code Protection bit->Block 0 not code-protected +#pragma config CP1 = OFF // Code Protection bit->Block 1 not code-protected + +// CONFIG5H +#pragma config CPB = OFF // Boot Block Code Protection bit->Boot block not code-protected +#pragma config CPD = OFF // Data EEPROM Code Protection bit->Data EEPROM not code-protected + +// CONFIG6L +#pragma config WRT0 = OFF // Table Write Protection bit->Block 0 not write-protected +#pragma config WRT1 = OFF // Table Write Protection bit->Block 1 not write-protected + +// CONFIG6H +#pragma config WRTC = OFF // Configuration Register Write Protection bit->Configuration registers not write-protected +#pragma config WRTB = OFF // Boot Block Write Protection bit->Boot block not write-protected +#pragma config WRTD = OFF // Data EEPROM Write Protection bit->Data EEPROM not write-protected + +// CONFIG7L +#pragma config EBTR0 = OFF // Table Read Protection bit->Block 0 not protected from table reads executed in other blocks +#pragma config EBTR1 = OFF // Table Read Protection bit->Block 1 not protected from table reads executed in other blocks + +// CONFIG7H +#pragma config EBTRB = OFF // Boot Block Table Read Protection bit->Boot block not protected from table reads executed in other blocks diff --git a/src/main.c b/src/main.c new file mode 100644 index 0000000..ae768ae --- /dev/null +++ b/src/main.c @@ -0,0 +1,78 @@ +/** + Generated Main Source File + + Company: + Microchip Technology Inc. + + File Name: + main.c + + Summary: + This is the main file generated using PIC10 / PIC12 / PIC16 / PIC18 MCUs + + Description: + This header file provides implementations for driver APIs for all modules selected in the GUI. + Generation Information : + Product Revision : PIC10 / PIC12 / PIC16 / PIC18 MCUs - 1.65.2 + Device : PIC18F14K50 + Driver Version : 2.00 +*/ + +/* + (c) 2018 Microchip Technology Inc. and its subsidiaries. + + Subject to your compliance with these terms, you may use Microchip software and any + derivatives exclusively with Microchip products. It is your responsibility to comply with third party + license terms applicable to your use of third party software (including open source software) that + may accompany Microchip software. + + THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES, WHETHER + EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE, INCLUDING ANY + IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY, AND FITNESS + FOR A PARTICULAR PURPOSE. + + IN NO EVENT WILL MICROCHIP BE LIABLE FOR ANY INDIRECT, SPECIAL, PUNITIVE, + INCIDENTAL OR CONSEQUENTIAL LOSS, DAMAGE, COST OR EXPENSE OF ANY KIND + WHATSOEVER RELATED TO THE SOFTWARE, HOWEVER CAUSED, EVEN IF MICROCHIP + HAS BEEN ADVISED OF THE POSSIBILITY OR THE DAMAGES ARE FORESEEABLE. TO + THE FULLEST EXTENT ALLOWED BY LAW, MICROCHIP'S TOTAL LIABILITY ON ALL + CLAIMS IN ANY WAY RELATED TO THIS SOFTWARE WILL NOT EXCEED THE AMOUNT + OF FEES, IF ANY, THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR THIS + SOFTWARE. + */ + +#include "mcc.h" +#include + +#include "usb.h" +#include "usb_device_hid.h" + +/* Demo project includes */ +#include "app_device_keyboard.h" +#include "app_page_selector.h" +#include "app_button_matrix.h" + +/* + Main application + */ +void main(void) +{ + // Initialize the device + SYSTEM_Initialize(); + + APP_PageSelectorInit(); + APP_ButtonMatrixInit(); + + USBDeviceInit(); + USBDeviceAttach(); + + while (1) { + USBDeviceTasks(); + APP_PageSelectorUpdate(); + APP_ButtonMatrixScan(); + APP_KeyboardTasks(); + } +} +/** + End of File +*/ diff --git a/src/mcc.c b/src/mcc.c new file mode 100644 index 0000000..43b1fc9 --- /dev/null +++ b/src/mcc.c @@ -0,0 +1,70 @@ +/** + @Generated PIC10 / PIC12 / PIC16 / PIC18 MCUs Source File + + @Company: + Microchip Technology Inc. + + @File Name: + mcc.c + + @Summary: + This is the mcc.c file generated using PIC10 / PIC12 / PIC16 / PIC18 MCUs + + @Description: + This header file provides implementations for driver APIs for all modules selected in the GUI. + Generation Information : + Product Revision : PIC10 / PIC12 / PIC16 / PIC18 MCUs - 1.65.2 + Device : PIC18F14K50 + Driver Version : 2.00 + The generated drivers are tested against the following: + Compiler : XC8 1.45 or later + MPLAB : MPLAB X 4.15 +*/ + +/* + (c) 2018 Microchip Technology Inc. and its subsidiaries. + + Subject to your compliance with these terms, you may use Microchip software and any + derivatives exclusively with Microchip products. It is your responsibility to comply with third party + license terms applicable to your use of third party software (including open source software) that + may accompany Microchip software. + + THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES, WHETHER + EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE, INCLUDING ANY + IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY, AND FITNESS + FOR A PARTICULAR PURPOSE. + + IN NO EVENT WILL MICROCHIP BE LIABLE FOR ANY INDIRECT, SPECIAL, PUNITIVE, + INCIDENTAL OR CONSEQUENTIAL LOSS, DAMAGE, COST OR EXPENSE OF ANY KIND + WHATSOEVER RELATED TO THE SOFTWARE, HOWEVER CAUSED, EVEN IF MICROCHIP + HAS BEEN ADVISED OF THE POSSIBILITY OR THE DAMAGES ARE FORESEEABLE. TO + THE FULLEST EXTENT ALLOWED BY LAW, MICROCHIP'S TOTAL LIABILITY ON ALL + CLAIMS IN ANY WAY RELATED TO THIS SOFTWARE WILL NOT EXCEED THE AMOUNT + OF FEES, IF ANY, THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR THIS + SOFTWARE. +*/ + +#include "mcc.h" + + +void SYSTEM_Initialize(void) +{ + + PIN_MANAGER_Initialize(); + OSCILLATOR_Initialize(); +} + +void OSCILLATOR_Initialize(void) +{ + // SCS0 FOSC; IDLEN disabled; IRCF 1MHz_HF; + OSCCON = 0x30; + // LFIOFS not stable; PRI_SD ON; HFIOFL not locked; + OSCCON2 = 0x04; + // INTSRC INTRC; SPLLEN disabled; TUN 0; + OSCTUNE = 0x00; +} + + +/** + End of File +*/ diff --git a/src/pin_manager.c b/src/pin_manager.c new file mode 100644 index 0000000..b7ce131 --- /dev/null +++ b/src/pin_manager.c @@ -0,0 +1,84 @@ +/** + Generated Pin Manager File + + Company: + Microchip Technology Inc. + + File Name: + pin_manager.c + + Summary: + This is the Pin Manager file generated using PIC10 / PIC12 / PIC16 / PIC18 MCUs + + Description: + This header file provides implementations for pin APIs for all pins selected in the GUI. + Generation Information : + Product Revision : PIC10 / PIC12 / PIC16 / PIC18 MCUs - 1.65.2 + Device : PIC18F14K50 + Driver Version : 2.01 + The generated drivers are tested against the following: + Compiler : XC8 1.45 + MPLAB : MPLAB X 4.15 + + Copyright (c) 2013 - 2015 released Microchip Technology Inc. All rights reserved. +*/ + +/* + (c) 2018 Microchip Technology Inc. and its subsidiaries. + + Subject to your compliance with these terms, you may use Microchip software and any + derivatives exclusively with Microchip products. It is your responsibility to comply with third party + license terms applicable to your use of third party software (including open source software) that + may accompany Microchip software. + + THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES, WHETHER + EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE, INCLUDING ANY + IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY, AND FITNESS + FOR A PARTICULAR PURPOSE. + + IN NO EVENT WILL MICROCHIP BE LIABLE FOR ANY INDIRECT, SPECIAL, PUNITIVE, + INCIDENTAL OR CONSEQUENTIAL LOSS, DAMAGE, COST OR EXPENSE OF ANY KIND + WHATSOEVER RELATED TO THE SOFTWARE, HOWEVER CAUSED, EVEN IF MICROCHIP + HAS BEEN ADVISED OF THE POSSIBILITY OR THE DAMAGES ARE FORESEEABLE. TO + THE FULLEST EXTENT ALLOWED BY LAW, MICROCHIP'S TOTAL LIABILITY ON ALL + CLAIMS IN ANY WAY RELATED TO THIS SOFTWARE WILL NOT EXCEED THE AMOUNT + OF FEES, IF ANY, THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR THIS + SOFTWARE. +*/ + +#include +#include "pin_manager.h" +#include "stdbool.h" + +void PIN_MANAGER_Initialize(void) { + /** + LATx registers + */ + LATA = 0x00; + LATB = 0x00; + LATC = 0x07; + + /** + TRISx registers + */ + TRISA = 0x30; + TRISB = 0xF0; + TRISC = 0x00; + + /** + ANSELx registers + */ + ANSEL = 0; + ANSELH = 0; + + /** + WPUx registers + */ + WPUB = 0xF0; + WPUA = 0x00; + INTCON2bits.nRABPU = 0; +} + +/** + End of File +*/ \ No newline at end of file diff --git a/src/usb_descriptors.c b/src/usb_descriptors.c new file mode 100644 index 0000000..d2df16f --- /dev/null +++ b/src/usb_descriptors.c @@ -0,0 +1,151 @@ +/******************************************************************************* +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 +*******************************************************************************/ + +// ***************************************************************************** +// ***************************************************************************** +// Section: Included Files +// ***************************************************************************** +// ***************************************************************************** +#include + +#include "usb.h" +#include "usb_device_hid.h" + + +// ***************************************************************************** +// ***************************************************************************** +// Section: File Scope or Global Constants +// ***************************************************************************** +// ***************************************************************************** + +/* 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 + 0x00, // Class Code + 0x00, // Subclass code + 0x00, // Protocol code + USB_EP0_BUFF_SIZE, // Max packet size for EP0, see usb_config.h + MY_VID, // Vendor ID + MY_PID, // Product ID: Keyboard fw demo + 0x0001, // 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 + DESC_CONFIG_WORD(0x0029), // Total length of data for this cfg + 1, // 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 */ + 0x09,//sizeof(USB_INTF_DSC), // Size of this descriptor in bytes + USB_DESCRIPTOR_INTERFACE, // INTERFACE descriptor type + 0, // Interface Number + 0, // Alternate Setting Number + 2, // Number of endpoints in this intf + HID_INTF, // Class code + BOOT_INTF_SUBCLASS, // Subclass code + HID_PROTOCOL_KEYBOARD, // Protocol code + 0, // Interface string index + + /* HID Class-Specific Descriptor */ + 0x09,//sizeof(USB_HID_DSC)+3, // Size of this descriptor in bytes RRoj hack + DSC_HID, // HID descriptor type + DESC_CONFIG_WORD(0x0111), // HID Spec Release Number in BCD format (1.11) + 0x00, // Country Code (0x00 for Not supported) + HID_NUM_OF_DSC, // Number of class descriptors, see usbcfg.h + DSC_RPT, // Report descriptor type + DESC_CONFIG_WORD(63), //sizeof(hid_rpt01), // Size of the report descriptor + + /* Endpoint Descriptor */ + 0x07,/*sizeof(USB_EP_DSC)*/ + USB_DESCRIPTOR_ENDPOINT, //Endpoint Descriptor + HID_EP | _EP_IN, //EndpointAddress + _INTERRUPT, //Attributes + DESC_CONFIG_WORD(8), //size + 0x01, //Interval + + /* Endpoint Descriptor */ + 0x07,/*sizeof(USB_EP_DSC)*/ + USB_DESCRIPTOR_ENDPOINT, //Endpoint Descriptor + HID_EP | _EP_OUT, //EndpointAddress + _INTERRUPT, //Attributes + DESC_CONFIG_WORD(8), //size + 0x01 //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[11];}sd001={ // 25 +sizeof(sd001),USB_DESCRIPTOR_STRING, +{'B','i','t','g','a','m','m','a',' ','O','U'}}; + +//Product string descriptor +const struct{uint8_t bLength;uint8_t bDscType;uint16_t string[7];}sd002={ // 13 +sizeof(sd002),USB_DESCRIPTOR_STRING, +{'P','a','l','e','t','t','e'}}; + +//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[]= +{ + (const uint8_t *const)&sd000, + (const uint8_t *const)&sd001, + (const uint8_t *const)&sd002 +}; + +// ***************************************************************************** +// ***************************************************************************** +// Section: File Scope Data Types +// ***************************************************************************** +// ***************************************************************************** + + +// ***************************************************************************** +// ***************************************************************************** +// Section: Macros or Functions +// ***************************************************************************** +// ***************************************************************************** + +/******************************************************************************* + End of File +*/ + diff --git a/src/usb_events.c b/src/usb_events.c new file mode 100644 index 0000000..8cc5294 --- /dev/null +++ b/src/usb_events.c @@ -0,0 +1,117 @@ +/******************************************************************************* +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 +*******************************************************************************/ + +// ***************************************************************************** +// ***************************************************************************** +// Section: Included Files +// ***************************************************************************** +// ***************************************************************************** +/* Standard C includes */ +#include + +/* Microchip library includes */ +#include "usb.h" +#include "usb_device_hid.h" + +/* Project includes */ +#include "app_device_keyboard.h" + + +// ***************************************************************************** +// ***************************************************************************** +// Section: File Scope or Global Constants +// ***************************************************************************** +// ***************************************************************************** +volatile signed int SOFCounter = 0; + +/******************************************************************* + * Function: bool USER_USB_CALLBACK_EVENT_HANDLER( + * USB_EVENT event, void *pdata, uint16_t size) + * + * PreCondition: None + * + * Input: USB_EVENT event - the type of event + * void *pdata - pointer to the event data + * uint16_t size - size of the event data + * + * Output: None + * + * Side Effects: None + * + * Overview: This function is called from the USB stack to + * notify a user application that a USB event + * occured. This callback is in interrupt context + * when the USB_INTERRUPT option is selected. + * + * Note: None + *******************************************************************/ +bool USER_USB_CALLBACK_EVENT_HANDLER(USB_EVENT event, void *pdata, uint16_t size) +{ + switch((int)event) + { + case EVENT_TRANSFER: + break; + + case EVENT_SOF: + if(SOFCounter < 32767) + { + SOFCounter++; + } + else + { + SOFCounter = 0; + } + break; + + case EVENT_SUSPEND: + break; + + case EVENT_RESUME: + break; + + case EVENT_CONFIGURED: + /* When the device is configured, we can (re)initialize the keyboard + * demo code. */ + APP_KeyboardInit(); + break; + + case EVENT_SET_DESCRIPTOR: + break; + + case EVENT_EP0_REQUEST: + /* We have received a non-standard USB request. The HID driver + * needs to check to see if the request was for it. */ + USBCheckHIDRequest(); + break; + + case EVENT_BUS_ERROR: + break; + + case EVENT_TRANSFER_TERMINATED: + break; + + default: + break; + } + return true; +} + +/******************************************************************************* + End of File +*/ diff --git a/usb/inc/usb.h b/usb/inc/usb.h new file mode 100644 index 0000000..6a2aa13 --- /dev/null +++ b/usb/inc/usb.h @@ -0,0 +1,66 @@ +// 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 + + +/******************************************************************************* + Module for Microchip USB Library + + Company: + Microchip Technology Inc. + + File Name: + usb.h + + Summary: + This header file exposes the core library APIs and definitions for the USB + library. + + Description: + This header file exposes the core library APIs and definitions for the USB + library. The user is responsible for also including the header file for + the specific driver they will be using. +*******************************************************************************/ + +#ifndef _USB_H_ +#define _USB_H_ + +#include "usb_config.h" + +#include "usb_common.h" // Common USB library definitions +#include "usb_ch9.h" // USB device framework definitions + +#if defined( USB_SUPPORT_DEVICE ) + #include "usb_device.h" // USB Device abstraction layer interface +#endif + +#include "usb_hal.h" // Hardware Abstraction Layer interface + +/* USB Library version number. This can be used to verify in an application + specific version of the library is being used. + */ +#define USB_MAJOR_VER 2 // Firmware version, major release number. +#define USB_MINOR_VER 13 // Firmware version, minor release number. +#define USB_DOT_VER 0 // Firmware version, dot release number. + +#endif // _USB_H_ + + + diff --git a/usb/inc/usb_ch9.h b/usb/inc/usb_ch9.h new file mode 100644 index 0000000..97010f5 --- /dev/null +++ b/usb/inc/usb_ch9.h @@ -0,0 +1,596 @@ +// 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 + + +/******************************************************************************* + Module for Microchip USB Library + + Company: + Microchip Technology Inc. + + File Name: + usb_ch9.h + + Summary: + Defines types associated with chapter 9 of the USB specification. + + Description: + Defines types associated with chapter 9 of the USB specification. +*******************************************************************************/ + +#ifndef _USB_CH9_H_ +#define _USB_CH9_H_ + +#include + +#if defined(__XC8) + #define __attribute__(a) +#endif + +// ***************************************************************************** +// ***************************************************************************** +// Section: USB Descriptors +// ***************************************************************************** +// ***************************************************************************** + +#define USB_DESCRIPTOR_DEVICE 0x01 // bDescriptorType for a Device Descriptor. +#define USB_DESCRIPTOR_CONFIGURATION 0x02 // bDescriptorType for a Configuration Descriptor. +#define USB_DESCRIPTOR_STRING 0x03 // bDescriptorType for a String Descriptor. +#define USB_DESCRIPTOR_INTERFACE 0x04 // bDescriptorType for an Interface Descriptor. +#define USB_DESCRIPTOR_ENDPOINT 0x05 // bDescriptorType for an Endpoint Descriptor. +#define USB_DESCRIPTOR_DEVICE_QUALIFIER 0x06 // bDescriptorType for a Device Qualifier. +#define USB_DESCRIPTOR_OTHER_SPEED 0x07 // bDescriptorType for a Other Speed Configuration. +#define USB_DESCRIPTOR_INTERFACE_POWER 0x08 // bDescriptorType for Interface Power. +#define USB_DESCRIPTOR_OTG 0x09 // bDescriptorType for an OTG Descriptor. + +// ***************************************************************************** +/* USB Device Descriptor Structure + +This struct defines the structure of a USB Device Descriptor. +*/ +typedef struct __attribute__ ((packed)) _USB_DEVICE_DESCRIPTOR +{ + uint8_t bLength; // Length of this descriptor. + uint8_t bDescriptorType; // DEVICE descriptor type (USB_DESCRIPTOR_DEVICE). + uint16_t bcdUSB; // USB Spec Release Number (BCD). + uint8_t bDeviceClass; // Class code (assigned by the USB-IF). 0xFF-Vendor specific. + uint8_t bDeviceSubClass; // Subclass code (assigned by the USB-IF). + uint8_t bDeviceProtocol; // Protocol code (assigned by the USB-IF). 0xFF-Vendor specific. + uint8_t bMaxPacketSize0; // Maximum packet size for endpoint 0. + uint16_t idVendor; // Vendor ID (assigned by the USB-IF). + uint16_t idProduct; // Product ID (assigned by the manufacturer). + uint16_t bcdDevice; // Device release number (BCD). + uint8_t iManufacturer; // Index of String Descriptor describing the manufacturer. + uint8_t iProduct; // Index of String Descriptor describing the product. + uint8_t iSerialNumber; // Index of String Descriptor with the device's serial number. + uint8_t bNumConfigurations; // Number of possible configurations. +} USB_DEVICE_DESCRIPTOR; + + +// ***************************************************************************** +/* USB Configuration Descriptor Structure + +This struct defines the structure of a USB Configuration Descriptor. +*/ +typedef struct __attribute__ ((packed)) _USB_CONFIGURATION_DESCRIPTOR +{ + uint8_t bLength; // Length of this descriptor. + uint8_t bDescriptorType; // CONFIGURATION descriptor type (USB_DESCRIPTOR_CONFIGURATION). + uint16_t wTotalLength; // Total length of all descriptors for this configuration. + uint8_t bNumInterfaces; // Number of interfaces in this configuration. + uint8_t bConfigurationValue; // Value of this configuration (1 based). + uint8_t iConfiguration; // Index of String Descriptor describing the configuration. + uint8_t bmAttributes; // Configuration characteristics. + uint8_t bMaxPower; // Maximum power consumed by this configuration. +} USB_CONFIGURATION_DESCRIPTOR; + +// Attributes bits +#define USB_CFG_DSC_REQUIRED 0x80 // Required attribute +#define USB_CFG_DSC_SELF_PWR (0x40|USB_CFG_DSC_REQUIRED) // Device is self powered. +#define USB_CFG_DSC_REM_WAKE (0x20|USB_CFG_DSC_REQUIRED) // Device can request remote wakup + + +// ***************************************************************************** +/* USB Interface Descriptor Structure + +This struct defines the structure of a USB Interface Descriptor. +*/ +typedef struct __attribute__ ((packed)) _USB_INTERFACE_DESCRIPTOR +{ + uint8_t bLength; // Length of this descriptor. + uint8_t bDescriptorType; // INTERFACE descriptor type (USB_DESCRIPTOR_INTERFACE). + uint8_t bInterfaceNumber; // Number of this interface (0 based). + uint8_t bAlternateSetting; // Value of this alternate interface setting. + uint8_t bNumEndpoints; // Number of endpoints in this interface. + uint8_t bInterfaceClass; // Class code (assigned by the USB-IF). 0xFF-Vendor specific. + uint8_t bInterfaceSubClass; // Subclass code (assigned by the USB-IF). + uint8_t bInterfaceProtocol; // Protocol code (assigned by the USB-IF). 0xFF-Vendor specific. + uint8_t iInterface; // Index of String Descriptor describing the interface. +} USB_INTERFACE_DESCRIPTOR; + + +// ***************************************************************************** +/* USB Endpoint Descriptor Structure + +This struct defines the structure of a USB Endpoint Descriptor. +*/ +typedef struct __attribute__ ((packed)) _USB_ENDPOINT_DESCRIPTOR +{ + uint8_t bLength; // Length of this descriptor. + uint8_t bDescriptorType; // ENDPOINT descriptor type (USB_DESCRIPTOR_ENDPOINT). + uint8_t bEndpointAddress; // Endpoint address. Bit 7 indicates direction (0=OUT, 1=IN). + uint8_t bmAttributes; // Endpoint transfer type. + uint16_t wMaxPacketSize; // Maximum packet size. + uint8_t bInterval; // Polling interval in frames. +} USB_ENDPOINT_DESCRIPTOR; + + +// Endpoint Direction +#define EP_DIR_IN 0x80 // Data flows from device to host +#define EP_DIR_OUT 0x00 // Data flows from host to device + + +// ****************************************************************** +// USB Endpoint Attributes +// ****************************************************************** + +// Section: Transfer Types +#define EP_ATTR_CONTROL (0<<0) // Endoint used for control transfers +#define EP_ATTR_ISOCH (1<<0) // Endpoint used for isochronous transfers +#define EP_ATTR_BULK (2<<0) // Endpoint used for bulk transfers +#define EP_ATTR_INTR (3<<0) // Endpoint used for interrupt transfers + +// Section: Synchronization Types (for isochronous endpoints) +#define EP_ATTR_NO_SYNC (0<<2) // No Synchronization +#define EP_ATTR_ASYNC (1<<2) // Asynchronous +#define EP_ATTR_ADAPT (2<<2) // Adaptive synchronization +#define EP_ATTR_SYNC (3<<2) // Synchronous + +// Section: Usage Types (for isochronous endpoints) +#define EP_ATTR_DATA (0<<4) // Data Endpoint +#define EP_ATTR_FEEDBACK (1<<4) // Feedback endpoint +#define EP_ATTR_IMP_FB (2<<4) // Implicit Feedback data EP + +// Section: Max Packet Sizes +#define EP_MAX_PKT_INTR_LS 8 // Max low-speed interrupt packet +#define EP_MAX_PKT_INTR_FS 64 // Max full-speed interrupt packet +#define EP_MAX_PKT_ISOCH_FS 1023 // Max full-speed isochronous packet +#define EP_MAX_PKT_BULK_FS 64 // Max full-speed bulk packet +#define EP_LG_PKT_BULK_FS 32 // Large full-speed bulk packet +#define EP_MED_PKT_BULK_FS 16 // Medium full-speed bulk packet +#define EP_SM_PKT_BULK_FS 8 // Small full-speed bulk packet + +/* Descriptor IDs +The descriptor ID type defines the information required by the HOST during a +GET_DESCRIPTOR request +*/ +typedef struct +{ + uint8_t index; + uint8_t type; + uint16_t language_id; + +} DESCRIPTOR_ID; + +// ***************************************************************************** +/* USB OTG Descriptor Structure + +This struct defines the structure of a USB OTG Descriptor. Note that this +structure may need to be packed, or even accessed as uint8_ts, to properly access +the correct fields when used on some device architectures. +*/ +typedef struct __attribute__ ((packed)) _USB_OTG_DESCRIPTOR +{ + uint8_t bLength; // Length of this descriptor. + uint8_t bDescriptorType; // OTG descriptor type (USB_DESCRIPTOR_OTG). + uint8_t bmAttributes; // OTG attributes. +} USB_OTG_DESCRIPTOR; + + +// ****************************************************************** +// Section: USB String Descriptor Structure +// ****************************************************************** +// This structure describes the USB string descriptor. The string +// descriptor provides user-readable information about various aspects of +// the device. The first string descriptor (string descriptor zero (0)), +// provides a list of the number of languages supported by the set of +// string descriptors for this device instead of an actual string. +// +// Note: The strings are in 2-uint8_t-per-character unicode, not ASCII. +// +// Note: This structure only describes the "header" of the string +// descriptor. The actual data (either the language ID array or the +// array of unicode characters making up the string, must be allocated +// immediately following this header with no padding between them. + +typedef struct __attribute__ ((packed)) _USB_STRING_DSC +{ + uint8_t bLength; // Size of this descriptor + uint8_t bDescriptorType; // Type, USB_DSC_STRING + +} USB_STRING_DESCRIPTOR; + + +// ****************************************************************** +// Section: USB Device Qualifier Descriptor Structure +// ****************************************************************** +// This structure describes the device qualifier descriptor. The device +// qualifier descriptor provides overall device information if the device +// supports "other" speeds. +// +// Note: A high-speed device may support "other" speeds (ie. full or low). +// If so, it may need to implement the the device qualifier and other +// speed descriptors. + +typedef struct __attribute__ ((packed)) _USB_DEVICE_QUALIFIER_DESCRIPTOR +{ + uint8_t bLength; // Size of this descriptor + uint8_t bType; // Type, always USB_DESCRIPTOR_DEVICE_QUALIFIER + uint16_t bcdUSB; // USB spec version, in BCD + uint8_t bDeviceClass; // Device class code + uint8_t bDeviceSubClass; // Device sub-class code + uint8_t bDeviceProtocol; // Device protocol + uint8_t bMaxPacketSize0; // EP0, max packet size + uint8_t bNumConfigurations; // Number of "other-speed" configurations + uint8_t bReserved; // Always zero (0) + +} USB_DEVICE_QUALIFIER_DESCRIPTOR; + +// ****************************************************************** +// Section: USB Setup Packet Structure +// ****************************************************************** +// This structure describes the data contained in a USB standard device +// request setup packet. It is the data packet sent from the host to +// the device to control and configure the device. +// +// Note: Refer to the USB 2.0 specification for additional details on the +// usage of the setup packet and standard device requests. +typedef union __attribute__ ((packed)) +{ + /** Standard Device Requests ***********************************/ + struct __attribute__ ((packed)) + { + uint8_t bmRequestType; //from table 9-2 of USB2.0 spec + uint8_t bRequest; //from table 9-2 of USB2.0 spec + uint16_t wValue; //from table 9-2 of USB2.0 spec + uint16_t wIndex; //from table 9-2 of USB2.0 spec + uint16_t wLength; //from table 9-2 of USB2.0 spec + }; + struct __attribute__ ((packed)) + { + unsigned :8; + unsigned :8; + union + { + uint16_t Val; + uint8_t v[2]; + struct + { + uint8_t LB; + uint8_t HB; + } byte; + } W_Value; + + union + { + uint16_t Val; + uint8_t v[2]; + struct + { + uint8_t LB; + uint8_t HB; + } byte; + } W_Index; + + union + { + uint16_t Val; + uint8_t v[2]; + struct + { + uint8_t LB; + uint8_t HB; + } byte; + } W_Length; + }; + struct __attribute__ ((packed)) + { + unsigned Recipient:5; //Device,Interface,Endpoint,Other + unsigned RequestType:2; //Standard,Class,Vendor,Reserved + unsigned DataDir:1; //Host-to-device,Device-to-host + unsigned :8; + uint8_t bFeature; //DEVICE_REMOTE_WAKEUP,ENDPOINT_HALT + unsigned :8; + unsigned :8; + unsigned :8; + unsigned :8; + unsigned :8; + }; + struct __attribute__ ((packed)) + { + union // offset description + { // ------ ------------------------ + uint8_t bmRequestType; // 0 Bit-map of request type + struct + { + uint8_t recipient: 5; // Recipient of the request + uint8_t type: 2; // Type of request + uint8_t direction: 1; // Direction of data X-fer + }; + }requestInfo; + }; + struct __attribute__ ((packed)) + { + unsigned :8; + unsigned :8; + uint8_t bDscIndex; //For Configuration and String DSC Only + uint8_t bDescriptorType; //Device,Configuration,String + uint16_t wLangID; //Language ID + unsigned :8; + unsigned :8; + }; + struct __attribute__ ((packed)) + { + unsigned :8; + unsigned :8; + uint8_t bDevADR; //Device Address 0-127 + uint8_t bDevADRH; //Must equal zero + unsigned :8; + unsigned :8; + unsigned :8; + unsigned :8; + }; + struct __attribute__ ((packed)) + { + unsigned :8; + unsigned :8; + uint8_t bConfigurationValue; //Configuration Value 0-255 + uint8_t bCfgRSD; //Must equal zero (Reserved) + unsigned :8; + unsigned :8; + unsigned :8; + unsigned :8; + }; + struct __attribute__ ((packed)) + { + unsigned :8; + unsigned :8; + uint8_t bAltID; //Alternate Setting Value 0-255 + uint8_t bAltID_H; //Must equal zero + uint8_t bIntfID; //Interface Number Value 0-255 + uint8_t bIntfID_H; //Must equal zero + unsigned :8; + unsigned :8; + }; + struct __attribute__ ((packed)) + { + unsigned :8; + unsigned :8; + unsigned :8; + unsigned :8; + uint8_t bEPID; //Endpoint ID (Number & Direction) + uint8_t bEPID_H; //Must equal zero + unsigned :8; + unsigned :8; + }; + struct __attribute__ ((packed)) + { + unsigned :8; + unsigned :8; + unsigned :8; + unsigned :8; + unsigned EPNum:4; //Endpoint Number 0-15 + unsigned :3; + unsigned EPDir:1; //Endpoint Direction: 0-OUT, 1-IN + unsigned :8; + unsigned :8; + unsigned :8; + }; + + /** End: Standard Device Requests ******************************/ + +} CTRL_TRF_SETUP, SETUP_PKT, *PSETUP_PKT; + + +// ****************************************************************** +// ****************************************************************** +// Section: USB Specification Constants +// ****************************************************************** +// ****************************************************************** + +// Section: Valid PID Values +//DOM-IGNORE-BEGIN +#define PID_OUT 0x1 // PID for an OUT token +#define PID_ACK 0x2 // PID for an ACK handshake +#define PID_DATA0 0x3 // PID for DATA0 data +#define PID_PING 0x4 // Special PID PING +#define PID_SOF 0x5 // PID for a SOF token +#define PID_NYET 0x6 // PID for a NYET handshake +#define PID_DATA2 0x7 // PID for DATA2 data +#define PID_SPLIT 0x8 // Special PID SPLIT +#define PID_IN 0x9 // PID for a IN token +#define PID_NAK 0xA // PID for a NAK handshake +#define PID_DATA1 0xB // PID for DATA1 data +#define PID_PRE 0xC // Special PID PRE (Same as PID_ERR) +#define PID_ERR 0xC // Special PID ERR (Same as PID_PRE) +#define PID_SETUP 0xD // PID for a SETUP token +#define PID_STALL 0xE // PID for a STALL handshake +#define PID_MDATA 0xF // PID for MDATA data + +#define PID_MASK_DATA 0x03 // Data PID mask +#define PID_MASK_DATA_SHIFTED (PID_MASK_DATA << 2) // Data PID shift to proper position +//DOM-IGNORE-END + +// Section: USB Token Types +//DOM-IGNORE-BEGIN +#define USB_TOKEN_OUT 0x01 // U1TOK - OUT token +#define USB_TOKEN_IN 0x09 // U1TOK - IN token +#define USB_TOKEN_SETUP 0x0D // U1TOK - SETUP token +//DOM-IGNORE-END + +// Section: OTG Descriptor Constants + +#define OTG_HNP_SUPPORT 0x02 // OTG Descriptor bmAttributes - HNP support flag +#define OTG_SRP_SUPPORT 0x01 // OTG Descriptor bmAttributes - SRP support flag + +// Section: Endpoint Directions + +#define USB_IN_EP 0x80 // IN endpoint mask +#define USB_OUT_EP 0x00 // OUT endpoint mask + +// Section: Standard Device Requests + +#define USB_REQUEST_GET_STATUS 0 // Standard Device Request - GET STATUS +#define USB_REQUEST_CLEAR_FEATURE 1 // Standard Device Request - CLEAR FEATURE +#define USB_REQUEST_SET_FEATURE 3 // Standard Device Request - SET FEATURE +#define USB_REQUEST_SET_ADDRESS 5 // Standard Device Request - SET ADDRESS +#define USB_REQUEST_GET_DESCRIPTOR 6 // Standard Device Request - GET DESCRIPTOR +#define USB_REQUEST_SET_DESCRIPTOR 7 // Standard Device Request - SET DESCRIPTOR +#define USB_REQUEST_GET_CONFIGURATION 8 // Standard Device Request - GET CONFIGURATION +#define USB_REQUEST_SET_CONFIGURATION 9 // Standard Device Request - SET CONFIGURATION +#define USB_REQUEST_GET_INTERFACE 10 // Standard Device Request - GET INTERFACE +#define USB_REQUEST_SET_INTERFACE 11 // Standard Device Request - SET INTERFACE +#define USB_REQUEST_SYNCH_FRAME 12 // Standard Device Request - SYNCH FRAME + +#define USB_FEATURE_ENDPOINT_HALT 0 // CLEAR/SET FEATURE - Endpoint Halt +#define USB_FEATURE_DEVICE_REMOTE_WAKEUP 1 // CLEAR/SET FEATURE - Device remote wake-up +#define USB_FEATURE_TEST_MODE 2 // CLEAR/SET FEATURE - Test mode + +// Section: Setup Data Constants + +#define USB_SETUP_HOST_TO_DEVICE 0x00 // Device Request bmRequestType transfer direction - host to device transfer +#define USB_SETUP_DEVICE_TO_HOST 0x80 // Device Request bmRequestType transfer direction - device to host transfer +#define USB_SETUP_TYPE_STANDARD 0x00 // Device Request bmRequestType type - standard +#define USB_SETUP_TYPE_CLASS 0x20 // Device Request bmRequestType type - class +#define USB_SETUP_TYPE_VENDOR 0x40 // Device Request bmRequestType type - vendor +#define USB_SETUP_RECIPIENT_DEVICE 0x00 // Device Request bmRequestType recipient - device +#define USB_SETUP_RECIPIENT_INTERFACE 0x01 // Device Request bmRequestType recipient - interface +#define USB_SETUP_RECIPIENT_ENDPOINT 0x02 // Device Request bmRequestType recipient - endpoint +#define USB_SETUP_RECIPIENT_OTHER 0x03 // Device Request bmRequestType recipient - other + +#define USB_SETUP_HOST_TO_DEVICE_BITFIELD (USB_SETUP_HOST_TO_DEVICE>>7) // Device Request bmRequestType transfer direction - host to device transfer - bit definition +#define USB_SETUP_DEVICE_TO_HOST_BITFIELD (USB_SETUP_DEVICE_TO_HOST>>7) // Device Request bmRequestType transfer direction - device to host transfer - bit definition +#define USB_SETUP_TYPE_STANDARD_BITFIELD (USB_SETUP_TYPE_STANDARD>>5) // Device Request bmRequestType type - standard +#define USB_SETUP_TYPE_CLASS_BITFIELD (USB_SETUP_TYPE_CLASS>>5) // Device Request bmRequestType type - class +#define USB_SETUP_TYPE_VENDOR_BITFIELD (USB_SETUP_TYPE_VENDOR>>5) // Device Request bmRequestType type - vendor +#define USB_SETUP_RECIPIENT_DEVICE_BITFIELD (USB_SETUP_RECIPIENT_DEVICE) // Device Request bmRequestType recipient - device +#define USB_SETUP_RECIPIENT_INTERFACE_BITFIELD (USB_SETUP_RECIPIENT_INTERFACE) // Device Request bmRequestType recipient - interface +#define USB_SETUP_RECIPIENT_ENDPOINT_BITFIELD (USB_SETUP_RECIPIENT_ENDPOINT) // Device Request bmRequestType recipient - endpoint +#define USB_SETUP_RECIPIENT_OTHER_BITFIELD (USB_SETUP_RECIPIENT_OTHER) // Device Request bmRequestType recipient - other + +// Section: OTG SET FEATURE Constants + +#define OTG_FEATURE_B_HNP_ENABLE 3 // SET FEATURE OTG - Enable B device to perform HNP +#define OTG_FEATURE_A_HNP_SUPPORT 4 // SET FEATURE OTG - A device supports HNP +#define OTG_FEATURE_A_ALT_HNP_SUPPORT 5 // SET FEATURE OTG - Another port on the A device supports HNP + +// Section: USB Endpoint Transfer Types + +#define USB_TRANSFER_TYPE_CONTROL 0x00 // Endpoint is a control endpoint. +#define USB_TRANSFER_TYPE_ISOCHRONOUS 0x01 // Endpoint is an isochronous endpoint. +#define USB_TRANSFER_TYPE_BULK 0x02 // Endpoint is a bulk endpoint. +#define USB_TRANSFER_TYPE_INTERRUPT 0x03 // Endpoint is an interrupt endpoint. + +// Section: Standard Feature Selectors for CLEAR_FEATURE Requests +#define USB_FEATURE_ENDPOINT_STALL 0 // Endpoint recipient +#define USB_FEATURE_DEVICE_REMOTE_WAKEUP 1 // Device recipient +#define USB_FEATURE_TEST_MODE 2 // Device recipient + + +// Section: USB Class Code Definitions +#define USB_HUB_CLASSCODE 0x09 // Class code for a hub. + +/******************************************************************** +USB Endpoint Definitions +USB Standard EP Address Format: DIR:X:X:X:EP3:EP2:EP1:EP0 +This is used in the descriptors. +********************************************************************/ +#define _EP_IN 0x80 +#define _EP_OUT 0x00 +#define _EP01_OUT 0x01 +#define _EP01_IN 0x81 +#define _EP02_OUT 0x02 +#define _EP02_IN 0x82 +#define _EP03_OUT 0x03 +#define _EP03_IN 0x83 +#define _EP04_OUT 0x04 +#define _EP04_IN 0x84 +#define _EP05_OUT 0x05 +#define _EP05_IN 0x85 +#define _EP06_OUT 0x06 +#define _EP06_IN 0x86 +#define _EP07_OUT 0x07 +#define _EP07_IN 0x87 +#define _EP08_OUT 0x08 +#define _EP08_IN 0x88 +#define _EP09_OUT 0x09 +#define _EP09_IN 0x89 +#define _EP10_OUT 0x0A +#define _EP10_IN 0x8A +#define _EP11_OUT 0x0B +#define _EP11_IN 0x8B +#define _EP12_OUT 0x0C +#define _EP12_IN 0x8C +#define _EP13_OUT 0x0D +#define _EP13_IN 0x8D +#define _EP14_OUT 0x0E +#define _EP14_IN 0x8E +#define _EP15_OUT 0x0F +#define _EP15_IN 0x8F + +/* Configuration Attributes */ +#define _DEFAULT (0x01<<7) //Default Value (Bit 7 is set) +#define _SELF (0x01<<6) //Self-powered (Supports if set) +#define _RWU (0x01<<5) //Remote Wakeup (Supports if set) +#define _HNP (0x01 << 1) //HNP (Supports if set) +#define _SRP (0x01) //SRP (Supports if set) + +/* Endpoint Transfer Type */ +#define _CTRL 0x00 //Control Transfer +#define _ISO 0x01 //Isochronous Transfer +#define _BULK 0x02 //Bulk Transfer + +#define _INTERRUPT 0x03 //Interrupt Transfer +#if defined(__18CXX) || defined(__C30__) || defined __XC16__ || defined(__XC8) + #define _INT 0x03 //Interrupt Transfer +#endif + +/* Isochronous Endpoint Synchronization Type */ +#define _NS (0x00<<2) //No Synchronization +#define _AS (0x01<<2) //Asynchronous +#define _AD (0x02<<2) //Adaptive +#define _SY (0x03<<2) //Synchronous + +/* Isochronous Endpoint Usage Type */ +#define _DE (0x00<<4) //Data endpoint +#define _FE (0x01<<4) //Feedback endpoint +#define _IE (0x02<<4) //Implicit feedback Data endpoint + +//These are the directional indicators used for the USBTransferOnePacket() +// function. +#define OUT_FROM_HOST 0 +#define IN_TO_HOST 1 + +#endif // _USB_CH9_H_ +/************************************************************************* + * EOF + */ + diff --git a/usb/inc/usb_common.h b/usb/inc/usb_common.h new file mode 100644 index 0000000..755c4a7 --- /dev/null +++ b/usb/inc/usb_common.h @@ -0,0 +1,474 @@ +// 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 + + +/******************************************************************************* + Module for Microchip USB Library + + Company: + Microchip Technology Inc. + + File Name: + usb_common.h + + Summary: + Defines types associated with both the USB host and USB device stacks but + not defined by the USB specification. + + Description: + Defines types associated with both the USB host and USB device stacks but + not defined by the USB specification. +*******************************************************************************/ + +//DOM-IGNORE-BEGIN +#ifndef _USB_COMMON_H_ +#define _USB_COMMON_H_ +//DOM-IGNORE-END + +#include +#include +#include + +// ***************************************************************************** +// ***************************************************************************** +// Section: USB Constants +// ***************************************************************************** +// ***************************************************************************** + +// Section: Error Code Values + +#define USB_SUCCESS 0x00 // USB operation successful. +#define USB_INVALID_STATE 0x01 // Operation cannot be performed in current state. +#define USB_BUSY 0x02 // A transaction is already in progress. +#define USB_ILLEGAL_REQUEST 0x03 // Cannot perform requested operation. +#define USB_INVALID_CONFIGURATION 0x04 // Configuration descriptor not found. +#define USB_MEMORY_ALLOCATION_ERROR 0x05 // Out of dynamic memory. +#define USB_UNKNOWN_DEVICE 0x06 // Device with specified address is not attached. +#define USB_CANNOT_ENUMERATE 0x07 // Cannot enumerate the attached device. +#define USB_EVENT_QUEUE_FULL 0x08 // Event queue was full when an event occured. +#define USB_ENDPOINT_BUSY 0x10 // Endpoint is currently processing a transaction. +#define USB_ENDPOINT_STALLED 0x11 // Endpoint is currently stalled. User must clear the condition. +#define USB_ENDPOINT_ERROR 0x12 // Will need more than this eventually +#define USB_ENDPOINT_ERROR_ILLEGAL_PID 0x13 // Illegal PID received. +#define USB_ENDPOINT_NOT_FOUND 0x14 // Requested endpoint does not exist on device. +#define USB_ENDPOINT_ILLEGAL_DIRECTION 0x15 // Reads must be performe on IN endpoints, writes on OUT endpoints. +//#define USB_ENDPOINT_TRANSACTION_IN_PROGRESS 0x16 +#define USB_ENDPOINT_NAK_TIMEOUT 0x17 // Too many NAK's occurred while waiting for the current transaction. +#define USB_ENDPOINT_ILLEGAL_TYPE 0x18 // Transfer type must match endpoint description. +#define USB_ENDPOINT_UNRESOLVED_STATE 0x19 // Endpoint is in an unknown state after completing a transaction. +#define USB_ENDPOINT_ERROR_BIT_STUFF 0x20 // USB Module - Bit stuff error. +#define USB_ENDPOINT_ERROR_DMA 0x21 // USB Module - DMA error. +#define USB_ENDPOINT_ERROR_TIMEOUT 0x22 // USB Module - Bus timeout. +#define USB_ENDPOINT_ERROR_DATA_FIELD 0x23 // USB Module - Data field size error. +#define USB_ENDPOINT_ERROR_CRC16 0x24 // USB Module - CRC16 failure. +#define USB_ENDPOINT_ERROR_END_OF_FRAME 0x25 // USB Module - End of Frame error. +#define USB_ENDPOINT_ERROR_PID_CHECK 0x26 // USB Module - Illegal PID received. +#define USB_ENDPOINT_ERROR_BMX 0x27 // USB Module - Bus Matrix error. +#define USB_ERROR_INSUFFICIENT_POWER 0x28 // Too much power was requested + +// Section: Return values for USBHostDeviceStatus() + +#define USB_DEVICE_STATUS 0x30 // Offset for USBHostDeviceStatus() return codes +#define USB_DEVICE_ATTACHED (USB_DEVICE_STATUS | 0x30) // Device is attached and running +#define USB_DEVICE_DETACHED (USB_DEVICE_STATUS | 0x01) // No device is attached +#define USB_DEVICE_ENUMERATING (USB_DEVICE_STATUS | 0x02) // Device is enumerating +#define USB_HOLDING_OUT_OF_MEMORY (USB_DEVICE_STATUS | 0x03) // Not enough heap space available +#define USB_HOLDING_UNSUPPORTED_DEVICE (USB_DEVICE_STATUS | 0x04) // Invalid configuration or unsupported class +#define USB_HOLDING_UNSUPPORTED_HUB (USB_DEVICE_STATUS | 0x05) // Hubs are not supported +#define USB_HOLDING_INVALID_CONFIGURATION (USB_DEVICE_STATUS | 0x06) // Invalid configuration requested +#define USB_HOLDING_PROCESSING_CAPACITY (USB_DEVICE_STATUS | 0x07) // Processing requirement excessive +#define USB_HOLDING_POWER_REQUIREMENT (USB_DEVICE_STATUS | 0x08) // Power requirement excessive +#define USB_HOLDING_CLIENT_INIT_ERROR (USB_DEVICE_STATUS | 0x09) // Client driver failed to initialize +#define USB_DEVICE_SUSPENDED (USB_DEVICE_STATUS | 0x0A) // Device is suspended + +#define USB_ERROR_CLASS_DEFINED 0x50 // Offset for application defined errors + +#define USB_SINGLE_DEVICE_ADDRESS 0x01 // Default USB device address (single device support) + + +// ***************************************************************************** +// ***************************************************************************** +// Section: USB Data Types +// ***************************************************************************** +// ***************************************************************************** + +// ***************************************************************************** +/* Data Transfer Flags + +The following flags are used in the flags parameter of the "USBDEVTransferData" +and "USBHALTransferData" routines. They can be accessed by the bitfield +definitions or the macros can be OR'd together to identify the endpoint number +and properties of the data transfer. + + + 7 6 5 4 3 2 1 0 - Field name + | | | | \_____/ + | | | | +----- ep_num - Endpoint number + | | | +---------- zero_pkt - End transfer with short or zero-sized packet + | | +------------ dts - 0=DATA0 packet, 1=DATA1 packet + | +-------------- force_dts - Force data toggle sync to match dts field + +---------------- direction - Transfer direction: 0=Receive, 1=Transmit + +*/ + +typedef union +{ + uint8_t bitmap; + struct + { + uint8_t ep_num: 4; + uint8_t zero_pkt: 1; + uint8_t dts: 1; + uint8_t force_dts: 1; + uint8_t direction: 1; + }field; + +} TRANSFER_FLAGS; + +// ***************************************************************************** +/* Data Transfer Flags, Endpoint Number Constants + +These macros can be used as values for the "ep_num" field of the TRANSFER_FLAGS +data type. +*/ +#define USB_EP0 0 // +#define USB_EP1 1 // +#define USB_EP2 2 // +#define USB_EP3 3 // +#define USB_EP4 4 // +#define USB_EP5 5 // +#define USB_EP6 6 // +#define USB_EP7 7 // +#define USB_EP8 8 // +#define USB_EP9 9 // +#define USB_EP10 10 // +#define USB_EP11 11 // +#define USB_EP12 12 // +#define USB_EP13 13 // +#define USB_EP14 14 // +#define USB_EP15 15 // + +// ***************************************************************************** +/* Data Transfer Flags, Bitmap Constants + +These macros can be used as values for the "bitmap" field of the TRANSFER_FLAGS +data type. +*/ +#define USB_TRANSMIT 0x80 // Data will be transmitted to the USB +#define USB_RECEIVE 0x00 // Data will be received from the USB +#define USB_FORCE_DTS 0x40 // Forces data toggle sync as below: +#define USB_DTS_MASK 0x20 // Mask for DTS bit (below) +#define USB_ZERO_PKT 0x10 // End transfer w/a short or zero-length packet +#define USB_DATA0 0x00|USB_FORCE_DTS // Force DATA0 +#define USB_DATA1 0x20|USB_FORCE_DTS // Force DATA1 +#define USB_SETUP_PKT USB_RECEIVE|USB_DATA0|USB_EP0 // Setup Packet +#define USB_SETUP_DATA USB_DATA1|USB_ZERO_PKT|USB_EP0 // Setup-transfer Data Packet +#define USB_SETUP_STATUS USB_DATA1|USB_EP0 // Setup-transfer Status Packet +#define USB_EP_NUM_MASK 0x0F // Endpoint number (ep_num) mask + +// ***************************************************************************** +/* Data Transfer Flags, Initialization Macro + +This macro can be used with the above bitmap constants to initialize a +TRANSFER_FLAGS value. It provides the correct data type to avoid compiler +warnings. +*/ +#define XFLAGS(f) ((TRANSFER_FLAGS)((uint8_t)(f))) // Initialization Macro + + +// ***************************************************************************** +/* USB Events + +This enumeration identifies USB events that occur. It is used to +inform USB drivers and applications of events on the bus. It is passed +as a parameter to the event-handling routine, which must match the +prototype of the USB_CLIENT_EVENT_HANDLER data type, when an event occurs. +*/ + +typedef enum +{ + // No event occured (NULL event) + EVENT_NONE = 0, + + EVENT_DEVICE_STACK_BASE = 1, + + EVENT_HOST_STACK_BASE = 100, + + // A USB hub has been attached. Hub support is not currently available. + EVENT_HUB_ATTACH, + + // A stall has occurred. This event is not used by the Host stack. + EVENT_STALL, + + // VBus SRP Pulse, (VBus > 2.0v), Data: uint8_t Port Number (For future support) + EVENT_VBUS_SES_REQUEST, + + // The voltage on Vbus has dropped below 4.4V/4.7V. The application is + // responsible for monitoring Vbus and calling USBHostVbusEvent() with this + // event. This event is not generated by the stack. + EVENT_VBUS_OVERCURRENT, + + // An enumerating device is requesting power. The data associated with this + // event is of the data type USB_VBUS_POWER_EVENT_DATA. Note that + // the requested current is specified in 2mA units, identical to the power + // specification in a device's Configuration Descriptor. + EVENT_VBUS_REQUEST_POWER, + + // Release power from a detaching device. The data associated with this + // event is of the data type USB_VBUS_POWER_EVENT_DATA. The current value + // specified in the data can be ignored. + EVENT_VBUS_RELEASE_POWER, + + // The voltage on Vbus is good, and the USB OTG module can be powered on. + // The application is responsible for monitoring Vbus and calling + // USBHostVbusEvent() with this event. This event is not generated by the + // stack. If the application issues an EVENT_VBUS_OVERCURRENT, then no + // power will be applied to that port, and no device can attach to that + // port, until the application issues the EVENT_VBUS_POWER_AVAILABLE for + // the port. + EVENT_VBUS_POWER_AVAILABLE, + + // The attached device is not supported by the application. The attached + // device is not allowed to enumerate. + EVENT_UNSUPPORTED_DEVICE, + + // Cannot enumerate the attached device. This is generated if communication + // errors prevent the device from enumerating. + EVENT_CANNOT_ENUMERATE, + + // The client driver cannot initialize the the attached device. The + // attached is not allowed to enumerate. + EVENT_CLIENT_INIT_ERROR, + + // The Host stack does not have enough heap space to enumerate the device. + // Check the amount of heap space allocated to the application. In MPLAB, + // select Project> Build Options...> Project. Select the appropriate + // linker tab, and inspect the "Heap size" entry. + EVENT_OUT_OF_MEMORY, + + // Unspecified host error. (This error should not occur). + EVENT_UNSPECIFIED_ERROR, + + // USB cable has been detached. The data associated with this event is the + // address of detached device, a single uint8_t. + EVENT_DETACH, + + // A USB transfer has completed. The data associated with this event is of + // the data type HOST_TRANSFER_DATA if the event is generated from the host + // stack. + EVENT_TRANSFER, + + // A USB Start of Frame token has been received. This event is not + // used by the Host stack. + EVENT_SOF, + + // Device-mode resume received. This event is not used by the Host stack. + EVENT_RESUME, + + // Device-mode suspend/idle event received. This event is not used by the + // Host stack. + EVENT_SUSPEND, + + // Device-mode bus reset received. This event is not used by the Host + // stack. + EVENT_RESET, + + // In Host mode, an isochronous data read has completed. This event will only + // be passed to the DataEventHandler, which is only utilized if it is defined. + // Note that the DataEventHandler is called from within the USB interrupt, so + // it is critical that it return in time for the next isochronous data packet. + EVENT_DATA_ISOC_READ, + + // In Host mode, an isochronous data write has completed. This event will only + // be passed to the DataEventHandler, which is only utilized if it is defined. + // Note that the DataEventHandler is called from within the USB interrupt, so + // it is critical that it return in time for the next isochronous data packet. + EVENT_DATA_ISOC_WRITE, + + // In Host mode, this event gives the application layer the option to reject + // a client driver that was selected by the stack. This is needed when multiple + // devices are supported by class level support, but one configuration and client + // driver is preferred over another. Since configuration number is not guaranteed, + // the stack cannot do this automatically. This event is issued only when + // looking through configuration descriptors; the driver selected at the device + // level cannot be overridden, since there shouldn't be any other options to + // choose from. + EVENT_OVERRIDE_CLIENT_DRIVER_SELECTION, + + // In host mode, this event is thrown for every millisecond that passes. Like all + // events, this is thrown from the USBHostTasks() or USBTasks() routine so its + // timeliness will be determined by the rate that these functions are called. If + // they are not called very often, then the 1ms events will build up and be + // dispatched as the USBTasks() or USBHostTasks() functions are called (one event + // per call to these functions. + EVENT_1MS, + + // In device mode, this event is thrown when we receive a Set Interface request from + // the host. The stack will automatically handle the interface switch, but the app + // may need to know about the interface switch for performing tasks such as powering + // up/down audio hardware. + EVENT_ALT_INTERFACE, + + // If the application layer must do things to the device before the device is + // configured, they should be done at this point. The application layer should + // return true to hold the USB state machine at this point, while any USB or other + // processing continues. When the USB state machine can safely proceed, the application + // layer should return FALSE. + EVENT_HOLD_BEFORE_CONFIGURATION, + + // Class-defined event offsets start here: + EVENT_GENERIC_BASE = 400, // Offset for Generic class events + + EVENT_MSD_BASE = 500, // Offset for Mass Storage Device class events + + EVENT_HID_BASE = 600, // Offset for Human Interface Device class events + + EVENT_PRINTER_BASE = 700, // Offset for Printer class events + + EVENT_CDC_BASE = 800, // Offset for CDC class events + + EVENT_CHARGER_BASE = 900, // Offset for Charger client driver events. + + EVENT_AUDIO_BASE = 1000, // Offset for Audio client driver events. + + EVENT_USER_BASE = 10000, // Add integral values to this event number + // to create user-defined events. + + // There was a transfer error on the USB. The data associated with this + // event is of data type HOST_TRANSFER_DATA. + EVENT_BUS_ERROR = INT_MAX + +} USB_EVENT; + + +// ***************************************************************************** +/* EVENT_TRANSFER Data + +This data structure is passed to the appropriate layer's +USB_EVENT_HANDLER when an EVT_XFER event has occurred, indicating +that a transfer has completed on the USB. It provides the endpoint, +direction, and actual size of the transfer. + */ + +typedef struct _transfer_event_data +{ + TRANSFER_FLAGS flags; // Transfer flags (see above) + uint32_t size; // Actual number of bytes transferred + uint8_t pid; // Packet ID + +} USB_TRANSFER_EVENT_DATA; + + +// ***************************************************************************** +/* EVENT_VBUS_REQUEST_POWER and EVENT_VBUS_RELEASE_POWER Data + +This data structure is passed to the appropriate layer's +USB_EVENT_HANDLER when an EVENT_VBUS_REQUEST_POWER or EVENT_VBUS_RELEASE_POWER +event has occurred, indicating that a change in Vbus power is being requested. +*/ + +typedef struct _vbus_power_data +{ + uint8_t port; // Physical port number + uint8_t current; // Current in 2mA units +} USB_VBUS_POWER_EVENT_DATA; + + +// ***************************************************************************** +/* USB_OVERRIDE_CLIENT_DRIVER_EVENT_DATA Data + +This data structure is passed to the application layer when a client driver is +select, in case multiple client drivers can support a particular device. +*/ +typedef struct _override_client_driver_data +{ + uint16_t idVendor; + uint16_t idProduct; + uint8_t bDeviceClass; + uint8_t bDeviceSubClass; + uint8_t bDeviceProtocol; +} USB_OVERRIDE_CLIENT_DRIVER_EVENT_DATA; + + +// ***************************************************************************** +/* EVT_STALL Data + +The EVT_STALL event has a 16-bit data value associated with it where +a bit is set in the position for each endpoint that is currently +stalled (ie. bit 0 = EP0, bit 1 = EP1, etc.) +*/ + + +// ***************************************************************************** +// ***************************************************************************** +// Section: Event Handling Routines +// ***************************************************************************** +// ***************************************************************************** + +/******************************************************************************* + Function: + bool ( USB_EVENT event, + void *data, unsigned int size ) + + Description: + This routine is a "call out" routine that must be implemented by + any layer of the USB SW Stack (except the HAL which is at the + root of the event-call tree that needs to receive events. When + an event occurs, the HAL calls the next higher layer in the + stack to handle the event. Each layer either handles the event + or calls the layer above it to handle the event. Events are + identified by the "event" parameter and may have associated + data. If the higher layer was able to handle the event, it + should return true. If not, it should return false. + + Preconditions: + USBInitialize must have been called to initialize the USB SW + Stack. + + Parameters: + USB_EVENT event - Identifies the bus event that occurred + void *data - Pointer to event-specific data + unsigned int size - Size of the event-specific data + + Return Values: + None + + Remarks: + The function is name is defined by the layer that implements + it. A pointer to the function will be placed by into a table + that the lower-layer will use to call it. This requires the + function to use a specific call "signature" (return data type + and values and data parameter types and values). + +*******************************************************************************/ + +typedef bool (*USB_EVENT_HANDLER) ( USB_EVENT event, void *data, unsigned int size ); + +#define USB_PING_PONG__NO_PING_PONG 0x00 //0b00 +#define USB_PING_PONG__EP0_OUT_ONLY 0x01 //0b01 +#define USB_PING_PONG__FULL_PING_PONG 0x02 //0b10 +#define USB_PING_PONG__ALL_BUT_EP0 0x03 //0b11 + +#endif // _USB_COMMON_H_ +/************************************************************************* + * EOF + */ + diff --git a/usb/inc/usb_device.h b/usb/inc/usb_device.h new file mode 100644 index 0000000..c8ecc9d --- /dev/null +++ b/usb/inc/usb_device.h @@ -0,0 +1,2054 @@ +// 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 + +/******************************************************************************* + Module for Microchip USB Library + + Company: + Microchip Technology Inc. + + File Name: + usb_device.h + + Summary: + Defines types and APIs associated with the USB device stack. + + Description: + Defines types and APIs associated with the USB device stack. +*******************************************************************************/ + +#ifndef _USB_DEVICE_H +#define _USB_DEVICE_H + +#include + +#include "usb_common.h" +#include "usb_config.h" + +#if defined(__XC8) + #define __attribute__(a) +#endif + +/** DEFINITIONS ****************************************************/ + +//USB_HANDLE is a pointer to an entry in the BDT. This pointer can be used +// to read the length of the last transfer, the status of the last transfer, +// and various other information. Insure to initialize USB_HANDLE objects +// to NULL so that they are in a known state during their first usage. +#define USB_HANDLE void* + +#define USB_EP0_ROM 0x00 //Data comes from RAM +#define USB_EP0_RAM 0x01 //Data comes from const +#define USB_EP0_BUSY 0x80 //The PIPE is busy +#define USB_EP0_INCLUDE_ZERO 0x40 //include a trailing zero packet +#define USB_EP0_NO_DATA 0x00 //no data to send +#define USB_EP0_NO_OPTIONS 0x00 //no options set + +/******************************************************************** + * Standard Request Codes + * USB 2.0 Spec Ref Table 9-4 + *******************************************************************/ + +/* USB Device States as returned by USBGetDeviceState(). Only the defenitions + for these states should be used. The actual value for each state should + not be relied upon as constant and may change based on the implementation. */ +typedef enum +{ + /* Detached is the state in which the device is not attached to the bus. When + in the detached state a device should not have any pull-ups attached to either + the D+ or D- line. */ + DETACHED_STATE + /*DOM-IGNORE-BEGIN*/ = 0x00 /*DOM-IGNORE-END*/, + /* Attached is the state in which the device is attached ot the bus but the + hub/port that it is attached to is not yet configured. */ + ATTACHED_STATE + /*DOM-IGNORE-BEGIN*/ = 0x01 /*DOM-IGNORE-END*/, + /* Powered is the state in which the device is attached to the bus and the + hub/port that it is attached to is configured. */ + POWERED_STATE + /*DOM-IGNORE-BEGIN*/ = 0x02 /*DOM-IGNORE-END*/, + /* Default state is the state after the device receives a RESET command from + the host. */ + DEFAULT_STATE + /*DOM-IGNORE-BEGIN*/ = 0x04 /*DOM-IGNORE-END*/, + /* Address pending state is not an official state of the USB defined states. + This state is internally used to indicate that the device has received a + SET_ADDRESS command but has not received the STATUS stage of the transfer yet. + The device is should not switch addresses until after the STATUS stage is + complete. */ + ADR_PENDING_STATE + /*DOM-IGNORE-BEGIN*/ = 0x08 /*DOM-IGNORE-END*/, + /* Address is the state in which the device has its own specific address on the + bus. */ + ADDRESS_STATE + /*DOM-IGNORE-BEGIN*/ = 0x10 /*DOM-IGNORE-END*/, + /* Configured is the state where the device has been fully enumerated and is + operating on the bus. The device is now allowed to execute its application + specific tasks. It is also allowed to increase its current consumption to the + value specified in the configuration descriptor of the current configuration. + */ + CONFIGURED_STATE + /*DOM-IGNORE-BEGIN*/ = 0x20 /*DOM-IGNORE-END*/ +} USB_DEVICE_STATE; + + +/* USB device stack events description here - DWF */ +typedef enum +{ + // Notification that a SET_CONFIGURATION() command was received (device) + EVENT_CONFIGURED + /*DOM-IGNORE-BEGIN*/ = EVENT_DEVICE_STACK_BASE /*DOM-IGNORE-END*/, + + // A SET_DESCRIPTOR request was received (device) + EVENT_SET_DESCRIPTOR, + + // An endpoint 0 request was received that the stack did not know how to + // handle. This is most often a request for one of the class drivers. + // Please refer to the class driver documentation for information related + // to what to do if this request is received. (device) + EVENT_EP0_REQUEST, + +// // A USB transfer has completed. The data associated with this event is of +// // the data type HOST_TRANSFER_DATA if the event is generated from the host +// // stack. +// EVENT_TRANSFER, +// +// // A USB Start of Frame token has been received. This event is not +// // used by the Host stack. +// EVENT_SOF, +// +// // Device-mode resume received. This event is not used by the Host stack. +// EVENT_RESUME, +// +// // Device-mode suspend/idle event received. This event is not used by the +// // Host stack. +// EVENT_SUSPEND, +// +// // Device-mode bus reset received. This event is not used by the Host +// // stack. +// EVENT_RESET, + +// // Device Mode: A setup packet received (data: SETUP_PKT). This event is +// // not used by the Host stack. +// EVENT_SETUP, + + // Device-mode USB cable has been attached. This event is not used by the + // Host stack. The client driver may provide an application event when a + // device attaches. + EVENT_ATTACH, + + // A user transfer was terminated by the stack. This event will pass back + // the value of the handle that was terminated. Compare this value against + // the current valid handles to determine which transfer was terminated. + EVENT_TRANSFER_TERMINATED + +} USB_DEVICE_STACK_EVENTS; + +/** Function Prototypes **********************************************/ + + +/******************************************************************************/ +/** External API Functions ****************************************************/ +/******************************************************************************/ + +/************************************************************************** + Function: + void USBDeviceInit(void) + + Description: + This function initializes the device stack it in the default state. The + USB module will be completely reset including all of the internal + variables, registers, and interrupt flags. + + Precondition: + This function must be called before any of the other USB Device + functions can be called, including USBDeviceTasks(). + + Parameters: + None + + Return Values: + None + + Remarks: + None + + **************************************************************************/ +void USBDeviceInit(void); + +/************************************************************************** + Function: + void USBDeviceTasks(void) + + Summary: + This function is the main state machine/transaction handler of the USB + device side stack. When the USB stack is operated in "USB_POLLING" mode + (usb_config.h user option) the USBDeviceTasks() function should be called + periodically to receive and transmit packets through the stack. This + function also takes care of control transfers associated with the USB + enumeration process, and detecting various USB events (such as suspend). + This function should be called at least once every 1.8ms during the USB + enumeration process. After the enumeration process is complete (which can + be determined when USBGetDeviceState() returns CONFIGURED_STATE), the + USBDeviceTasks() handler may be called the faster of: either once + every 9.8ms, or as often as needed to make sure that the hardware USTAT + FIFO never gets full. A good rule of thumb is to call USBDeviceTasks() at + a minimum rate of either the frequency that USBTransferOnePacket() gets + called, or, once/1.8ms, whichever is faster. See the inline code comments + near the top of usb_device.c for more details about minimum timing + requirements when calling USBDeviceTasks(). + + When the USB stack is operated in "USB_INTERRUPT" mode, it is not necessary + to call USBDeviceTasks() from the main loop context. In the USB_INTERRUPT + mode, the USBDeviceTasks() handler only needs to execute when a USB + interrupt occurs, and therefore only needs to be called from the interrupt + context. + + Description: + This function is the main state machine/transaction handler of the USB + device side stack. When the USB stack is operated in "USB_POLLING" mode + (usb_config.h user option) the USBDeviceTasks() function should be called + periodically to receive and transmit packets through the stack. This + function also takes care of control transfers associated with the USB + enumeration process, and detecting various USB events (such as suspend). + This function should be called at least once every 1.8ms during the USB + enumeration process. After the enumeration process is complete (which can + be determined when USBGetDeviceState() returns CONFIGURED_STATE), the + USBDeviceTasks() handler may be called the faster of: either once + every 9.8ms, or as often as needed to make sure that the hardware USTAT + FIFO never gets full. A good rule of thumb is to call USBDeviceTasks() at + a minimum rate of either the frequency that USBTransferOnePacket() gets + called, or, once/1.8ms, whichever is faster. See the inline code comments + near the top of usb_device.c for more details about minimum timing + requirements when calling USBDeviceTasks(). + + When the USB stack is operated in "USB_INTERRUPT" mode, it is not necessary + to call USBDeviceTasks() from the main loop context. In the USB_INTERRUPT + mode, the USBDeviceTasks() handler only needs to execute when a USB + interrupt occurs, and therefore only needs to be called from the interrupt + context. + + Typical usage: + + void main(void) + { + USBDeviceInit(); + while(1) + { + USBDeviceTasks(); //Takes care of enumeration and other USB events + if((USBGetDeviceState() \< CONFIGURED_STATE) || + (USBIsDeviceSuspended() == true)) + { + //Either the device is not configured or we are suspended, + // so we don't want to execute any USB related application code + continue; //go back to the top of the while loop + } + else + { + //Otherwise we are free to run USB and non-USB related user + //application code. + UserApplication(); + } + } + } + + + Precondition: + Make sure the USBDeviceInit() function has been called prior to calling + USBDeviceTasks() for the first time. + Remarks: + USBDeviceTasks() does not need to be called while in the USB suspend mode, + if the user application firmware in the USBCBSuspend() callback function + enables the ACTVIF USB interrupt source and put the microcontroller into + sleep mode. If the application firmware decides not to sleep the + microcontroller core during USB suspend (ex: continues running at full + frequency, or clock switches to a lower frequency), then the USBDeviceTasks() + function must still be called periodically, at a rate frequent enough to + ensure the 10ms resume recovery interval USB specification is met. Assuming + a worst case primary oscillator and PLL start up time of <5ms, then + USBDeviceTasks() should be called once every 5ms in this scenario. + + When the USB cable is detached, or the USB host is not actively powering + the VBUS line to +5V nominal, the application firmware does not always have + to call USBDeviceTasks() frequently, as no USB activity will be taking + place. However, if USBDeviceTasks() is not called regularly, some + alternative means of promptly detecting when VBUS is powered (indicating + host attachment), or not powered (host powered down or USB cable unplugged) + is still needed. For self or dual self/bus powered USB applications, see + the USBDeviceAttach() and USBDeviceDetach() API documentation for additional + considerations. + */ +void USBDeviceTasks(void); + + +/******************************************************************************* + Function: + void USBEnableEndpoint(uint8_t ep, uint8_t options) + + Summary: + This function will enable the specified endpoint with the specified + options + Description: + This function will enable the specified endpoint with the specified + options. + + Typical Usage: + + void USBCBInitEP(void) + { + USBEnableEndpoint(MSD_DATA_IN_EP,USB_IN_ENABLED|USB_OUT_ENABLED|USB_HANDSHAKE_ENABLED|USB_DISALLOW_SETUP); + USBMSDInit(); + } + + + In the above example endpoint number MSD_DATA_IN_EP is being configured + for both IN and OUT traffic with handshaking enabled. Also since + MSD_DATA_IN_EP is not endpoint 0 (MSD does not allow this), then we can + explicitly disable SETUP packets on this endpoint. + Conditions: + None + Input: + uint8_t ep - the endpoint to be configured + uint8_t options - optional settings for the endpoint. The options should + be ORed together to form a single options string. The + available optional settings for the endpoint. The + options should be ORed together to form a single options + string. The available options are the following\: + * USB_HANDSHAKE_ENABLED enables USB handshaking (ACK, + NAK) + * USB_HANDSHAKE_DISABLED disables USB handshaking (ACK, + NAK) + * USB_OUT_ENABLED enables the out direction + * USB_OUT_DISABLED disables the out direction + * USB_IN_ENABLED enables the in direction + * USB_IN_DISABLED disables the in direction + * USB_ALLOW_SETUP enables control transfers + * USB_DISALLOW_SETUP disables control transfers + * USB_STALL_ENDPOINT STALLs this endpoint + Return: + None + Remarks: + None + *****************************************************************************/ +void USBEnableEndpoint(uint8_t ep, uint8_t options); + + +/************************************************************************* + Function: + USB_HANDLE USBTransferOnePacket(uint8_t ep, uint8_t dir, uint8_t* data, uint8_t len) + + Summary: + Transfers a single packet (one transaction) of data on the USB bus. + + Description: + The USBTransferOnePacket() function prepares a USB endpoint + so that it may send data to the host (an IN transaction), or + receive data from the host (an OUT transaction). The + USBTransferOnePacket() function can be used both to receive and + send data to the host. This function is the primary API function + provided by the USB stack firmware for sending or receiving application + data over the USB port. + + The USBTransferOnePacket() is intended for use with all application + endpoints. It is not used for sending or receiving application data + through endpoint 0 by using control transfers. Separate API + functions, such as USBEP0Receive(), USBEP0SendRAMPtr(), and + USBEP0SendROMPtr() are provided for this purpose. + + The USBTransferOnePacket() writes to the Buffer Descriptor Table (BDT) + entry associated with an endpoint buffer, and sets the UOWN bit, which + prepares the USB hardware to allow the transaction to complete. The + application firmware can use the USBHandleBusy() macro to check the + status of the transaction, to see if the data has been successfully + transmitted yet. + + + Typical Usage + + //make sure that the we are in the configured state + if(USBGetDeviceState() == CONFIGURED_STATE) + { + //make sure that the last transaction isn't busy by checking the handle + if(!USBHandleBusy(USBInHandle)) + { + //Write the new data that we wish to send to the host to the INPacket[] array + INPacket[0] = USEFUL_APPLICATION_VALUE1; + INPacket[1] = USEFUL_APPLICATION_VALUE2; + //INPacket[2] = ... (fill in the rest of the packet data) + + //Send the data contained in the INPacket[] array through endpoint "EP_NUM" + USBInHandle = USBTransferOnePacket(EP_NUM,IN_TO_HOST,(uint8_t*)&INPacket[0],sizeof(INPacket)); + } + } + + + Conditions: + Before calling USBTransferOnePacket(), the following should be true. + 1. The USB stack has already been initialized (USBDeviceInit() was called). + 2. A transaction is not already pending on the specified endpoint. This + is done by checking the previous request using the USBHandleBusy() + macro (see the typical usage example). + 3. The host has already sent a set configuration request and the + enumeration process is complete. + This can be checked by verifying that the USBGetDeviceState() + macro returns "CONFIGURED_STATE", prior to calling + USBTransferOnePacket(). + + Input: + uint8_t ep - The endpoint number that the data will be transmitted or + received on + uint8_t dir - The direction of the transfer + This value is either OUT_FROM_HOST or IN_TO_HOST + uint8_t* data - For IN transactions: pointer to the RAM buffer containing + the data to be sent to the host. For OUT transactions: pointer + to the RAM buffer that the received data should get written to. + uint8_t len - Length of the data needing to be sent (for IN transactions). + For OUT transactions, the len parameter should normally be set + to the endpoint size specified in the endpoint descriptor. + + Return Values: + USB_HANDLE - handle to the transfer. The handle is a pointer to + the BDT entry associated with this transaction. The + status of the transaction (ex: if it is complete or still + pending) can be checked using the USBHandleBusy() macro + and supplying the USB_HANDLE provided by + USBTransferOnePacket(). + + Remarks: + If calling the USBTransferOnePacket() function from within the USBCBInitEP() + callback function, the set configuration is still being processed and the + USBDeviceState may not be == CONFIGURED_STATE yet. In this special case, + the USBTransferOnePacket() may still be called, but make sure that the + endpoint has been enabled and initialized by the USBEnableEndpoint() + function first. + + *************************************************************************/ +USB_HANDLE USBTransferOnePacket(uint8_t ep,uint8_t dir,uint8_t* data,uint8_t len); + +/******************************************************************** + Function: + void USBStallEndpoint(uint8_t ep, uint8_t dir) + + Summary: + Configures the specified endpoint to send STALL to the host, the next + time the host tries to access the endpoint. + + PreCondition: + None + + Parameters: + uint8_t ep - The endpoint number that should be configured to send STALL. + uint8_t dir - The direction of the endpoint to STALL, either + IN_TO_HOST or OUT_FROM_HOST. + + Return Values: + None + + Remarks: + None + + *******************************************************************/ +void USBStallEndpoint(uint8_t ep, uint8_t dir); +/************************************************************************** + Function: + void USBCancelIO(uint8_t endpoint) + + Description: + This function cancels the transfers pending on the specified endpoint. + This function can only be used after a SETUP packet is received and + before that setup packet is handled. This is the time period in which + the EVENT_EP0_REQUEST is thrown, before the event handler function + returns to the stack. + + Precondition: + + Parameters: + uint8_t endpoint - the endpoint number you wish to cancel the transfers for + + Return Values: + None + + Remarks: + None + + **************************************************************************/ +void USBCancelIO(uint8_t endpoint); + +/************************************************************************** + Function: + void USBDeviceDetach(void) + + Summary: + This function configures the USB module to "soft detach" itself from + the USB host. + + Description: + This function configures the USB module to perform a "soft detach" + operation, by disabling the D+ (or D-) ~1.5k pull up resistor, which + lets the host know the device is present and attached. This will make + the host think that the device has been unplugged. This is potentially + useful, as it allows the USB device to force the host to re-enumerate + the device (on the firmware has re-enabled the USB module/pull up, by + calling USBDeviceAttach(), to "soft re-attach" to the host). + + Precondition: + Should only be called when USB_INTERRUPT is defined. See remarks + section if USB_POLLING mode option is being used (usb_config.h option). + + Additionally, this function should only be called from the main() loop + context. Do not call this function from within an interrupt handler, as + this function may modify global interrupt enable bits and settings. + + Parameters: + None + + Return Values: + None + + Remarks: + If the application firmware calls USBDeviceDetach(), it is strongly + recommended that the firmware wait at least >= 80ms before calling + USBDeviceAttach(). If the firmware performs a soft detach, and then + re-attaches too soon (ex: after a few micro seconds for instance), some + hosts may interpret this as an unexpected "glitch" rather than as a + physical removal/re-attachment of the USB device. In this case the host + may simply ignore the event without re-enumerating the device. To + ensure that the host properly detects and processes the device soft + detach/re-attach, it is recommended to make sure the device remains + detached long enough to mimic a real human controlled USB + unplug/re-attach event (ex: after calling USBDeviceDetach(), do not + call USBDeviceAttach() for at least 80+ms, preferably longer. + + Neither the USBDeviceDetach() or USBDeviceAttach() functions are blocking + or take long to execute. It is the application firmwares + responsibility for adding the 80+ms delay, when using these API + functions. + + Note: The Windows plug and play event handler processing is fairly + slow, especially in certain versions of Windows, and for certain USB + device classes. It has been observed that some device classes need to + provide even more USB detach dwell interval (before calling + USBDeviceAttach()), in order to work correctly after re-enumeration. + If the USB device is a CDC class device, it is recommended to wait + at least 1.5 seconds or longer, before soft re-attaching to the host, + to provide the plug and play event handler enough time to finish + processing the removal event, before the re-attach occurs. + + If the application is using the USB_POLLING mode option, then the + USBDeviceDetach() and USBDeviceAttach() functions are not available. + In this mode, the USB stack relies on the "#define USE_USB_BUS_SENSE_IO" + and "#define USB_BUS_SENSE" options in the + HardwareProfile � [platform name].h file. + + When using the USB_POLLING mode option, and the + "#define USE_USB_BUS_SENSE_IO" definition has been commented out, then + the USB stack assumes that it should always enable the USB module at + pretty much all times. Basically, anytime the application firmware + calls USBDeviceTasks(), the firmware will automatically enable the USB + module. This mode would typically be selected if the application was + designed to be a purely bus powered device. In this case, the + application is powered from the +5V VBUS supply from the USB port, so + it is correct and sensible in this type of application to power up and + turn on the USB module, at anytime that the microcontroller is + powered (which implies the USB cable is attached and the host is also + powered). + + In a self powered application, the USB stack is designed with the + intention that the user will enable the "#define USE_USB_BUS_SENSE_IO" + option in the HardwareProfile � [platform name].h file. When this + option is defined, then the USBDeviceTasks() function will automatically + check the I/O pin port value of the designated pin (based on the + #define USB_BUS_SENSE option in the HardwareProfile � [platform name].h + file), every time the application calls USBDeviceTasks(). If the + USBDeviceTasks() function is executed and finds that the pin defined by + the #define USB_BUS_SENSE is in a logic low state, then it will + automatically disable the USB module and tri-state the D+ and D- pins. + If however the USBDeviceTasks() function is executed and finds the pin + defined by the #define USB_BUS_SENSE is in a logic high state, then it + will automatically enable the USB module, if it has not already been + enabled. + + **************************************************************************/ +void USBDeviceDetach(void); + +/*DOM-IGNORE-BEGIN*/ +#if !defined(USB_INTERRUPT) + #define USBDeviceDetach() +#endif +/*DOM-IGNORE-END*/ + +/************************************************************************** + Function: + void USBDeviceAttach(void) + + Summary: + Checks if VBUS is present, and that the USB module is not already + initalized, and if so, enables the USB module so as to signal device + attachment to the USB host. + + Description: + This function indicates to the USB host that the USB device has been + attached to the bus. This function needs to be called in order for the + device to start to enumerate on the bus. + + Precondition: + Should only be called when USB_INTERRUPT is defined. Also, should only + be called from the main() loop context. Do not call USBDeviceAttach() + from within an interrupt handler, as the USBDeviceAttach() function + may modify global interrupt enable bits and settings. + + For normal USB devices: + Make sure that if the module was previously on, that it has been turned off + for a long time (ex: 100ms+) before calling this function to re-enable the module. + If the device turns off the D+ (for full speed) or D- (for low speed) ~1.5k ohm + pull up resistor, and then turns it back on very quickly, common hosts will sometimes + reject this event, since no human could ever unplug and re-attach a USB device in a + microseconds (or nanoseconds) timescale. The host could simply treat this as some kind + of glitch and ignore the event altogether. + Parameters: + None + + Return Values: + None + + Remarks: + See also the USBDeviceDetach() API function documentation. +****************************************************************************/ +void USBDeviceAttach(void); + +/*DOM-IGNORE-BEGIN*/ +#if !defined(USB_INTERRUPT) + #define USBDeviceAttach() +#endif +/*DOM-IGNORE-END*/ + + +/******************************************************************************* + Function: void USBCtrlEPAllowStatusStage(void); + + Summary: This function prepares the proper endpoint 0 IN or endpoint 0 OUT + (based on the controlTransferState) to allow the status stage packet + of a control transfer to complete. This function gets used + internally by the USB stack itself, but it may also be called from + the application firmware, IF the application firmware called + the USBDeferStatusStage() function during the initial processing + of the control transfer request. In this case, the application + must call the USBCtrlEPAllowStatusStage() once, after it has fully + completed processing and handling the data stage portion of the + request. + + If the application firmware has no need for delaying control + transfers, and therefore never calls USBDeferStatusStage(), then the + application firmware should not call USBCtrlEPAllowStatusStage(). + + Description: + + Conditions: + None + + Input: + + Return: + + Remarks: + None + *****************************************************************************/ +void USBCtrlEPAllowStatusStage(void); + + + +/******************************************************************************* + Function: void USBCtrlEPAllowDataStage(void); + + Summary: This function allows the data stage of either a host-to-device or + device-to-host control transfer (with data stage) to complete. + This function is meant to be used in conjunction with either the + USBDeferOUTDataStage() or USBDeferINDataStage(). If the firmware + does not call either USBDeferOUTDataStage() or USBDeferINDataStage(), + then the firmware does not need to manually call + USBCtrlEPAllowDataStage(), as the USB stack will call this function + instead. + + Description: + + Conditions: A control transfer (with data stage) should already be pending, + if the firmware calls this function. Additionally, the firmware + should have called either USBDeferOUTDataStage() or + USBDeferINDataStage() at the start of the control transfer, if + the firmware will be calling this function manually. + + Input: + + Return: + + Remarks: + *****************************************************************************/ +void USBCtrlEPAllowDataStage(void); + + +/******************************************************************************* + Function: void USBDeferOUTDataStage(void); + + Summary: This function will cause the USB hardware to continuously NAK the + OUT data packets sent from the host, during the data stage of a + device to host control transfer. This allows the firmware more time + to prepare the RAM buffer that will eventually be used to receive the + data from the host. This is also useful, if the firmware wishes to + receive the OUT data in a different context than what the + USBDeviceTasks() function executes at. + + Calling this function (macro) will assert ownership of the currently + pending control transfer. Therefore, the USB stack will not STALL + when it reaches the data stage of the control transfer, even if the + firmware has not (yet) called the USBEP0Receive() API function. + However, the application firmware must still (eventually, once it is + ready) call one of the aforementioned API function. + + Example Usage: + + 1. Host sends a SETUP packet to the device, requesting a host to + device control transfer, with data stage (OUT data packets). + 2. USBDeviceTasks() executes, and then calls the USBCBCheckOtherReq() + callback event handler. The USBCBCheckOtherReq() calls the + application specific/device class specific handler that detects + the type of control transfer. + 3. If the firmware needs more time before it wishes to receive the + first OUT data packet, or, if the firmware wishes to process the + command in a different context, then it may call + USBDeferOUTDataStage(), in the context of the + USBCBCheckOtherReq() handler function. + 4. If the firmware called USBDeferOUTDataStage() in step #3 above, + then the hardware will NAK the OUT data packets sent by the + host, for the OUT data stage. + 5. Once the firmware is ready, it should then call USBEP0Receive(), + to prepare the USB stack to receive the OUT data from the host, + and to write it to the user specified buffer. + 6. The firmware should now call USBCtrlEPAllowDataStage(). This + will allow the data stage to complete. Once all OUT data has + been received, the user callback function (provided by the + function pointer provided when calling USBEP0Receive()) will + get called. + 7. Once all data has been received from the host, the status stage + (a 0-byte IN packet) will complete automatically (assuming the + firmware did not call USBDeferStatusStage() during step #3). + + + Description: + + Conditions: Before calling USBDeferOUTDataStage(), the firmware should first + verify that the control transfer has a data stage, and that + it is of type host-to-device (OUT). + + Input: + + Return: + + Remarks: Section 9.2.6 of the official USB 2.0 specifications indicates that + the USB device must be able to receive all bytes and complete the + control transfer within a maximum of 5 seconds. + + If the firmware calls USBDeferOUTDataStage(), it must eventually call + USBEP0Receive(), and then call USBCtrlEPAllowDataStage(). If it does + not do this, the control transfer will never be able to complete. + This will break the USB connection, as the host needs to be able to + communicate over EP0, in order to perform basic tasks including + enumeration. + + The firmware should never call both USBDeferINDataStage() and + USBDeferOUTDataStage() during the same control transfer. These + functions are mutually exclusive (a control transfer with data stage + can never contain both IN and OUT data packets during the data stage). + *****************************************************************************/ +void USBDeferOUTDataStage(void); +extern volatile bool USBDeferOUTDataStagePackets; +/*DOM-IGNORE-BEGIN*/ +#define USBDeferOUTDataStage() {USBDeferOUTDataStagePackets = true; outPipes[0].info.bits.busy = 1;} +/*DOM-IGNORE-END*/ + +/******************************************************************************* + Function: void USBDeferStatusStage(void); + + Summary: Calling this function will prevent the USB stack from automatically + enabling the status stage for the currently pending control transfer + from completing immediately after all data bytes have been sent or + received. This is useful if a class handler or USB application + firmware project uses control transfers for sending/receiving data + over EP0, but requires time in order to finish processing and/or to + consume the data. + + For example: Consider an application which receives OUT data from the + USB host, through EP0 using control transfers. Now assume that this + application wishes to do something time consuming with this data (ex: + transmit it to and save it to an external EEPconst device, connected + via SPI/I2C/etc.). In this case, it would typically be desirable to + defer allowing the USB status stage of the control transfer to complete, + until after the data has been fully sent to the EEPconst device and saved. + + If the USB class handler firmware that processes the control transfer + SETUP packet determines that it will need extra time to complete the + control transfer, it may optionally call USBDeferStatusStage(). If it + does so, it is then the responsibility of the application firmware to + eventually call USBCtrlEPAllowStatusStage(), once the firmware has + finished processing the data associated with the control transfer. + + If the firmware call USBDeferStatusStage(), but never calls + USBCtrlEPAllowStatusStage(), then one of two possibilities will occur. + + 1. If the "USB_ENABLE_STATUS_STAGE_TIMEOUTS" option is commented in + usb_config.h, then the status stage of the control transfer will + never be able to complete. This is an error case and should be + avoided. + 2. If the "USB_ENABLE_STATUS_STAGE_TIMEOUTS" option is enabled in + usb_config.h, then the USBDeviceTasks() function will + automatically call USBCtrlEPAllowStatusStage(), after the + "USB_STATUS_STAGE_TIMEOUT" has elapsed, since the last quanta of + "progress" has occurred in the control transfer. Progress is + defined as the last successful transaction completing on EP0 IN or + EP0 OUT. + Although the timeouts feature allows the status stage to + [eventually] complete, it is still preferable to manually call + USBCtrlEPAllowStatusStage() after the application firmware has + finished processing/consuming the control transfer data, as this + will allow for much faster processing of control transfers, and + therefore much higher data rates and better user responsiveness. + Description: + + Conditions: + None + + Input: + + Return: + + Remarks: If this function is called, is should get called after the SETUP + packet has arrived (the control transfer has started), but before + the USBCtrlEPServiceComplete() function has been called by the USB + stack. Therefore, the normal place to call USBDeferStatusStage() + would be from within the USBCBCheckOtherReq() handler context. For + example, in a HID application using control transfers, the + USBDeferStatusStage() function would be called from within the + USER_GET_REPORT_HANDLER or USER_SET_REPORT_HANDLER functions. + *****************************************************************************/ +void USBDeferStatusStage(void); +extern volatile bool USBDeferStatusStagePacket; +/*DOM-IGNORE-BEGIN*/ +#define USBDeferStatusStage() {USBDeferStatusStagePacket = true;} +/*DOM-IGNORE-END*/ + + +/******************************************************************************* + Function: bool USBOUTDataStageDeferred(void); + + Summary: Returns true if a control transfer with OUT data stage is pending, + and the firmware has called USBDeferOUTDataStage(), but has not + yet called USBCtrlEPAllowDataStage(). + Returns false if a control transfer with OUT data stage is either + not pending, or the firmware did not call USBDeferOUTDataStage() + at the start of the control transfer. + + This function (macro) would typically be used in the case where the + USBDeviceTasks() function executes in the interrupt context (ex: + USB_INTERRUPT option selected in usb_config.h), but the firmware + wishes to take care of handling the data stage of the control transfer + in the main loop context. + + In this scenario, typical usage would be: + 1. Host starts a control transfer with OUT data stage. + 2. USBDeviceTasks() (in this scenario, interrupt context) executes. + 3. USBDeviceTasks() calls USBCBCheckOtherReq(), which in turn + determines that the control transfer is class specific, with + OUT data stage. + 4. The user code in USBCBCheckOtherReq() (also in interrupt context, + since it is called from USBDeviceTasks(), and therefore executes + at the same priority/context) calls USBDeferOUTDataStage(). + + 5. Meanwhile, in the main loop context, a polling handler may be + periodically checking if(USBOUTDataStageDeferred() == true). + Ordinarily, it would evaluate false, but when a control transfer + becomes pending, and after the USBDeferOUTDataStage() macro has + been called (ex: in the interrupt context), the if() statement + will evaluate true. In this case, the main loop context can then + take care of receiving the data, by calling USBEP0Receive() and + USBCtrlEPAllowDataStage(). + + Description: + + Conditions: + + Input: + + Return: + + Remarks: + *****************************************************************************/ +bool USBOUTDataStageDeferred(void); +/*DOM-IGNORE-BEGIN*/ +#define USBOUTDataStageDeferred() USBDeferOUTDataStagePackets +/*DOM-IGNORE-END*/ + +/******************************************************************************* + Function: void USBDeferINDataStage(void); + + Summary: This function will cause the USB hardware to continuously NAK the + IN token packets sent from the host, during the data stage of a + device to host control transfer. This allows the firmware more time + to process and prepare the IN data packets that will eventually be + sent to the host. This is also useful, if the firmware needs to + process/prepare the IN data in a different context than what the + USBDeviceTasks() function executes at. + + Calling this function (macro) will assert ownership of the currently + pending control transfer. Therefore, the USB stack will not STALL + when it reaches the data stage of the control transfer, even if the + firmware has not (yet) called the USBEP0SendRAMPtr() or + USBEP0SendROMPtr() API function. However, the application firmware + must still (eventually, once it is ready) call one of the + aforementioned API functions. + + Example Usage: + + 1. Host sends a SETUP packet to the device, requesting a device to + host control transfer, with data stage. + 2. USBDeviceTasks() executes, and then calls the USBCBCheckOtherReq() + callback event handler. The USBCBCheckOtherReq() calls the + application specific/device class specific handler that detects + the type of control transfer. + 3. If the firmware needs more time to prepare the first IN data packet, + or, if the firmware wishes to process the command in a different + context (ex: if USBDeviceTasks() executes as an interrupt handler, + but the IN data stage data needs to be prepared in the main loop + context), then it may call USBDeferINDataStage(), in the context + of the USBCBCheckOtherReq() handler function. + 4. If the firmware called USBDeferINDataStage() in step #3 above, + then the hardware will NAK the IN token packets sent by the + host, for the IN data stage. + 5. Once the firmware is ready, and has successfully prepared the + data to be sent to the host in fulfillment of the control + transfer, it should then call USBEP0SendRAMPtr() or + USBEP0SendROMPtr(), to prepare the USB stack to know how many + bytes to send to the host, and from what source location. + 6. The firmware should now call USBCtrlEPAllowDataStage(). This + will allow the data stage to complete. The USB stack will send + the data buffer specified by the USBEP0SendRAMPtr() or + USBEP0SendROMPtr() function, when it was called. + 7. Once all data has been sent to the host, or if the host performs + early termination, the status stage (a 0-byte OUT packet) will + complete automatically (assuming the firmware did not call + USBDeferStatusStage() during step #3). + + + Description: + + Conditions: Before calling USBDeferINDataStage(), the firmware should first + verify that the control transfer has a data stage, and that + it is of type device-to-host (IN). + + Input: + + Return: + + Remarks: Section 9.2.6 of the official USB 2.0 specifications indicates that + the USB device must return the first IN data packet within 500ms + of the start of the control transfer. In order to meet this + specification, the firmware must call USBEP0SendRAMPtr() or + USBEP0SendROMPtr(), and then call USBCtrlEPAllowDataStage(), in + less than 500ms from the start of the control transfer. + + If the firmware calls USBDeferINDataStage(), it must eventually call + USBEP0SendRAMPtr() or USBEP0SendROMPtr(), and then call + USBCtrlEPAllowDataStage(). If it does not do this, the control + transfer will never be able to complete. + + The firmware should never call both USBDeferINDataStage() and + USBDeferOUTDataStage() during the same control transfer. These + functions are mutually exclusive (a control transfer with data stage + can never contain both IN and OUT data packets during the data stage). + *****************************************************************************/ +void USBDeferINDataStage(void); +extern volatile bool USBDeferINDataStagePackets; +/*DOM-IGNORE-BEGIN*/ +#define USBDeferINDataStage() {USBDeferINDataStagePackets = true; inPipes[0].info.bits.busy = 1;} +/*DOM-IGNORE-END*/ + + + +/******************************************************************************* + Function: bool USBINDataStageDeferred(void); + + Summary: Returns true if a control transfer with IN data stage is pending, + and the firmware has called USBDeferINDataStage(), but has not + yet called USBCtrlEPAllowDataStage(). + Returns false if a control transfer with IN data stage is either + not pending, or the firmware did not call USBDeferINDataStage() + at the start of the control transfer. + + This function (macro) would typically be used in the case where the + USBDeviceTasks() function executes in the interrupt context (ex: + USB_INTERRUPT option selected in usb_config.h), but the firmware + wishes to take care of handling the data stage of the control transfer + in the main loop context. + + In this scenario, typical usage would be: + 1. Host starts a control transfer with IN data stage. + 2. USBDeviceTasks() (in this scenario, interrupt context) executes. + 3. USBDeviceTasks() calls USBCBCheckOtherReq(), which in turn + determines that the control transfer is class specific, with + IN data stage. + 4. The user code in USBCBCheckOtherReq() (also in interrupt context, + since it is called from USBDeviceTasks(), and therefore executes + at the same priority/context) calls USBDeferINDataStage(). + + 5. Meanwhile, in the main loop context, a polling handler may be + periodically checking if(USBINDataStageDeferred() == true). + Ordinarily, it would evaluate false, but when a control transfer + becomes pending, and after the USBDeferINDataStage() macro has + been called (ex: in the interrupt context), the if() statement + will evaluate true. In this case, the main loop context can then + take care of sending the data (when ready), by calling + USBEP0SendRAMPtr() or USBEP0SendROMPtr() and + USBCtrlEPAllowDataStage(). + + Description: + + Conditions: + + Input: + + Return: + + Remarks: + *****************************************************************************/ +bool USBINDataStageDeferred(void); +/*DOM-IGNORE-BEGIN*/ +#define USBINDataStageDeferred() USBDeferINDataStagePackets +/*DOM-IGNORE-END*/ + + + +/******************************************************************** + Function: + bool USBGetRemoteWakeupStatus(void) + + Summary: + This function indicates if remote wakeup has been enabled by the host. + Devices that support remote wakeup should use this function to + determine if it should send a remote wakeup. + + Description: + This function indicates if remote wakeup has been enabled by the host. + Devices that support remote wakeup should use this function to + determine if it should send a remote wakeup. + + If a device does not support remote wakeup (the Remote wakeup bit, bit + 5, of the bmAttributes field of the Configuration descriptor is set to + 1), then it should not send a remote wakeup command to the PC and this + function is not of any use to the device. If a device does support + remote wakeup then it should use this function as described below. + + If this function returns false and the device is suspended, it should + not issue a remote wakeup (resume). + + If this function returns true and the device is suspended, it should + issue a remote wakeup (resume). + + A device can add remote wakeup support by having the _RWU symbol added + in the configuration descriptor (located in the usb_descriptors.c file + in the project). This done in the 8th byte of the configuration + descriptor. For example: + + + const uint8_t configDescriptor1[]={ + 0x09, // Size + USB_DESCRIPTOR_CONFIGURATION, // descriptor type + DESC_CONFIG_WORD(0x0022), // Total length + 1, // Number of interfaces + 1, // Index value of this cfg + 0, // Configuration string index + _DEFAULT | _SELF | _RWU, // Attributes, see usb_device.h + 50, // Max power consumption in 2X mA(100mA) + + //The rest of the configuration descriptor should follow + + + For more information about remote wakeup, see the following section of + the USB v2.0 specification available at www.usb.org: + * Section 9.2.5.2 + * Table 9-10 + * Section 7.1.7.7 + * Section 9.4.5 + + Conditions: + None + + Return Values: + true - Remote Wakeup has been enabled by the host + false - Remote Wakeup is not currently enabled + + Remarks: + None + + *******************************************************************/ +bool USBGetRemoteWakeupStatus(void); +/*DOM-IGNORE-BEGIN*/ +#define USBGetRemoteWakeupStatus() RemoteWakeup +/*DOM-IGNORE-END*/ + +/*************************************************************************** + Function: + USB_DEVICE_STATE USBGetDeviceState(void) + + Summary: + This function will return the current state of the device on the USB. + This function should return CONFIGURED_STATE before an application + tries to send information on the bus. + Description: + This function returns the current state of the device on the USB. This + \function is used to determine when the device is ready to communicate + on the bus. Applications should not try to send or receive data until + this function returns CONFIGURED_STATE. + + It is also important that applications yield as much time as possible + to the USBDeviceTasks() function as possible while the this function + \returns any value between ATTACHED_STATE through CONFIGURED_STATE. + + For more information about the various device states, please refer to + the USB specification section 9.1 available from www.usb.org. + + Typical usage: + + void main(void) + { + USBDeviceInit() + while(1) + { + USBDeviceTasks(); + if((USBGetDeviceState() \< CONFIGURED_STATE) || + (USBIsDeviceSuspended() == true)) + { + //Either the device is not configured or we are suspended + // so we don't want to do execute any application code + continue; //go back to the top of the while loop + } + else + { + //Otherwise we are free to run user application code. + UserApplication(); + } + } + } + + Conditions: + None + Return Values: + USB_DEVICE_STATE - the current state of the device on the bus + + Remarks: + None + ***************************************************************************/ +USB_DEVICE_STATE USBGetDeviceState(void); +/*DOM-IGNORE-BEGIN*/ +#define USBGetDeviceState() USBDeviceState +/*DOM-IGNORE-END*/ + + + +/*************************************************************************** + Function: + bool USBGetSuspendState(void) + + Summary: + This function indicates if the USB port that this device is attached to is + currently suspended. When suspended, it will not be able to transfer data + over the bus. + Description: + This function indicates if the USB port that this device is attached to is + currently suspended. When suspended, it will not be able to transfer data + over the bus. + This function can be used by the application to skip over section of + code that do not need to execute if the device is unable to send data + over the bus. This function can also be used to help determine when it is + legal to perform USB remote wakeup signaling, for devices supporting this + feature. + + Typical usage: + + void main(void) + { + USBDeviceInit() + while(1) + { + USBDeviceTasks(); + if((USBGetDeviceState() \< CONFIGURED_STATE) || + (USBGetSuspendState() == true)) + { + //Either the device is not configured or we are suspended + // so we don't want to do execute any application code + continue; //go back to the top of the while loop + } + else + { + //Otherwise we are free to run user application code. + UserApplication(); + } + } + } + + Conditions: + None + Return Values: + true - the USB port this device is attached to is suspended. + false - the USB port this device is attached to is not suspended. + Remarks: + This function is the same as USBIsBusSuspended(). + ***************************************************************************/ +bool USBGetSuspendState(void); +/*DOM-IGNORE-BEGIN*/ +#define USBGetSuspendState() USBBusIsSuspended +/*DOM-IGNORE-END*/ + +/******************************************************************************* + Function: + bool USBIsDeviceSuspended(void) + + Summary: + This function indicates if the USB module is in suspend mode. + + Description: + This function indicates if the USB module is in suspend mode. This function + does NOT indicate that a suspend request has been received. It only + reflects the state of the USB module. + + Typical Usage: + + if(USBIsDeviceSuspended() == true) + { + return; + } + // otherwise do some application specific tasks + + + Conditions: + None + Input: + None + Return: + None + Remarks: + None + *****************************************************************************/ +bool USBIsDeviceSuspended(void); +/*DOM-IGNORE-BEGIN*/ +#define USBIsDeviceSuspended() USBSuspendControl +/*DOM-IGNORE-END*/ + + +/******************************************************************************* + Function: + bool USBIsBusSuspended(void); + + Summary: + This function indicates if the USB bus is in suspend mode. + + Description: + This function indicates if the USB bus is in suspend mode. This function + is typically used for checking if the conditions are consistent with + performing a USB remote wakeup sequence. + + Typical Usage: + + if((USBIsBusSuspended() == true) && (USBGetRemoteWakeupStatus() == true)) + { + //Check if some stimulus occured, which will be used as the wakeup source + if(sw3 == 0) + { + USBCBSendResume(); //Send the remote wakeup signalling to the host + } + } + // otherwise do some other application specific tasks + + + Conditions: + None + Input: + None + Return: + None + Remarks: + The USBIsBusSuspended() function relies on the USBBusIsSuspended boolean + variable, which gets updated by the USBDeviceTasks() function. Therefore, + in order to be sure the return value is not "stale", it is suggested to make + sure USBDeviceTasks() has executed recently (if using USB polling mode). + *****************************************************************************/ +bool USBIsBusSuspended(void); +/*DOM-IGNORE-BEGIN*/ +#define USBIsBusSuspended() USBBusIsSuspended +/*DOM-IGNORE-END*/ + +/******************************************************************************* + Function: + void USBSoftDetach(void); + + Summary: + This function performs a detach from the USB bus via software. + + Description: + This function performs a detach from the USB bus via software. + + Conditions: + None + Input: + None + Return: + None + Remarks: + Caution should be used when detaching from the bus. Some PC drivers and + programs may require additional time after a detach before a device can be + reattached to the bus. + *****************************************************************************/ +void USBSoftDetach(void); +/*DOM-IGNORE-BEGIN*/ +#define USBSoftDetach() U1CON = 0; U1IE = 0; USBDeviceState = DETACHED_STATE; +/*DOM-IGNORE-END*/ + + +/************************************************************************* + Function: + bool USBHandleBusy(USB_HANDLE handle) + + Summary: + Checks to see if the input handle is busy + + Description: + Checks to see if the input handle is busy + + Typical Usage + + //make sure that the last transfer isn't busy by checking the handle + if(!USBHandleBusy(USBGenericInHandle)) + { + //Send the data contained in the INPacket[] array out on + // endpoint USBGEN_EP_NUM + USBGenericInHandle = USBGenWrite(USBGEN_EP_NUM,(uint8_t*)&INPacket[0],sizeof(INPacket)); + } + + + Conditions: + None + Input: + USB_HANDLE handle - handle of the transfer that you want to check the + status of + Return Values: + true - The specified handle is busy + false - The specified handle is free and available for a transfer + Remarks: + None + *************************************************************************/ +bool USBHandleBusy(USB_HANDLE handle); +/*DOM-IGNORE-BEGIN*/ +#if defined(__XC8__) + #define USBHandleBusy(handle) ((handle != 0x0000) && ((*(volatile uint8_t*)handle & _USIE) != 0x00)) +#else + #define USBHandleBusy(handle) (handle==0?0:((volatile BDT_ENTRY*)handle)->STAT.UOWN) +#endif +/*DOM-IGNORE-END*/ + +/******************************************************************** + Function: + uint16_t USBHandleGetLength(USB_HANDLE handle) + + Summary: + Retrieves the length of the destination buffer of the input + handle + + Description: + Retrieves the length of the destination buffer of the input + handle + + PreCondition: + None + + Parameters: + USB_HANDLE handle - the handle to the transfer you want the + address for. + + Return Values: + uint16_t - length of the current buffer that the input handle + points to. If the transfer is complete then this is the + length of the data transmitted or the length of data + actually received. + + Remarks: + None + + *******************************************************************/ +uint16_t USBHandleGetLength(USB_HANDLE handle); +/*DOM-IGNORE-BEGIN*/ +#define USBHandleGetLength(handle) (((volatile BDT_ENTRY*)handle)->CNT) +/*DOM-IGNORE-END*/ + +/******************************************************************** + Function: + uint16_t USBHandleGetAddr(USB_HANDLE) + + Summary: + Retrieves the address of the destination buffer of the input + handle + + Description: + Retrieves the address of the destination buffer of the input + handle + + PreCondition: + None + + Parameters: + USB_HANDLE handle - the handle to the transfer you want the + address for. + + Return Values: + uint16_t - address of the current buffer that the input handle + points to. + + Remarks: + None + + *******************************************************************/ +uint16_t USBHandleGetAddr(USB_HANDLE); +/*DOM-IGNORE-BEGIN*/ +#define USBHandleGetAddr(handle) ConvertToVirtualAddress((((volatile BDT_ENTRY*)handle)->ADR)) +/*DOM-IGNORE-END*/ + + +/******************************************************************** + Function: + USB_HANDLE USBGetNextHandle(uint8_t ep_num, uint8_t ep_dir) + Summary: + Retrieves the handle to the next endpoint BDT entry that the + USBTransferOnePacket() will use. + Description: + Retrieves the handle to the next endpoint BDT that the + USBTransferOnePacket() will use. Useful for initialization and when + ping pong buffering will be used on application endpoints. + PreCondition: + Will return NULL if the USB device has not yet been configured/the + endpoint specified has not yet been initialized by USBEnableEndpoint(). + Parameters: + uint8_t ep_num - The endpoint number to get the handle for (valid + values are 1-15, 0 is not a valid input value for this API) + uint8_t ep_dir - The endpoint direction associated with the endpoint number + to get the handle for (valid values are OUT_FROM_HOST and IN_TO_HOST). + Return Values: + USB_HANDLE - Returns the USB_HANDLE (a pointer) to the BDT that will be + used next time the USBTransferOnePacket() function is called, for the + given ep_num and ep_dir + Remarks: + This API is useful for initializing USB_HANDLEs during initialization of + the application firmware. It is also useful when ping-pong buffering is + enabled, and the application firmware wishes to arm both the even and odd + BDTs for an endpoint simultaneously. In this case, the application + firmware for sending data to the host would typically be something like + follows: + + + USB_HANDLE Handle1; + USB_HANDLE Handle2; + USB_HANDLE* pHandle = &Handle1; + uint8_t UserDataBuffer1[64]; + uint8_t UserDataBuffer2[64]; + uint8_t* pDataBuffer = &UserDataBuffer1[0]; + + //Add some code that loads UserDataBuffer1[] with useful data to send, + //using the pDataBuffer pointer, for example: + //for(i = 0; i < 64; i++) + //{ + // *pDataBuffer++ = [useful data value]; + //} + + //Check if the next USB endpoint BDT is available + if(!USBHandleBusy(USBGetNextHandle(ep_num, IN_TO_HOST)) + { + //The endpoint is available. Send the data. + *pHandle = USBTransferOnePacket(ep_num, ep_dir, pDataBuffer, bytecount); + //Toggle the handle and buffer pointer for the next transaction + if(pHandle == &Handle1) + { + pHandle = &Handle2; + pDataBuffer = &UserDataBuffer2[0]; + } + else + { + pHandle = &Handle1; + pDataBuffer = &UserDataBuffer1[0]; + } + } + + //The firmware can then load the next data buffer (in this case + //UserDataBuffer2)with useful data, and send it using the same + //process. For example: + + //Add some code that loads UserDataBuffer2[] with useful data to send, + //using the pDataBuffer pointer, for example: + //for(i = 0; i < 64; i++) + //{ + // *pDataBuffer++ = [useful data value]; + //} + + //Check if the next USB endpoint BDT is available + if(!USBHandleBusy(USBGetNextHandle(ep_num, IN_TO_HOST)) + { + //The endpoint is available. Send the data. + *pHandle = USBTransferOnePacket(ep_num, ep_dir, pDataBuffer, bytecount); + //Toggle the handle and buffer pointer for the next transaction + if(pHandle == &Handle1) + { + pHandle = &Handle2; + pDataBuffer = &UserDataBuffer2[0]; + } + else + { + pHandle = &Handle1; + pDataBuffer = &UserDataBuffer1[0]; + } + } + + + *******************************************************************/ +USB_HANDLE USBGetNextHandle(uint8_t ep_num, uint8_t ep_dir); +/*DOM-IGNORE-BEGIN*/ +#define USBGetNextHandle(ep_num, ep_dir) ((ep_dir == OUT_FROM_HOST)?((USB_HANDLE)pBDTEntryOut[ep_num]):((USB_HANDLE)pBDTEntryIn[ep_num])) +/*DOM-IGNORE-END*/ + +/******************************************************************** + Function: + void USBEP0Transmit(uint8_t options) + + Summary: + Sets the address of the data to send over the + control endpoint + + PreCondition: + None + + Parameters: + options - the various options that you want + when sending the control data. Options are: + USB_EP0_ROM + USB_EP0_RAM + USB_EP0_BUSY + USB_EP0_INCLUDE_ZERO + USB_EP0_NO_DATA + USB_EP0_NO_OPTIONS + + Return Values: + None + + Remarks: + None + + *******************************************************************/ +void USBEP0Transmit(uint8_t options); +/*DOM-IGNORE-BEGIN*/ +#define USBEP0Transmit(options) inPipes[0].info.Val = options | USB_EP0_BUSY +/*DOM-IGNORE-END*/ + +/************************************************************************* + Function: + void USBEP0SendRAMPtr(uint8_t* src, uint16_t size, uint8_t Options) + + Summary: + Sets the source, size, and options of the data you wish to send from a + RAM source + Conditions: + None + Input: + src - address of the data to send + size - the size of the data needing to be transmitted + options - the various options that you want when sending the control + data. Options are\: + * USB_EP0_ROM + * USB_EP0_RAM + * USB_EP0_BUSY + * USB_EP0_INCLUDE_ZERO + * USB_EP0_NO_DATA + * USB_EP0_NO_OPTIONS + Remarks: + None + *************************************************************************/ +void USBEP0SendRAMPtr(uint8_t* src, uint16_t size, uint8_t Options); +/*DOM-IGNORE-BEGIN*/ +#define USBEP0SendRAMPtr(src,size,options) {\ + inPipes[0].pSrc.bRam = src;\ + inPipes[0].wCount.Val = size;\ + inPipes[0].info.Val = options | USB_EP0_BUSY | USB_EP0_RAM;\ + } +/*DOM-IGNORE-END*/ + +/************************************************************************** + Function: + void USBEP0SendROMPtr(uint8_t* src, uint16_t size, uint8_t Options) + + Summary: + Sets the source, size, and options of the data you wish to send from a + const source + Conditions: + None + Input: + src - address of the data to send + size - the size of the data needing to be transmitted + options - the various options that you want when sending the control + data. Options are\: + * USB_EP0_ROM + * USB_EP0_RAM + * USB_EP0_BUSY + * USB_EP0_INCLUDE_ZERO + * USB_EP0_NO_DATA + * USB_EP0_NO_OPTIONS + Remarks: + None + **************************************************************************/ +void USBEP0SendROMPtr(uint8_t* src, uint16_t size, uint8_t Options); +/*DOM-IGNORE-BEGIN*/ +#define USBEP0SendROMPtr(src,size,options) {\ + inPipes[0].pSrc.bRom = src;\ + inPipes[0].wCount.Val = size;\ + inPipes[0].info.Val = options | USB_EP0_BUSY | USB_EP0_ROM;\ + } +/*DOM-IGNORE-END*/ + +/*************************************************************************** + Function: + void USBEP0Receive(uint8_t* dest, uint16_t size, void (*function)) + Summary: + Sets the destination, size, and a function to call on the completion of + the next control write. + Conditions: + None + Input: + dest - address of where the incoming data will go (make sure that this + address is directly accessible by the USB module for parts with + dedicated USB RAM this address must be in that space) + size - the size of the data being received (is almost always going to be + presented by the preceeding setup packet SetupPkt.wLength) + (*function) - a function that you want called once the data is received. If + this is specified as NULL then no function is called. + Remarks: + None + ***************************************************************************/ +void USBEP0Receive(uint8_t* dest, uint16_t size, void (*function)); +/*DOM-IGNORE-BEGIN*/ +#define USBEP0Receive(dest,size,function) {outPipes[0].pDst.bRam = dest;outPipes[0].wCount.Val = size;outPipes[0].pFunc = function;outPipes[0].info.bits.busy = 1; } +/*DOM-IGNORE-END*/ + +/******************************************************************** + Function: + USB_HANDLE USBTxOnePacket(uint8_t ep, uint8_t* data, uint16_t len) + + Summary: + Sends the specified data out the specified endpoint + + PreCondition: + None + + Parameters: + ep - the endpoint number you want to send the data out of + data - pointer to a user buffer that contains the data that you wish to + send to the host. Note: This RAM buffer must be accessible by + the USB module. + len - the number of bytes of data that you wish to send to the host, + in the next transaction on this endpoint. Note: this value + should always be less than or equal to the endpoint size, as + specified in the USB endpoint descriptor. + + Return Values: + USB_HANDLE - Returns a pointer to the BDT entry associated with the + transaction. The firmware can check for completion + of the transaction by using the USBHandleBusy() function, + using the returned USB_HANDLE value. + + Remarks: + None + + *******************************************************************/ +USB_HANDLE USBTxOnePacket(uint8_t ep, uint8_t* data, uint16_t len); +/*DOM-IGNORE-BEGIN*/ +#define USBTxOnePacket(ep,data,len) USBTransferOnePacket(ep,IN_TO_HOST,data,len) +/*DOM-IGNORE-END*/ + +/******************************************************************** + Function: + USB_HANDLE USBRxOnePacket(uint8_t ep, uint8_t* data, uint16_t len) + + Summary: + Receives the specified data out the specified endpoint + + PreCondition: + None + + Parameters: + ep - The endpoint number you want to receive the data on. + data - Pointer to a user buffer where the data will go when + it arrives from the host. Note: This RAM must be USB module + accessible. + len - The len parameter should always be set to the maximum endpoint packet + size, specified in the USB descriptor for this endpoint. The host + may send <= the number of bytes as the endpoint size in the endpoint + descriptor. After the transaction is complete, the application + firmware can call USBHandleGetLength() to determine how many bytes + the host actually sent in the last transaction on this endpoint. + + Return Values: + USB_HANDLE - Returns a pointer to the BDT entry associated with the + transaction. The firmware can check for completion + of the transaction by using the USBHandleBusy() function, + using the returned USB_HANDLE value. + + Remarks: + None + + *******************************************************************/ +USB_HANDLE USBRxOnePacket(uint8_t ep, uint8_t* data, uint16_t len); +/*DOM-IGNORE-BEGIN*/ +#define USBRxOnePacket(ep,data,len) USBTransferOnePacket(ep,OUT_FROM_HOST,data,len) +/*DOM-IGNORE-END*/ + +/******************************************************************************* + Function: + bool USB_APPLICATION_EVENT_HANDLER(uint8_t address, USB_EVENT event, void *pdata, uint16_t size); + + Summary: + This function is called whenever the USB stack wants to notify the user of + an event. + + Description: + This function is called whenever the USB stack wants to notify the user of + an event. This function should be implemented by the user. + + Example Usage: + Conditions: + None + + Input: + uint8_t address - the address of the device when the event happened + uint8_t event - The event input specifies which event happened. The + possible options are listed in the USB_DEVICE_STACK_EVENTS + enumeration. + + Return: + None + Remarks: + None + *****************************************************************************/ +bool USB_APPLICATION_EVENT_HANDLER(uint8_t address, USB_EVENT event, void *pdata, uint16_t size); + + + + +/************************************************************************** + Function: + void USBIncrement1msInternalTimers(void) + + Description: + This function increments internal 1ms time base counters, which are + useful for application code (that can use a 1ms time base/counter), and + for certain USB event timing specific purposes. + + In USB full speed applications, the application code does not need to (and should + not) explicitly call this function, as the USBDeviceTasks() function will + automatically call this function whenever a 1ms time interval has elapsed + (assuming the code is calling USBDeviceTasks() frequently enough in USB_POLLING + mode, or that USB interrupts aren't being masked for more than 1ms at a time + in USB_INTERRUPT mode). + + In USB low speed applications, the application firmware is responsible for + periodically calling this function at a ~1ms rate. This can be done using + a general purpose microcontroller timer set to interrupt every 1ms for example. + If the low speed application code does not call this function, the internal timers + will not increment, and the USBGet1msTickCount() API function will not be available. + Additionally, certain USB stack operations (like control transfer timeouts) + may be unavailable. + + Precondition: + This function should be called only after USBDeviceInit() has been + called (at least once at the start of the application). Ordinarily, + application code should never call this function, unless it is a low speed + USB device. + + Parameters: + None + + Return Values: + None + + Remarks: + This function does not need to be called during USB suspend conditions, when + the USB module/stack is disabled, or when the USB cable is detached from the host. + ***************************************************************************/ +void USBIncrement1msInternalTimers(void); + + +/************************************************************************** + Function: + uint32_t USBGet1msTickCount(void) + + Description: + This function retrieves a 32-bit unsigned integer that normally increments by + one every one millisecond. The count value starts from zero when the + USBDeviceInit() function is first called. See the remarks section for + details on special circumstances where the tick count will not increment. + + Precondition: + This function should be called only after USBDeviceInit() has been + called (at least once at the start of the application). + + Parameters: + None + + Return Values: + uint32_t representing the approximate millisecond count, since the time the + USBDeviceInit() function was first called. + + Remarks: + On 8-bit USB full speed devices, the internal counter is incremented on + every SOF packet detected. Therefore, it will not increment during suspend + or when the USB cable is detached. However, on 16-bit devices, the T1MSECIF + hardware interrupt source is used to increment the internal counter. Therefore, + on 16-bit devices, the count continue to increment during USB suspend or + detach events, so long as the application code has not put the microcontroller + to sleep during these events, and the application firmware is regularly + calling the USBDeviceTasks() function (or allowing it to execute, if using + USB_INTERRUPT mode operation). + + In USB low speed applications, the host does not broadcast SOF packets to + the device, so the application firmware becomes responsible for calling + USBIncrement1msInternalTimers() periodically (ex: from a general purpose + timer interrupt handler), or else the returned value from this function will + not increment. + + Prior to calling USBDeviceInit() for the first time the returned value will + be unpredictable. + + This function is USB_INTERRUPT mode safe and may be called from main loop + code without risk of retrieving a partially updated 32-bit number. + + However, this value only increments when the USBDeviceTasks() function is allowed + to execute. If USB_INTERRUPT mode is used, it is allowable to block on this + function. If however USB_POLLING mode is used, one must not block on this + function without also calling USBDeviceTasks() continuously for the blocking + duration (since the USB stack must still be allowed to execute, and the USB + stack is also responsible for updating the tick counter internally). + + If the application is operating in USB_POLLING mode, this function should + only be called from the main loop context, and not from an interrupt handler, + as the returned value could be incorrect, if the main loop context code was in + the process of updating the internal count at the moment of the interrupt event. + ***************************************************************************/ +uint32_t USBGet1msTickCount(void); + + + + +/************************************************************************** + Function: + uint8_t USBGetTicksSinceSuspendEnd(void); + + Description: + This function retrieves a 8-bit unsigned byte that represents the number + of milliseconds that have elapsed since the end of a USB suspend event. + The value saturates at 255. + + Precondition: + This function should be called only after USBDeviceInit() has been + called (at least once at the start of the application). + + Parameters: + None + + Return Values: + uint32_t representing the current millisecond count, since the time the + USBDeviceInit() function was first called, while the USB bus was non-suspended + and the device was attached to an active host. + + Remarks: + This function does not increment during USB suspend conditions, or when the USB + cable is detached from the host. Prior to calling USBDeviceInit() for the + first time the returned value will be unpredictable. + + This function is USB_INTERRUPT mode safe and may be called from main loop + code without risk of retrieving a partially updated 32-bit number. + + However, this value only increments when the USBDeviceTasks() function is allowed + to execute. If USB_INTERRUPT mode is used, it is allowable to block on this + function. If however USB_POLLING mode is used, one must not block on this + function without also calling USBDeviceTasks() continuously for the blocking + duration (since the USB stack must still be allowed to execute, and the USB + stack is also responsible for updating the tick counter internally). + ***************************************************************************/ +uint8_t USBGetTicksSinceSuspendEnd(void); +/*DOM-IGNORE-BEGIN*/ +#define USBGetTicksSinceSuspendEnd() USBTicksSinceSuspendEnd +/*DOM-IGNORE-END*/ + + + +/** Section: MACROS ******************************************************/ + +/* The DESC_CONFIG_WORD() macro is implemented for convenience. Since the + configuration descriptor array is a uint8_t array, each entry needs to be a + uint8_t in LSB format. The DESC_CONFIG_WORD() macro breaks up a uint16_t into + the appropriate uint8_t entries in LSB. + Typical Usage: + + const uint8_t configDescriptor1[]={ + 0x09, // Size of this descriptor in bytes + USB_DESCRIPTOR_CONFIGURATION, // CONFIGURATION descriptor type + DESC_CONFIG_WORD(0x0022), // Total length of data for this cfg + +*/ +#define DESC_CONFIG_WORD(a) (a&0xFF),((a>>8)&0xFF) + +/* The DESC_CONFIG_uint32_t() macro is implemented for convenience. Since the + configuration descriptor array is a uint8_t array, each entry needs to be a + uint8_t in LSB format. The DESC_CONFIG_uint32_t() macro breaks up a uint32_t into + the appropriate uint8_t entries in LSB. +*/ +#define DESC_CONFIG_uint32_t(a) (a&0xFF),((a>>8)&0xFF),((a>>16)&0xFF),((a>>24)&0xFF) + +/* The DESC_CONFIG_uint8_t() macro is implemented for convenience. The + DESC_CONFIG_uint8_t() macro provides a consistent macro for use with a byte + when generating a configuration descriptor when using either the + DESC_CONFIG_WORD() or DESC_CONFIG_uint32_t() macros. +*/ +#define DESC_CONFIG_uint8_t(a) (a) + + + + + + + + + + + + + + + + +/* DOM-IGNORE-BEGIN */ +/******************************************************************************* +******************************************************************************** +******************************************************************************** + This section contains implementation specific information that may vary + between releases as the implementation needs to change. This section is + included for compilation reasons only. +******************************************************************************** +******************************************************************************** +*******************************************************************************/ + +#if defined(USB_POLLING) + #define USB_VOLATILE +#else + #define USB_VOLATILE volatile +#endif + +#define CTRL_TRF_RETURN void +#define CTRL_TRF_PARAMS void + +typedef union +{ + uint16_t Val; + uint8_t v[2]; + struct + { + uint8_t LB; + uint8_t HB; + } byte; +} uint16_t_VAL; + +// Definition of the PIPE structure +// This structure is used to keep track of data that is sent out +// of the stack automatically. +typedef struct __attribute__ ((packed)) +{ + union __attribute__ ((packed)) + { + //Various options of pointers that are available to + // get the data from + uint8_t *bRam; + const uint8_t *bRom; + uint16_t *wRam; + const uint16_t *wRom; + }pSrc; + union __attribute__ ((packed)) + { + struct __attribute__ ((packed)) + { + //is this transfer from RAM or const? + uint8_t ctrl_trf_mem :1; + uint8_t reserved :5; + //include a zero length packet after + //data is done if data_size%ep_size = 0? + uint8_t includeZero :1; + //is this PIPE currently in use + uint8_t busy :1; + }bits; + uint8_t Val; + }info; + uint16_t_VAL __attribute__((aligned)) wCount; +}IN_PIPE; + +extern USB_VOLATILE IN_PIPE inPipes[]; + +typedef struct __attribute__ ((packed)) +{ + union __attribute__ ((packed)) + { + //Various options of pointers that are available to + // get the data from + uint8_t *bRam; + uint16_t *wRam; + }pDst; + union __attribute__ ((packed)) + { + struct __attribute__ ((packed)) + { + uint8_t reserved :7; + //is this PIPE currently in use + uint8_t busy :1; + }bits; + uint8_t Val; + }info; + uint16_t_VAL wCount; + CTRL_TRF_RETURN (*pFunc)(CTRL_TRF_PARAMS); +}OUT_PIPE; + +extern USB_VOLATILE bool RemoteWakeup; +extern USB_VOLATILE bool USBBusIsSuspended; +extern USB_VOLATILE USB_DEVICE_STATE USBDeviceState; +extern USB_VOLATILE uint8_t USBActiveConfiguration; +extern USB_VOLATILE uint8_t USBTicksSinceSuspendEnd; +/******************************************************************************/ +/* DOM-IGNORE-END */ + +#include + +#endif //USB_DEVICE_H diff --git a/usb/inc/usb_device_cdc.h b/usb/inc/usb_device_cdc.h new file mode 100644 index 0000000..19b7f64 --- /dev/null +++ b/usb/inc/usb_device_cdc.h @@ -0,0 +1,976 @@ +// 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 + +#ifndef CDC_H +#define CDC_H + +/** I N C L U D E S **********************************************************/ +#include "usb.h" +#include "usb_config.h" + +/** D E F I N I T I O N S ****************************************************/ + +/* Class-Specific Requests */ +#define SEND_ENCAPSULATED_COMMAND 0x00 +#define GET_ENCAPSULATED_RESPONSE 0x01 +#define SET_COMM_FEATURE 0x02 +#define GET_COMM_FEATURE 0x03 +#define CLEAR_COMM_FEATURE 0x04 +#define SET_LINE_CODING 0x20 +#define GET_LINE_CODING 0x21 +#define SET_CONTROL_LINE_STATE 0x22 +#define SEND_BREAK 0x23 + +/* Notifications * + * Note: Notifications are polled over + * Communication Interface (Interrupt Endpoint) + */ +#define NETWORK_CONNECTION 0x00 +#define RESPONSE_AVAILABLE 0x01 +#define SERIAL_STATE 0x20 + + +/* Device Class Code */ +#define CDC_DEVICE 0x02 + +/* Communication Interface Class Code */ +#define COMM_INTF 0x02 + +/* Communication Interface Class SubClass Codes */ +#define ABSTRACT_CONTROL_MODEL 0x02 + +/* Communication Interface Class Control Protocol Codes */ +#define V25TER 0x01 // Common AT commands ("Hayes(TM)") + + +/* Data Interface Class Codes */ +#define DATA_INTF 0x0A + +/* Data Interface Class Protocol Codes */ +#define NO_PROTOCOL 0x00 // No class specific protocol required + + +/* Communication Feature Selector Codes */ +#define ABSTRACT_STATE 0x01 +#define COUNTRY_SETTING 0x02 + +/* Functional Descriptors */ +/* Type Values for the bDscType Field */ +#define CS_INTERFACE 0x24 +#define CS_ENDPOINT 0x25 + +/* bDscSubType in Functional Descriptors */ +#define DSC_FN_HEADER 0x00 +#define DSC_FN_CALL_MGT 0x01 +#define DSC_FN_ACM 0x02 // ACM - Abstract Control Management +#define DSC_FN_DLM 0x03 // DLM - Direct Line Managment +#define DSC_FN_TELEPHONE_RINGER 0x04 +#define DSC_FN_RPT_CAPABILITIES 0x05 +#define DSC_FN_UNION 0x06 +#define DSC_FN_COUNTRY_SELECTION 0x07 +#define DSC_FN_TEL_OP_MODES 0x08 +#define DSC_FN_USB_TERMINAL 0x09 +/* more.... see Table 25 in USB CDC Specification 1.1 */ + +/* CDC Bulk IN transfer states */ +#define CDC_TX_READY 0 +#define CDC_TX_BUSY 1 +#define CDC_TX_BUSY_ZLP 2 // ZLP: Zero Length Packet +#define CDC_TX_COMPLETING 3 + +#if defined(USB_CDC_SET_LINE_CODING_HANDLER) + #define LINE_CODING_TARGET &cdc_notice.SetLineCoding._byte[0] + #define LINE_CODING_PFUNC &USB_CDC_SET_LINE_CODING_HANDLER +#else + #define LINE_CODING_TARGET &line_coding._byte[0] + #define LINE_CODING_PFUNC NULL +#endif + +#if defined(USB_CDC_SUPPORT_HARDWARE_FLOW_CONTROL) + #define CONFIGURE_RTS(a) UART_RTS = a; +#else + #define CONFIGURE_RTS(a) +#endif + +#if defined(USB_CDC_SUPPORT_ABSTRACT_CONTROL_MANAGEMENT_CAPABILITIES_D3) + #error This option is not currently supported. +#else + #define USB_CDC_SUPPORT_ABSTRACT_CONTROL_MANAGEMENT_CAPABILITIES_D3_VAL 0x00 +#endif + +#if defined(USB_CDC_SUPPORT_ABSTRACT_CONTROL_MANAGEMENT_CAPABILITIES_D2) + #define USB_CDC_SUPPORT_ABSTRACT_CONTROL_MANAGEMENT_CAPABILITIES_D2_VAL 0x04 +#else + #define USB_CDC_SUPPORT_ABSTRACT_CONTROL_MANAGEMENT_CAPABILITIES_D2_VAL 0x00 +#endif + +#if defined(USB_CDC_SUPPORT_ABSTRACT_CONTROL_MANAGEMENT_CAPABILITIES_D1) + #define USB_CDC_SUPPORT_ABSTRACT_CONTROL_MANAGEMENT_CAPABILITIES_D1_VAL 0x02 +#else + #define USB_CDC_SUPPORT_ABSTRACT_CONTROL_MANAGEMENT_CAPABILITIES_D1_VAL 0x00 +#endif + +#if defined(USB_CDC_SUPPORT_ABSTRACT_CONTROL_MANAGEMENT_CAPABILITIES_D0) + #error This option is not currently supported. +#else + #define USB_CDC_SUPPORT_ABSTRACT_CONTROL_MANAGEMENT_CAPABILITIES_D0_VAL 0x00 +#endif + +#define USB_CDC_ACM_FN_DSC_VAL \ + USB_CDC_SUPPORT_ABSTRACT_CONTROL_MANAGEMENT_CAPABILITIES_D3_VAL |\ + USB_CDC_SUPPORT_ABSTRACT_CONTROL_MANAGEMENT_CAPABILITIES_D2_VAL |\ + USB_CDC_SUPPORT_ABSTRACT_CONTROL_MANAGEMENT_CAPABILITIES_D1_VAL |\ + USB_CDC_SUPPORT_ABSTRACT_CONTROL_MANAGEMENT_CAPABILITIES_D0_VAL + +/****************************************************************************** + Function: + void CDCSetBaudRate(uint32_t baudRate) + + Summary: + This macro is used set the baud rate reported back to the host during + a get line coding request. (optional) + + Description: + This macro is used set the baud rate reported back to the host during + a get line coding request. + + Typical Usage: + + CDCSetBaudRate(19200); + + + This function is optional for CDC devices that do not actually convert + the USB traffic to a hardware UART. + + PreCondition: + None + + Parameters: + uint32_t baudRate - The desired baud rate + + Return Values: + None + + Remarks: + None + + *****************************************************************************/ +#define CDCSetBaudRate(baudRate) {line_coding.dwDTERate=baudRate;} + +/****************************************************************************** + Function: + void CDCSetCharacterFormat(uint8_t charFormat) + + Summary: + This macro is used manually set the character format reported back to + the host during a get line coding request. (optional) + + Description: + This macro is used manually set the character format reported back to + the host during a get line coding request. + + Typical Usage: + + CDCSetCharacterFormat(NUM_STOP_BITS_1); + + + This function is optional for CDC devices that do not actually convert + the USB traffic to a hardware UART. + + PreCondition: + None + + Parameters: + uint8_t charFormat - number of stop bits. Available options are: + * NUM_STOP_BITS_1 - 1 Stop bit + * NUM_STOP_BITS_1_5 - 1.5 Stop bits + * NUM_STOP_BITS_2 - 2 Stop bits + + Return Values: + None + + Remarks: + None + + *****************************************************************************/ +#define CDCSetCharacterFormat(charFormat) {line_coding.bCharFormat=charFormat;} +#define NUM_STOP_BITS_1 0 //1 stop bit - used by CDCSetLineCoding() and CDCSetCharacterFormat() +#define NUM_STOP_BITS_1_5 1 //1.5 stop bit - used by CDCSetLineCoding() and CDCSetCharacterFormat() +#define NUM_STOP_BITS_2 2 //2 stop bit - used by CDCSetLineCoding() and CDCSetCharacterFormat() + +/****************************************************************************** + Function: + void CDCSetParity(uint8_t parityType) + + Summary: + This function is used manually set the parity format reported back to + the host during a get line coding request. (optional) + + Description: + This macro is used manually set the parity format reported back to + the host during a get line coding request. + + Typical Usage: + + CDCSetParity(PARITY_NONE); + + + This function is optional for CDC devices that do not actually convert + the USB traffic to a hardware UART. + + PreCondition: + None + + Parameters: + uint8_t parityType - Type of parity. The options are the following: + * PARITY_NONE + * PARITY_ODD + * PARITY_EVEN + * PARITY_MARK + * PARITY_SPACE + + Return Values: + None + + Remarks: + None + + *****************************************************************************/ +#define CDCSetParity(parityType) {line_coding.bParityType=parityType;} +#define PARITY_NONE 0 //no parity - used by CDCSetLineCoding() and CDCSetParity() +#define PARITY_ODD 1 //odd parity - used by CDCSetLineCoding() and CDCSetParity() +#define PARITY_EVEN 2 //even parity - used by CDCSetLineCoding() and CDCSetParity() +#define PARITY_MARK 3 //mark parity - used by CDCSetLineCoding() and CDCSetParity() +#define PARITY_SPACE 4 //space parity - used by CDCSetLineCoding() and CDCSetParity() + +/****************************************************************************** + Function: + void CDCSetDataSize(uint8_t dataBits) + + Summary: + This function is used manually set the number of data bits reported back + to the host during a get line coding request. (optional) + + Description: + This function is used manually set the number of data bits reported back + to the host during a get line coding request. + + Typical Usage: + + CDCSetDataSize(8); + + + This function is optional for CDC devices that do not actually convert + the USB traffic to a hardware UART. + + PreCondition: + None + + Parameters: + uint8_t dataBits - number of data bits. The options are 5, 6, 7, 8, or 16. + + Return Values: + None + + Remarks: + None + + *****************************************************************************/ +#define CDCSetDataSize(dataBits) {line_coding.bDataBits=dataBits;} + +/****************************************************************************** + Function: + void CDCSetLineCoding(uint32_t baud, uint8_t format, uint8_t parity, uint8_t dataSize) + + Summary: + This function is used to manually set the data reported back + to the host during a get line coding request. (optional) + + Description: + This function is used to manually set the data reported back + to the host during a get line coding request. + + Typical Usage: + + CDCSetLineCoding(19200, NUM_STOP_BITS_1, PARITY_NONE, 8); + + + This function is optional for CDC devices that do not actually convert + the USB traffic to a hardware UART. + + PreCondition: + None + + Parameters: + uint32_t baud - The desired baud rate + uint8_t format - number of stop bits. Available options are: + * NUM_STOP_BITS_1 - 1 Stop bit + * NUM_STOP_BITS_1_5 - 1.5 Stop bits + * NUM_STOP_BITS_2 - 2 Stop bits + uint8_t parity - Type of parity. The options are the following: + * PARITY_NONE + * PARITY_ODD + * PARITY_EVEN + * PARITY_MARK + * PARITY_SPACE + uint8_t dataSize - number of data bits. The options are 5, 6, 7, 8, or 16. + + Return Values: + None + + Remarks: + None + + *****************************************************************************/ +#define CDCSetLineCoding(baud,format,parity,dataSize) {\ + CDCSetBaudRate(baud);\ + CDCSetCharacterFormat(format);\ + CDCSetParity(parity);\ + CDCSetDataSize(dataSize);\ + } + +/****************************************************************************** + Function: + bool USBUSARTIsTxTrfReady(void) + + Summary: + This macro is used to check if the CDC class is ready + to send more data. + + Description: + This macro is used to check if the CDC class handler firmware is + ready to send more data to the host over the CDC bulk IN endpoint. + + Typical Usage: + + if(USBUSARTIsTxTrfReady()) + { + putrsUSBUSART("Hello World"); + } + + + PreCondition: + The return value of this function is only valid if the device is in a + configured state (i.e. - USBDeviceGetState() returns CONFIGURED_STATE) + + Parameters: + None + + Return Values: + Returns a boolean value indicating if the CDC class handler firmware + is ready to receive new data to send to the host over the bulk data IN + endpoint. A return value of true indicates that the CDC handler + firmware is ready to receive new data, and it is therefore safe to + call other APIs like putrsUSBUSART() and putsUSBUSART(). A return + value of false implies that the firmware is still busy sending the + last data, or is otherwise not ready to process any new data at + this time. + + Remarks: + Make sure the application periodically calls the CDCTxService() + handler, or pending USB IN transfers will not be able to advance + and complete. + + *****************************************************************************/ +#define USBUSARTIsTxTrfReady() (cdc_trf_state == CDC_TX_READY) + +/****************************************************************************** + Function: + void mUSBUSARTTxRam(uint8_t *pData, uint8_t len) + + Description: + Deprecated in MCHPFSUSB v2.3. This macro has been replaced by + USBUSARTIsTxTrfReady(). + *****************************************************************************/ +#define mUSBUSARTIsTxTrfReady() USBUSARTIsTxTrfReady() + +/****************************************************************************** + Function: + void mUSBUSARTTxRam(uint8_t *pData, uint8_t len) + + Description: + Use this macro to transfer data located in data memory. + Use this macro when: + 1. Data stream is not null-terminated + 2. Transfer length is known + Remember: cdc_trf_state must == CDC_TX_READY + Unlike putsUSBUSART, there is not code double checking + the transfer state. Unexpected behavior will occur if + this function is called when cdc_trf_state != CDC_TX_READY + + Typical Usage: + + if(USBUSARTIsTxTrfReady()) + { + mUSBUSARTTxRam(&UserDataBuffer[0], 200); + } + + + PreCondition: + cdc_trf_state must be in the CDC_TX_READY state. + Value of 'len' must be equal to or smaller than 255 bytes. + The USB stack should have reached the CONFIGURED_STATE prior + to calling this API function for the first time. + + Parameters: + pDdata : Pointer to the starting location of data bytes + len : Number of bytes to be transferred + + Return Values: + None + + Remarks: + This macro only handles the setup of the transfer. The + actual transfer is handled by CDCTxService(). This macro + does not "double buffer" the data. The application firmware + should not modify the contents of the pData buffer until all + of the data has been sent, as indicated by the + USBUSARTIsTxTrfReady() function returning true, subsequent to + calling mUSBUSARTTxRam(). + + + *****************************************************************************/ +#define mUSBUSARTTxRam(pData,len) \ +{ \ + pCDCSrc.bRam = pData; \ + cdc_tx_len = len; \ + cdc_mem_type = USB_EP0_RAM; \ + cdc_trf_state = CDC_TX_BUSY; \ +} + +/****************************************************************************** + Function: + void mUSBUSARTTxRom(rom uint8_t *pData, uint8_t len) + + Description: + Use this macro to transfer data located in program memory. + Use this macro when: + 1. Data stream is not null-terminated + 2. Transfer length is known + + Remember: cdc_trf_state must == CDC_TX_READY + Unlike putrsUSBUSART, there is not code double checking + the transfer state. Unexpected behavior will occur if + this function is called when cdc_trf_state != CDC_TX_READY + + Typical Usage: + + if(USBUSARTIsTxTrfReady()) + { + mUSBUSARTTxRom(&SomeRomString[0], 200); + } + + + PreCondition: + cdc_trf_state must be in the CDC_TX_READY state. + Value of 'len' must be equal to or smaller than 255 bytes. + + Parameters: + pDdata : Pointer to the starting location of data bytes + len : Number of bytes to be transferred + + Return Values: + None + + Remarks: + This macro only handles the setup of the transfer. The + actual transfer is handled by CDCTxService(). + + *****************************************************************************/ +#define mUSBUSARTTxRom(pData,len) \ +{ \ + pCDCSrc.bRom = pData; \ + cdc_tx_len = len; \ + cdc_mem_type = USB_EP0_ROM; \ + cdc_trf_state = CDC_TX_BUSY; \ +} + +/************************************************************************** + Function: + void CDCInitEP(void) + + Summary: + This function initializes the CDC function driver. This function should + be called after the SET_CONFIGURATION command (ex: within the context of + the USBCBInitEP() function). + Description: + This function initializes the CDC function driver. This function sets + the default line coding (baud rate, bit parity, number of data bits, + and format). This function also enables the endpoints and prepares for + the first transfer from the host. + + This function should be called after the SET_CONFIGURATION command. + This is most simply done by calling this function from the + USBCBInitEP() function. + + Typical Usage: + + void USBCBInitEP(void) + { + CDCInitEP(); + } + + Conditions: + None + Remarks: + None + **************************************************************************/ +void CDCInitEP(void); + +/****************************************************************************** + Function: + void USBCheckCDCRequest(void) + + Description: + This routine checks the most recently received SETUP data packet to + see if the request is specific to the CDC class. If the request was + a CDC specific request, this function will take care of handling the + request and responding appropriately. + + PreCondition: + This function should only be called after a control transfer SETUP + packet has arrived from the host. + + Parameters: + None + + Return Values: + None + + Remarks: + This function does not change status or do anything if the SETUP packet + did not contain a CDC class specific request. + *****************************************************************************/ +void USBCheckCDCRequest(void); + + +/************************************************************************** + Function: void CDCNotificationHandler(void) + Summary: Checks for changes in DSR status and reports them to the USB host. + Description: Checks for changes in DSR pin state and reports any changes + to the USB host. + Conditions: CDCInitEP() must have been called previously, prior to calling + CDCNotificationHandler() for the first time. + Remarks: + This function is only implemented and needed when the + USB_CDC_SUPPORT_DSR_REPORTING option has been enabled. If the function is + enabled, it should be called periodically to sample the DSR pin and feed + the information to the USB host. This can be done by calling + CDCNotificationHandler() by itself, or, by calling CDCTxService() which + also calls CDCNotificationHandler() internally, when appropriate. + **************************************************************************/ +void CDCNotificationHandler(void); + + +/********************************************************************************** + Function: + bool USBCDCEventHandler(USB_EVENT event, void *pdata, uint16_t size) + + Summary: + Handles events from the USB stack, which may have an effect on the CDC + endpoint(s). + + Description: + Handles events from the USB stack. This function should be called when + there is a USB event that needs to be processed by the CDC driver. + + Conditions: + Value of input argument 'len' should be smaller than the maximum + endpoint size responsible for receiving bulk data from USB host for CDC + class. Input argument 'buffer' should point to a buffer area that is + bigger or equal to the size specified by 'len'. + Input: + event - the type of event that occurred + pdata - pointer to the data that caused the event + size - the size of the data that is pointed to by pdata + + **********************************************************************************/ +bool USBCDCEventHandler(USB_EVENT event, void *pdata, uint16_t size); + + +/********************************************************************************** + Function: + uint8_t getsUSBUSART(char *buffer, uint8_t len) + + Summary: + getsUSBUSART copies a string of BYTEs received through USB CDC Bulk OUT + endpoint to a user's specified location. It is a non-blocking function. + It does not wait for data if there is no data available. Instead it + returns '0' to notify the caller that there is no data available. + + Description: + getsUSBUSART copies a string of BYTEs received through USB CDC Bulk OUT + endpoint to a user's specified location. It is a non-blocking function. + It does not wait for data if there is no data available. Instead it + returns '0' to notify the caller that there is no data available. + + Typical Usage: + + uint8_t numBytes; + uint8_t buffer[64] + + numBytes = getsUSBUSART(buffer,sizeof(buffer)); //until the buffer is free. + if(numBytes \> 0) + { + //we received numBytes bytes of data and they are copied into + // the "buffer" variable. We can do something with the data + // here. + } + + Conditions: + Value of input argument 'len' should be smaller than the maximum + endpoint size responsible for receiving bulk data from USB host for CDC + class. Input argument 'buffer' should point to a buffer area that is + bigger or equal to the size specified by 'len'. + Input: + buffer - Pointer to where received BYTEs are to be stored + len - The number of BYTEs expected. + Output: + uint8_t - Returns a byte indicating the total number of bytes that were actually + received and copied into the specified buffer. The returned value + can be anything from 0 up to the len input value. A return value of 0 + indicates that no new CDC bulk OUT endpoint data was available. + + **********************************************************************************/ +uint8_t getsUSBUSART(uint8_t *buffer, uint8_t len); + +/****************************************************************************** + Function: + void putUSBUSART(char *data, uint8_t length) + + Summary: + putUSBUSART writes an array of data to the USB. Use this version, is + capable of transferring 0x00 (what is typically a NULL character in any of + the string transfer functions). + + Description: + putUSBUSART writes an array of data to the USB. Use this version, is + capable of transferring 0x00 (what is typically a NULL character in any of + the string transfer functions). + + Typical Usage: + + if(USBUSARTIsTxTrfReady()) + { + char data[] = {0x00, 0x01, 0x02, 0x03, 0x04}; + putUSBUSART(data,5); + } + + + The transfer mechanism for device-to-host(put) is more flexible than + host-to-device(get). It can handle a string of data larger than the + maximum size of bulk IN endpoint. A state machine is used to transfer a + \long string of data over multiple USB transactions. CDCTxService() + must be called periodically to keep sending blocks of data to the host. + + Conditions: + USBUSARTIsTxTrfReady() must return true. This indicates that the last + transfer is complete and is ready to receive a new block of data. The + string of characters pointed to by 'data' must equal to or smaller than + 255 BYTEs. + + Input: + char *data - pointer to a RAM array of data to be transfered to the host + uint8_t length - the number of bytes to be transfered (must be less than 255). + + *****************************************************************************/ +void putUSBUSART(uint8_t *data, uint8_t Length); + +/****************************************************************************** + Function: + void putsUSBUSART(char *data) + + Summary: + putsUSBUSART writes a string of data to the USB including the null + character. Use this version, 'puts', to transfer data from a RAM buffer. + + Description: + putsUSBUSART writes a string of data to the USB including the null + character. Use this version, 'puts', to transfer data from a RAM buffer. + + Typical Usage: + + if(USBUSARTIsTxTrfReady()) + { + char data[] = "Hello World"; + putsUSBUSART(data); + } + + + The transfer mechanism for device-to-host(put) is more flexible than + host-to-device(get). It can handle a string of data larger than the + maximum size of bulk IN endpoint. A state machine is used to transfer a + \long string of data over multiple USB transactions. CDCTxService() + must be called periodically to keep sending blocks of data to the host. + + Conditions: + USBUSARTIsTxTrfReady() must return true. This indicates that the last + transfer is complete and is ready to receive a new block of data. The + string of characters pointed to by 'data' must equal to or smaller than + 255 BYTEs. + + Input: + char *data - null\-terminated string of constant data. If a + null character is not found, 255 BYTEs of data + will be transferred to the host. + + *****************************************************************************/ +void putsUSBUSART(char *data); + + +/************************************************************************** + Function: + void putrsUSBUSART(const const char *data) + + Summary: + putrsUSBUSART writes a string of data to the USB including the null + character. Use this version, 'putrs', to transfer data literals and + data located in program memory. + + Description: + putrsUSBUSART writes a string of data to the USB including the null + character. Use this version, 'putrs', to transfer data literals and + data located in program memory. + + Typical Usage: + + if(USBUSARTIsTxTrfReady()) + { + putrsUSBUSART("Hello World"); + } + + + The transfer mechanism for device-to-host(put) is more flexible than + host-to-device(get). It can handle a string of data larger than the + maximum size of bulk IN endpoint. A state machine is used to transfer a + \long string of data over multiple USB transactions. CDCTxService() + must be called periodically to keep sending blocks of data to the host. + + Conditions: + USBUSARTIsTxTrfReady() must return true. This indicates that the last + transfer is complete and is ready to receive a new block of data. The + string of characters pointed to by 'data' must equal to or smaller than + 255 BYTEs. + + Input: + const const char *data - null\-terminated string of constant data. If a + null character is not found, 255 BYTEs of data + will be transferred to the host. + + **************************************************************************/ +void putrsUSBUSART(const const char *data); + +/************************************************************************ + Function: + void CDCTxService(void) + + Summary: + CDCTxService handles device-to-host transaction(s). This function + should be called once per Main Program loop after the device reaches + the configured state. + Description: + CDCTxService handles device-to-host transaction(s). This function + should be called once per Main Program loop after the device reaches + the configured state (after the CDCIniEP() function has already executed). + This function is needed, in order to advance the internal software state + machine that takes care of sending multiple transactions worth of IN USB + data to the host, associated with CDC serial data. Failure to call + CDCTxService() periodically will prevent data from being sent to the + USB host, over the CDC serial data interface. + + Typical Usage: + + void main(void) + { + USBDeviceInit(); + while(1) + { + USBDeviceTasks(); + if((USBGetDeviceState() \< CONFIGURED_STATE) || + (USBIsDeviceSuspended() == true)) + { + //Either the device is not configured or we are suspended + // so we don't want to do execute any application code + continue; //go back to the top of the while loop + } + else + { + //Keep trying to send data to the PC as required + CDCTxService(); + + //Run application code. + UserApplication(); + } + } + } + + Conditions: + CDCIniEP() function should have already exectuted/the device should be + in the CONFIGURED_STATE. + Remarks: + None + ************************************************************************/ +void CDCTxService(void); + + +/** S T R U C T U R E S ******************************************************/ + +/* Line Coding Structure */ +#define LINE_CODING_LENGTH 0x07 + +typedef union _LINE_CODING +{ + struct + { + uint8_t _byte[LINE_CODING_LENGTH]; + }; + struct + { + uint32_t dwDTERate; + uint8_t bCharFormat; + uint8_t bParityType; + uint8_t bDataBits; + }; +} LINE_CODING; + +typedef union _CONTROL_SIGNAL_BITMAP +{ + uint8_t _byte; + struct + { + unsigned DTE_PRESENT:1; // [0] Not Present [1] Present + unsigned CARRIER_CONTROL:1; // [0] Deactivate [1] Activate + }; +} CONTROL_SIGNAL_BITMAP; + + +/* Functional Descriptor Structure - See CDC Specification 1.1 for details */ + +/* Header Functional Descriptor */ +typedef struct __attribute__((packed)) _USB_CDC_HEADER_FN_DSC +{ + uint8_t bFNLength; + uint8_t bDscType; + uint8_t bDscSubType; + uint16_t bcdCDC; +} USB_CDC_HEADER_FN_DSC; + +/* Abstract Control Management Functional Descriptor */ +typedef struct __attribute__((packed)) _USB_CDC_ACM_FN_DSC +{ + uint8_t bFNLength; + uint8_t bDscType; + uint8_t bDscSubType; + uint8_t bmCapabilities; +} USB_CDC_ACM_FN_DSC; + +/* Union Functional Descriptor */ +typedef struct __attribute__((packed)) _USB_CDC_UNION_FN_DSC +{ + uint8_t bFNLength; + uint8_t bDscType; + uint8_t bDscSubType; + uint8_t bMasterIntf; + uint8_t bSaveIntf0; +} USB_CDC_UNION_FN_DSC; + +/* Call Management Functional Descriptor */ +typedef struct __attribute__((packed)) _USB_CDC_CALL_MGT_FN_DSC +{ + uint8_t bFNLength; + uint8_t bDscType; + uint8_t bDscSubType; + uint8_t bmCapabilities; + uint8_t bDataInterface; +} USB_CDC_CALL_MGT_FN_DSC; + +typedef union __attribute__((packed)) _CDC_NOTICE +{ + LINE_CODING GetLineCoding; + LINE_CODING SetLineCoding; + unsigned char packet[CDC_COMM_IN_EP_SIZE]; +} CDC_NOTICE, *PCDC_NOTICE; + +/* Bit structure definition for the SerialState notification byte */ +typedef union +{ + uint8_t byte; + struct + { + uint8_t DCD :1; + uint8_t DSR :1; + uint8_t BreakState :1; + uint8_t RingDetect :1; + uint8_t FramingError :1; + uint8_t ParityError :1; + uint8_t Overrun :1; + uint8_t Reserved :1; + }bits; +}BM_SERIAL_STATE; + +/* Serial State Notification Packet Structure */ +typedef struct +{ + uint8_t bmRequestType; //Always 0xA1 for serial state notification packets + uint8_t bNotification; //Always SERIAL_STATE (0x20) for serial state notification packets + uint16_t wValue; //Always 0 for serial state notification packets + uint16_t wIndex; //Interface number + uint16_t wLength; //Should always be 2 for serial state notification packets + BM_SERIAL_STATE SerialState; + uint8_t Reserved; +}SERIAL_STATE_NOTIFICATION; + +//DOM-IGNORE-BEGIN +/** E X T E R N S ************************************************************/ +extern uint8_t cdc_rx_len; +extern USB_HANDLE lastTransmission; + +extern uint8_t cdc_trf_state; +extern POINTER pCDCSrc; +extern uint8_t cdc_tx_len; +extern uint8_t cdc_mem_type; + +extern CDC_NOTICE cdc_notice; +extern LINE_CODING line_coding; + +extern volatile CTRL_TRF_SETUP SetupPkt; +extern const uint8_t configDescriptor1[]; + +/** Public Prototypes *************************************************/ +//------------------------------------------------------------------------------ +//This is the list of public API functions provided by usb_function_cdc.c. +//This list is commented out, since the actual prototypes are declared above +//with associated inline documentation. +//------------------------------------------------------------------------------ +//void USBCheckCDCRequest(void); +//void CDCInitEP(void); +//bool USBCDCEventHandler(USB_EVENT event, void *pdata, uint16_t size); +//uint8_t getsUSBUSART(char *buffer, uint8_t len); +//void putUSBUSART(char *data, uint8_t Length); +//void putsUSBUSART(char *data); +//void putrsUSBUSART(const const char *data); +//void CDCTxService(void); +//void CDCNotificationHandler(void); +//------------------------------------------------------------------------------ +//DOM-IGNORE-END + + +#endif //CDC_H diff --git a/usb/inc/usb_device_generic.h b/usb/inc/usb_device_generic.h new file mode 100644 index 0000000..2471dab --- /dev/null +++ b/usb/inc/usb_device_generic.h @@ -0,0 +1,177 @@ +// 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 + +#ifndef USBGEN_H +#define USBGEN_H + +#include +#include "usb_config.h" + +/** I N C L U D E S **********************************************************/ + +/** D E F I N I T I O N S ****************************************************/ + +/** S T R U C T U R E S ******************************************************/ + +/** E X T E R N S ************************************************************/ + +/** P U B L I C P R O T O T Y P E S *****************************************/ + +/******************************************************************** + Function: + USB_HANDLE USBGenWrite(BYTE ep, BYTE* data, WORD len) + + Summary: + Sends the specified data out the specified endpoint + + Description: + This function sends the specified data out the specified + endpoint and returns a handle to the transfer information. + + Typical Usage: + + //make sure that the last transfer isn't busy by checking the handle + if(!USBHandleBusy(USBGenericInHandle)) + { + //Send the data contained in the INPacket[] array out on + // endpoint USBGEN_EP_NUM + USBGenericInHandle = USBGenWrite(USBGEN_EP_NUM,(BYTE*)&INPacket[0],sizeof(INPacket)); + } + + + PreCondition: + None + + Parameters: + BYTE ep - the endpoint you want to send the data out of + BYTE* data - pointer to the data that you wish to send + WORD len - the length of the data that you wish to send + + Return Values: + USB_HANDLE - a handle for the transfer. This information + should be kept to track the status of the transfer + + Remarks: + None + + *******************************************************************/ +#define USBGenWrite(ep,data,len) USBTxOnePacket(ep,data,len) + + +/******************************************************************** + Function: + USB_HANDLE USBGenRead(BYTE ep, BYTE* data, WORD len) + + Summary: + Receives the specified data out the specified endpoint + + Description: + Receives the specified data out the specified endpoint. + + Typical Usage: + + //Read 64-bytes from endpoint USBGEN_EP_NUM, into the OUTPacket array. + // Make sure to save the return handle so that we can check it later + // to determine when the transfer is complete. + if(!USBHandleBusy(USBOutHandle)) + { + USBOutHandle = USBGenRead(USBGEN_EP_NUM,(BYTE*)&OUTPacket,64); + } + + + PreCondition: + None + + Parameters: + BYTE ep - the endpoint you want to receive the data into + BYTE* data - pointer to where the data will go when it arrives + WORD len - the length of the data that you wish to receive + + Return Values: + USB_HANDLE - a handle for the transfer. This information + should be kept to track the status of the transfer + + Remarks: + None + + *******************************************************************/ +#define USBGenRead(ep,data,len) USBRxOnePacket(ep,data,len) + + +/******************************************************************** + Function: + void USBCheckVendorRequest(void) + + Summary: + This routine handles vendor class specific requests that happen on EP0. + This function should be called from the USBCBCheckOtherReq() call back + function whenever implementing a custom/vendor class device. + + Description: + This routine handles vendor specific requests that may arrive on EP0 as + a control transfer. These can include, but are not necessarily + limited to, requests for Microsft specific OS feature descriptor(s). + This function should be called from the USBCBCheckOtherReq() call back + function whenever using a vendor class device. + + Typical Usage: + + void USBCBCheckOtherReq(void) + { + //Since the stack didn't handle the request I need to check + // my class drivers to see if it is for them + USBCheckVendorRequest(); + } + + + PreCondition: + None + + Parameters: + Although this function has a void input, this handler function will + typically need to look at the 8-byte SETUP packet contents that the + host just sent, which may contain the vendor class specific request. + + Therefore, the statically allocated SetupPkt structure may be looked + at while in the context of this function, and it will contain the most + recently received 8-byte SETUP packet data. + + Return Values: + None + + Remarks: + This function normally gets called within the same context as the + USBDeviceTasks() function, just after a new control transfer request + from the host has arrived. If the USB stack is operated in + USB_INTERRUPT mode (a usb_config.h option), then this function + will be executed in the interrupt context. If however the USB stack + is operated in the USB_POLLING mode, then this function executes in the + main loop context. + + In order to respond to class specific control transfer request(s) in + this handler function, it is suggested to use one or more of the + USBEP0SendRAMPtr(), USBEP0SendROMPtr(), or USBEP0Receive() API + functions. + + *******************************************************************/ +void USBCheckVendorRequest(void); + +#endif //USBGEN_H diff --git a/usb/inc/usb_device_hid.h b/usb/inc/usb_device_hid.h new file mode 100644 index 0000000..6e0c3eb --- /dev/null +++ b/usb/inc/usb_device_hid.h @@ -0,0 +1,307 @@ +// 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 + +#ifndef HID_H +#define HID_H + + +/** INCLUDES *******************************************************/ + +#include "usb_ch9.h" + +/** DEFINITIONS ****************************************************/ + +/* Class-Specific Requests */ +#define GET_REPORT 0x01 +#define GET_IDLE 0x02 +#define GET_PROTOCOL 0x03 +#define SET_REPORT 0x09 +#define SET_IDLE 0x0A +#define SET_PROTOCOL 0x0B + +/* Class Descriptor Types */ +#define DSC_HID 0x21 +#define DSC_RPT 0x22 +#define DSC_PHY 0x23 + +/* Protocol Selection */ +#define BOOT_PROTOCOL 0x00 +#define RPT_PROTOCOL 0x01 + +/* HID Interface Class Code */ +#define HID_INTF 0x03 + +/* HID Interface Class SubClass Codes */ +#define BOOT_INTF_SUBCLASS 0x01 + +/* HID Interface Class Protocol Codes */ +#define HID_PROTOCOL_NONE 0x00 +#define HID_PROTOCOL_KEYBOARD 0x01 +#define HID_PROTOCOL_MOUSE 0x02 + +/******************************************************************** + Function: + void USBCheckHIDRequest(void) + + Summary: + This routine handles HID specific request that happen on EP0. + This function should be called from the USBCBCheckOtherReq() call back + function whenever implementing a HID device. + + Description: + This routine handles HID specific request that happen on EP0. These + include, but are not limited to, requests for the HID report + descriptors. This function should be called from the + USBCBCheckOtherReq() call back function whenever using an HID device. + + Typical Usage: + + void USBCBCheckOtherReq(void) + { + //Since the stack didn't handle the request I need to check + // my class drivers to see if it is for them + USBCheckHIDRequest(); + } + + + PreCondition: + None + + Parameters: + None + + Return Values: + None + + Remarks: + None + + *******************************************************************/ +void USBCheckHIDRequest(void); + +/******************************************************************** + Function: + bool HIDTxHandleBusy(USB_HANDLE handle) + + Summary: + Retrieves the status of the buffer ownership + + Description: + Retrieves the status of the buffer ownership. This function will + indicate if the previous transfer is complete or not. + + This function will take the input handle (pointer to a BDT entry) and + will check the UOWN bit. If the UOWN bit is set then that indicates + that the transfer is not complete and the USB module still owns the data + memory. If the UOWN bit is clear that means that the transfer is + complete and that the CPU now owns the data memory. + + For more information about the BDT, please refer to the appropriate + datasheet for the device in use. + + Typical Usage: + + //make sure that the last transfer isn't busy by checking the handle + if(!HIDTxHandleBusy(USBInHandle)) + { + //Send the data contained in the ToSendDataBuffer[] array out on + // endpoint HID_EP + USBInHandle = HIDTxPacket(HID_EP,(uint8_t*)&ToSendDataBuffer[0],sizeof(ToSendDataBuffer)); + } + + + PreCondition: + None. + + Parameters: + USB_HANDLE handle - the handle for the transfer in question. + The handle is returned by the HIDTxPacket() and HIDRxPacket() + functions. Please insure that USB_HANDLE objects are initialized + to NULL. + + Return Values: + TRUE - the HID handle is still busy + FALSE - the HID handle is not busy and is ready to send + additional data. + + Remarks: + None + + *******************************************************************/ +#define HIDTxHandleBusy(handle) USBHandleBusy(handle) + +/******************************************************************** + Function: + bool HIDRxHandleBusy(USB_HANDLE handle) + + Summary: + Retrieves the status of the buffer ownership + + Description: + Retrieves the status of the buffer ownership. This function will + indicate if the previous transfer is complete or not. + + This function will take the input handle (pointer to a BDT entry) and + will check the UOWN bit. If the UOWN bit is set then that indicates + that the transfer is not complete and the USB module still owns the data + memory. If the UOWN bit is clear that means that the transfer is + complete and that the CPU now owns the data memory. + + For more information about the BDT, please refer to the appropriate + datasheet for the device in use. + + Typical Usage: + + if(!HIDRxHandleBusy(USBOutHandle)) + { + //The data is available in the buffer that was specified when the + // HIDRxPacket() was called. + } + + + PreCondition: + None + + Parameters: + USB_HANDLE handle - the handle for the transfer in question. + The handle is returned by the HIDTxPacket() and HIDRxPacket() + functions. Please insure that USB_HANDLE objects are initialized + to NULL. + + Return Values: + TRUE - the HID handle is still busy + FALSE - the HID handle is not busy and is ready to receive + additional data. + + Remarks: + None + + *******************************************************************/ +#define HIDRxHandleBusy(handle) USBHandleBusy(handle) + +/******************************************************************** + Function: + USB_HANDLE HIDTxPacket(uint8_t ep, uint8_t* data, uint16_t len) + + Summary: + Sends the specified data out the specified endpoint + + Description: + This function sends the specified data out the specified + endpoint and returns a handle to the transfer information. + + Typical Usage: + + //make sure that the last transfer isn't busy by checking the handle + if(!HIDTxHandleBusy(USBInHandle)) + { + //Send the data contained in the ToSendDataBuffer[] array out on + // endpoint HID_EP + USBInHandle = HIDTxPacket(HID_EP,(uint8_t*)&ToSendDataBuffer[0],sizeof(ToSendDataBuffer)); + } + + + PreCondition: + None + + Parameters: + uint8_t ep - the endpoint you want to send the data out of + uint8_t* data - pointer to the data that you wish to send + uint16_t len - the length of the data that you wish to send + + Return Values: + USB_HANDLE - a handle for the transfer. This information + should be kept to track the status of the transfer + + Remarks: + None + + *******************************************************************/ +#define HIDTxPacket USBTxOnePacket + +/******************************************************************** + Function: + USB_HANDLE HIDRxPacket(uint8_t ep, uint8_t* data, uint16_t len) + + Summary: + Receives the specified data out the specified endpoint + + Description: + Receives the specified data out the specified endpoint. + + Typical Usage: + + //Read 64-uint8_ts from endpoint HID_EP, into the ReceivedDataBuffer array. + // Make sure to save the return handle so that we can check it later + // to determine when the transfer is complete. + USBOutHandle = HIDRxPacket(HID_EP,(uint8_t*)&ReceivedDataBuffer,64); + + + PreCondition: + None + + Parameters: + uint8_t ep - the endpoint you want to receive the data into + uint8_t* data - pointer to where the data will go when it arrives + uint16_t len - the length of the data that you wish to receive + + Return Values: + USB_HANDLE - a handle for the transfer. This information + should be kept to track the status of the transfer + + Remarks: + None + + *******************************************************************/ +#define HIDRxPacket USBRxOnePacket + +// Section: STRUCTURES *********************************************/ + +//USB HID Descriptor header as detailed in section +//"6.2.1 HID Descriptor" of the HID class definition specification +typedef struct _USB_HID_DSC_HEADER +{ + uint8_t bDescriptorType; //offset 9 + uint16_t wDscLength; //offset 10 +} USB_HID_DSC_HEADER; + +//USB HID Descriptor header as detailed in section +//"6.2.1 HID Descriptor" of the HID class definition specification +typedef struct _USB_HID_DSC +{ + uint8_t bLength; //offset 0 + uint8_t bDescriptorType; //offset 1 + uint16_t bcdHID; //offset 2 + uint8_t bCountryCode; //offset 4 + uint8_t bNumDsc; //offset 5 + + + //USB_HID_DSC_HEADER hid_dsc_header[HID_NUM_OF_DSC]; + /* HID_NUM_OF_DSC is defined in usbcfg.h */ + +} USB_HID_DSC; + +/** Section: EXTERNS ********************************************************/ +extern volatile CTRL_TRF_SETUP SetupPkt; +extern const uint8_t configDescriptor1[]; +extern volatile uint8_t CtrlTrfData[USB_EP0_BUFF_SIZE]; + +#endif //HID_H diff --git a/usb/inc/usb_device_local.h b/usb/inc/usb_device_local.h new file mode 100644 index 0000000..5c66f43 --- /dev/null +++ b/usb/inc/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(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(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(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(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(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(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(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(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(event,pointer,size) +#endif + diff --git a/usb/inc/usb_device_midi.h b/usb/inc/usb_device_midi.h new file mode 100644 index 0000000..bdb3975 --- /dev/null +++ b/usb/inc/usb_device_midi.h @@ -0,0 +1,69 @@ +// 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 + +typedef union +{ + uint32_t Val; + uint8_t v[4]; + union + { + struct + { + uint8_t CIN :4; + uint8_t CN :4; + uint8_t MIDI_0; + uint8_t MIDI_1; + uint8_t MIDI_2; + }; + struct + { + uint8_t CodeIndexNumber :4; + uint8_t CableNumber :4; + uint8_t DATA_0; + uint8_t DATA_1; + uint8_t DATA_2; + }; + }; +} USB_AUDIO_MIDI_EVENT_PACKET, *P_USB_AUDIO_MIDI_EVENT_PACKET; + +/* Code Index Number (CIN) values */ +/* Table 4-1 of midi10.pdf */ +#define MIDI_CIN_MISC_FUNCTION_RESERVED 0x0 +#define MIDI_CIN_CABLE_EVENTS_RESERVED 0x1 +#define MIDI_CIN_2_uint8_t_MESSAGE 0x2 +#define MIDI_CIN_MTC 0x2 +#define MIDI_CIN_SONG_SELECT 0x2 +#define MIDI_CIN_3_uint8_t_MESSAGE 0x3 +#define MIDI_CIN_SSP 0x3 +#define MIDI_CIN_SYSEX_START 0x4 +#define MIDI_CIN_SYSEX_CONTINUE 0x4 +#define MIDI_CIN_1_uint8_t_MESSAGE 0x5 +#define MIDI_CIN_SYSEX_ENDS_1 0x5 +#define MIDI_CIN_SYSEX_ENDS_2 0x6 +#define MIDI_CIN_SYSEX_ENDS_3 0x7 +#define MIDI_CIN_NOTE_OFF 0x8 +#define MIDI_CIN_NOTE_ON 0x9 +#define MIDI_CIN_POLY_KEY_PRESS 0xA +#define MIDI_CIN_CONTROL_CHANGE 0xB +#define MIDI_CIN_PROGRAM_CHANGE 0xC +#define MIDI_CIN_CHANNEL_PREASURE 0xD +#define MIDI_CIN_PITCH_BEND_CHANGE 0xE +#define MIDI_CIN_SINGLE_uint8_t 0xF diff --git a/usb/inc/usb_hal.h b/usb/inc/usb_hal.h new file mode 100644 index 0000000..a6836e5 --- /dev/null +++ b/usb/inc/usb_hal.h @@ -0,0 +1,614 @@ +// 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 + +#ifndef _USB_HAL_H_ +#define _USB_HAL_H_ + +// ***************************************************************************** +// ***************************************************************************** +// Section: Included Files +// ***************************************************************************** +// ***************************************************************************** +#include + +#if defined(__18CXX) || defined(__XC8) + #if defined(_PIC14E) + #include "usb_hal_pic16f1.h" + #else + #include "usb_hal_pic18.h" + #endif +#elif defined(__C30__) || defined __XC16__ + #if defined(__dsPIC33E__) + #include "usb_hal_dspic33e.h" + #elif defined(__PIC24E__) + #include "usb_hal_pic24e.h" + #else + #include "usb_hal_pic24f.h" + #endif +#elif defined(__XC32__) + #if defined(__PIC32MM__) + #include "usb_hal_pic32mm.h" + #else + #error "Silicon Platform not defined" + #endif +#else + #error "Silicon Platform not defined" +#endif + +#ifdef __cplusplus // Provide C++ Compatability + extern "C" { +#endif + +// ***************************************************************************** +// ***************************************************************************** +// Section: Constants +// ***************************************************************************** +// ***************************************************************************** +/* USBHALControlUsbResistors flags */ +#define USB_HAL_PULL_UP_D_PLUS 0x80 // Pull D+ line high +#define USB_HAL_PULL_UP_D_MINUS 0x40 // Pull D- line high +#define USB_HAL_PULL_DN_D_PLUS 0x20 // Pull D+ line low +#define USB_HAL_PULL_DN_D_MINUS 0x10 // Pull D- line low +/* + The following are defined for convenience: + */ +#define USB_HAL_DEV_CONN_FULL_SPD USB_HAL_PULL_UP_D_PLUS +#define USB_HAL_DEV_CONN_LOW_SPD USB_HAL_PULL_UP_D_MINUS +#define USB_HAL_DEV_DISCONNECT 0 + +/* USBHALControlBusPower Commands */ +#define USB_VBUS_DISCHARGE 0 // Dicharge Vbus via resistor +#define USB_VBUS_CHARGE 1 // Charge Vbus via resistor +#define USB_VBUS_POWER_ON 3 // Supply power to Vbus +#define USB_VBUS_POWER_OFF 4 // Do not supply power to Vbus + +/* + USBHALGetLastError Error Bits. + */ +#define USBHAL_PID_ERR 0x00000001 // Packet ID Error +#define USBHAL_CRC5 0x00000002 // (Host) Token CRC5 check failed +#define USBHAL_HOST_EOF 0x00000002 // (Host) EOF not reached before next SOF +#define USBHAL_CRC16 0x00000004 // Data packet CRC error +#define USBHAL_DFN8 0x00000008 // Data field size not n*8 bits +#define USBHAL_BTO_ERR 0x00000010 // Bus turn-around timeout +#define USBHAL_DMA_ERR 0x00000020 // DMA error, unable to read/write memory +#define USBHAL_BTS_ERR 0x00000080 // Bit-stuffing error +#define USBHAL_XFER_ID 0x00000100 // Unable to identify transfer EP +#define USBHAL_NO_EP 0x00000200 // Invalid endpoint number +#define USBHAL_DMA_ERR2 0x00000400 // Error starting DMA transaction + +/* Flags for USBHALSetEpConfiguration */ +#if defined(__18CXX) || defined(__XC8) + #define USB_HAL_TRANSMIT 0x0400 // Enable EP for transmitting data + #define USB_HAL_RECEIVE 0x0200 // Enable EP for receiving data + #define USB_HAL_HANDSHAKE 0x1000 // Enable EP to give ACK/NACK (non isoch) + + #define USB_HAL_NO_INC 0x0010 // Use for DMA to another device FIFO + #define USB_HAL_HW_KEEPS 0x0020 // Cause HW to keep EP +#else + #define USB_HAL_TRANSMIT 0x0400 // Enable EP for transmitting data + #define USB_HAL_RECEIVE 0x0800 // Enable EP for receiving data + #define USB_HAL_HANDSHAKE 0x0100 // Enable EP to give ACK/NACK (non isoch) + + /* Does not work, Fix this if needed. 3/1/07 - Bud + #define USB_HAL_NO_INC 0x0010 // Use for DMA to another device FIFO + #define USB_HAL_HW_KEEPS 0x0020 // Cause HW to keep EP + */ + #define USB_HAL_ALLOW_HUB 0x8000 // (host only) Enable low-spd hub support + #define USB_HAL_NO_RETRY 0x4000 // (host only) disable auto-retry on NACK +#endif +// ***************************************************************************** +// ***************************************************************************** +// Section: Data Types +// ***************************************************************************** +// ***************************************************************************** + + +// ***************************************************************************** +// ***************************************************************************** +// Section: Interface Routines +// ***************************************************************************** +// ***************************************************************************** + +/************************************************************************* + Function: + void USBHALSetBusAddress( uint8_t addr ) + + Description: + This routine sets the address of the system on the USB + when acting as a peripheral device. + + Preconditions: + 1. USBHALInitialize must have been called to + initialize the USB HAL. + 2. Endpoint zero (0) must be configured as appropriate + by calls to USBHALSetEpConfiguration. + 3. The system must have been enumerated on the USB (as + a device). + + Parameters: + addr Desired address of this device on the USB. + + Return Values: + None + + Side Effect: + The bus address has been set. + + Remarks: + The address is assigned by the host and is received in + a SET_ADDRESS setup request. + + *************************************************************************/ +/* + This routine is implemented as a macro to a lower-level level routine. + */ + +#define USBHALSetBusAddress OTGCORE_SetDeviceAddr + +void USBHALSetBusAddress( uint8_t addr ); + + +/************************************************************************* + Function: + void USBHALControlUsbResistors( uint8_t flags ); + + Description: + This routine enables or disables the USB pull-up or + pull-down resistors as requested. + + Precondition: + USBInitialize must have been called to initialize the + USB SW stack. + + Parameters: + flags - This is a bit-mapped flags value indicating + which resistors to enable or disable (see below). + + Return Values: + true if successful, false if not. + + Side Effects: + The resistors are enabled as requested. + + Remarks: + Used for USB peripheral control to connect to or + disconnect from the bus. Otherwise, used for OTG + SRP/HNP and host support. + + *************************************************************************/ + +/* + This routine is implemented as a macro to a lower-level level routine. + */ + #if defined(__18CXX) || defined(__XC8) + void USBHALControlUsbResistors( uint8_t flags ); + #else + #define USBHALControlUsbResistors OTGCORE_ControlUsbResistors + void USBHALControlUsbResistors( uint8_t flags ); +#endif + +/* + MCHP: Define a method to check for SE0 & a way to send a reset (SE0). + */ + + +/************************************************************************* + Function: + bool USBHALSessionIsValid( void ) + + Description: + This routine determines if there is currently a valid + USB session or not. + + Precondition: + USBInitialize must have been called to initialize the + USB SW stack. + + Parameters: + None + + Return Values: + true if the session is currently valid, false if not. + + Remarks: + Only used for host and OTG support. + + *************************************************************************/ + +bool USBHALSessionIsValid( void ); + + +/************************************************************************* + Function: + USBHALControlBusPower + + Description: + This routine provides a bitmap of the most recent + error conditions to occur. + + Precondition: + USBInitialize must have been called to initialize the + USB SW stack. + + Parameters: + cmd - Identifies desired command (see below). + + Return Values: + true if successful, false if not. + + Remarks: + Only used for host and OTG support. + + *************************************************************************/ + +bool USBHALControlBusPower( uint8_t cmd ); + +/************************************************************************* + Function: + unsigned long USBHALGetLastError( void ) + + Description: + This routine provides a bitmap of the most recent + error conditions to occur. + + Precondition: + USBInitialize must have been called to initialize the + USB SW stack. + + Parameters: + None + + Return Values: + Bitmap indicating the most recent error condition(s). + + Side Effect: + Error record is cleared. + + Remarks: + Although record of the error state is cleared, nothing + is done to fix the condition or recover from the + error. The client must take appropriate steps. + + *************************************************************************/ + +unsigned long USBHALGetLastError( void ); + + + + +/************************************************************************* + Function: + void USBHALHandleBusEvent ( void ) + + Description: + This routine checks the USB for any events that may + have occurred and handles them appropriately. It may + be called directly to poll the USB and handle events + or it may be called in response to an interrupt. + + Precondition: + USBInitialize must have been called to initialize the + USB SW stack. + + Parameters: + None + + Return Values: + None + + Side Effects: + Depend on the event that may have occurred. + + Remarks: + None + + *************************************************************************/ + +void USBHALHandleBusEvent ( void ); + + +/************************************************************************* + Function: + bool USBHALStallPipe( TRANSFER_FLAGS pipe ) + + Description: + This routine stalls the given endpoint. + + Preconditions: + USBHALInitialize must have been called to initialize + the USB HAL. + + Parameters: + pipe - Uses the TRANSFER_FLAGS (see USBCommon.h) format to + identify the endpoint and direction making up the + pipe to stall. + + Note: Only ep_num and direction fields are required. + + Return Values: + true if able to stall endpoint, false if not. + + Side Effects: + The endpoint will stall if additional data transfer is + attempted. + Given endpoint has been stalled. + + Remarks: + Starting another data transfer automatically + "un-stalls" the endpoint. + + *************************************************************************/ +/* + Note: This function is implemented as a macro, calling directly into + an internal HAL routine. + */ + +#define USBHALStallPipe OTGCORE_StallPipe + +bool USBHALStallPipe( TRANSFER_FLAGS pipe ); + + +/****************************************************************************** + Function: + bool USBHALUnstallPipe( TRANSFER_FLAGS pipe ) + + Description: + This routine clears the stall condition for the given pipe. + + PreCondition: + Assumes OTGCORE_DeviceEnable has been called and + OTGCORE_StallPipe has been called on the given pipe. + + Parameters: + pipe - Uses the TRANSFER_FLAGS (see USBCommon.h) format to + identify the endpoint and direction making up the + pipe to un-stall. + + Return Values: + true if able to stall the pipe, false if not. + + Side Effects: + The BSTALL and UOWN bits (and all other control bits) in + the BDT for the given pipe will be cleared. + + Remarks: + None + + *****************************************************************************/ +/* + Note: This function is implemented as a macro, calling directly into + an internal HAL routine. + */ + +#define USBHALUnstallPipe OTGCORE_UnstallPipe + +bool USBHALUnstallPipe( TRANSFER_FLAGS pipe ); + + +/************************************************************************** + Function: + USBHALGetStalledEndpoints + + Description: + This function returns a 16-bit bit-mapped value with a + bit set in the position of any endpoint that is stalled + (i.e. if endpoint 0 is stalled then bit 0 is set, if + endpoint 1 is stalled then bit 1 is set, etc.). + + Preconditions: + USBHALInitialize must have been called to initialize + the USB HAL. + + Parameters: + None + + Return Values: + Bitmap of the currently stalled endpoints (see overview). + + Remarks: + None + *************************************************************************/ + +/* + Note: This function is implemented as a macro, calling directly into + a HAL routine. + */ + +#define USBHALGetStalledEndpoints OTGCORE_GetStalledEndpoints + +uint16_t USBHALGetStalledEndpoints ( void ); + + +/****************************************************************************** + Function: + bool USBHALFlushPipe( TRANSFER_FLAGS pipe ) + + Description: + This routine clears any pending transfers on the given + pipe. + + Preconditions: + USBHALInitialize must have been called to initialize the + USB HAL. + + The caller must ensure that there is no possible way for + hardware to be currently accessing the pipe (see notes). + + Parameters: + pipe - Uses the TRANSFER_FLAGS (see USBCommon.h) format to + identify the endpoint and direction making up the + pipe to flush. + + Return Values: + true if successful, false if not. + + Side Effects: + Transfer data for this pipe has been zeroed out. + + Remarks: + This routine ignores the normal HW protocol for ownership + of the pipe data and flushes the pipe, even if it is in + process. Thus, the caller must ensure that data transfer + cannot be in process. This situation occurs when a + transfer has been terminated early by the host. + *****************************************************************************/ + +bool USBHALFlushPipe( TRANSFER_FLAGS pipe ); + + +/************************************************************************** + Function: + USBHALTransferData + + Description: + This routine prepares to transfer data on the USB. + If the system is in device mode, the actual transfer + will not occur until the host performs an OUT request + to the given endpoint. If the system is in host mode, + the transfer will not start until the token has been + sent on the bus. + + Preconditions: + 1. USBHALInitialize must have been called to + initialize the USB HAL. + 2. The endpoint through which the data will be + transferred must be configured as appropriate by a + call to USBHALSetEpConfiguration. + 3. The bus must have been enumerated (either as a host + or device). Except for EP0 transfers. + + Parameters: + flags - Flags consists of the endpoint number OR'd + with one or more flags indicating transfer + direction and such (see "Data Transfer + Macros" in USBCommon.h): + + 7 6 5 4 3 2 1 0 - Description + | | | | \_____/ + | | | | +----- Endpoint Number + | | | +---------- Short or zero-size packet + | | +------------ Data Toggle 0/1 + | +-------------- Force Data Toggle + +---------------- 1=Transmit/0=Receive + + buffer Address of the buffer to receive data. + + size Number of uint8_ts of data to transfer. + + Return Values: + true if the HAL was able to successfully start the + data transfer, false if not. + + Side Effects: + The HAL has prepared to transfer the data on the USB. + + Remarks: + The HAL will continue the data transfer, keeping track + of the buffer address, data remaining, and ping-pong + buffer details internally when USBHALHandleBusEvent is + called (either polled or in response to an interrupt). + The caller will receive notification that the transfer + has completed when the EVT_XFER event is passed into + the USBHALBusEventCallout call-out function. + + *************************************************************************/ + +bool USBHALTransferData ( TRANSFER_FLAGS flags, + void *buffer, + unsigned int size ); + + +/************************************************************************* + Function: + USBHALSetEpConfiguration + + Description: + This routine allows the caller to configure various + options (see "Flags for USBHALSetEpConfiguration", + below) and set the behavior for the given endpoint. + + Precondition: + USBHALInitialize has been called. + + Parameters: + ep_num - Number of endpoint to configure, Must be + (ep_num >=0) && (ep_num <= USB_DEV_HIGHEST_EP_NUMBER) + max_pkt_size Size of largest packet this enpoint can + transfer. + + flags - Configuration flags (see below) + + Return Values: + true if successful, false if not. + + Side Effects: + The endpoint has been configured as desired. + + Remarks: + The base address and size of the buffer is not set by + this routine. Those features of an endpoint are + dynamically managed by the USBHALTransferData routine. + An endpoint can be "de-configured" by setting its max + packet size to 0. When doing this, you should also + set all flags to 0. + *************************************************************************/ + +bool USBHALSetEpConfiguration ( uint8_t ep_num, uint16_t max_pkt_size, uint16_t flags ); + +/************************************************************************* + Function: + USBHALInitialize + + Description: + This call performs the basic initialization of the USB + HAL. This routine must be called before any of the + other HAL interface routines are called. + + Precondition: + The system has been initialized. + + Parameters: + flags - Initialization flags + + Return Values: + true if successful, false if not. + + Side Effects: + The USB HAL SW stack was initialized. + + Remarks: + This routine can be called to reset the controller. + + *************************************************************************/ + +bool USBHALInitialize ( unsigned long flags ); + + +#ifdef __cplusplus // Provide C++ Compatibility + } +#endif + +#endif // _USB_HAL_H_ +/************************************************************************* + * EOF + */ + diff --git a/usb/inc/usb_hal_local.h b/usb/inc/usb_hal_local.h new file mode 100644 index 0000000..cd79551 --- /dev/null +++ b/usb/inc/usb_hal_local.h @@ -0,0 +1,564 @@ +// 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 + +#ifndef _USB_HAL_LOCAL_H_ +#define _USB_HAL_LOCAL_H_ + +#include "usb.h" + +#if defined (__18CXX) || defined(__XC8) + #include "usb_pic18_local.h" +#elif defined (__C30__) || defined __XC16__ + #if defined (__dsPIC33EP512MU810__) + #include + #endif +#elif defined (__PIC32MX__) || defined (__PIC32MM__) + #include +#else + #error "Error! Unsupported processor" +#endif + +// Misc Definitions: + +#ifndef USB_DEVICE_ATTACH_DEBOUNCE_TIME + #define USB_DEVICE_ATTACH_DEBOUNCE_TIME 100 // 100 ms default time +#endif + +#ifndef LOCAL_INLINE + #define LOCAL_INLINE static inline +#endif + +#define OUT 0 // +#define IN 1 // + + +/* Endpoint control value and mask bits */ +#define EP_HSHK 0x01 // Enable handshake +#define EP_STALL 0x02 // Stall endpoint +#define EP_EP_TX_EN 0x04 // Enable transmitting from endpoint +#define EP_EP_RX_EN 0x08 // Enable receiving from endpoint +#define EP_EP_CTL_DIS 0x10 // Disable control transfers to/from endpoint +#define EP_RETRY_DIS 0x40 // (Host Only) No retry of NAK'd transactions +#define EP_HOST_WOHUB 0x80 // (Host Only) Allow connection to low-speed hub + +// Status mask +#if defined(__18CXX) || defined(__XC8) + + #define UIR_SOF_TOK (1<<6) + #define UIR_TOK_DNE (1<<3) + #define UIR_USB_RST (1<<0) + #define UIR_UERR (1<<1) + #define UIR_UIDLE (1<<4) + #define UIR_STALL (1<<5) + + #define STATUS_MASK (UIR_USB_RST|UIR_UERR|UIR_SOF_TOK|UIR_TOK_DNE| \ + UIR_UIDLE|UIR_STALL) + +#elif defined(__C30__) || defined __XC16__ + + // Status Bits + #define UIR_USB_RST 0x0001 + #define UIR_UERR 0x0002 + #define UIR_SOF_TOK 0x0004 + #define UIR_TOK_DNE 0x0008 + #define UIR_UIDLE 0x0010 + #define UIR_RESUME 0x0020 + #define UIR_ATTACH 0x0040 + #define UIR_STALL 0x0080 + + // Error Status Bits + #define UEIR_PID_ERR 0x0001 + #define UEIR_CRC5 0x0002 + #define UEIR_HOST_EOF 0x0002 + #define UEIR_CRC16 0x0004 + #define UEIR_DFN8 0x0008 + #define UEIR_BTO_ERR 0x0010 + #define UEIR_DMA_ERR 0x0020 + #define UEIR_BTS_ERR 0x0080 + +/* #define STATUS_MASK (UIR_USB_RST|UIR_UERR|UIR_SOF_TOK|UIR_TOK_DNE| \ + UIR_UIDLE|UIR_RESUME|UIR_ATTACH|UIR_STALL) */ + #define STATUS_MASK (UIR_USB_RST|UIR_UERR|UIR_TOK_DNE|UIR_STALL) + +#else + + // Status Bits + #define UIR_USB_RST 0x00000001 + #define UIR_UERR 0x00000002 + #define UIR_SOF_TOK 0x00000004 + #define UIR_TOK_DNE 0x00000008 + #define UIR_UIDLE 0x00000010 + #define UIR_RESUME 0x00000020 + #define UIR_ATTACH 0x00000040 + #define UIR_STALL 0x00000080 + + // Error Status Bits + #define UEIR_PID_ERR 0x00000001 + #define UEIR_CRC5 0x00000002 + #define UEIR_HOST_EOF 0x00000002 + #define UEIR_CRC16 0x00000004 + #define UEIR_DFN8 0x00000008 + #define UEIR_BTO_ERR 0x00000010 + #define UEIR_DMA_ERR 0x00000020 + #define UEIR_BTS_ERR 0x00000080 + + /*#define STATUS_MASK (UIR_USB_RST|UIR_UERR|UIR_SOF_TOK|UIR_TOK_DNE| \ + UIR_UIDLE|UIR_RESUME|UIR_ATTACH|UIR_STALL) */ + #define STATUS_MASK (UIR_USB_RST|UIR_UERR|UIR_TOK_DNE|UIR_STALL) + +#endif + + + +// Assumes HAL error flags are equal to USB OTG UEIR bits +// (see USBHALGetLastError and ErrorHandler). +#if( (USBHAL_PID_ERR != UEIR_PID_ERR ) || \ + (USBHAL_CRC5 != UEIR_CRC5 ) || \ + (USBHAL_HOST_EOF != UEIR_HOST_EOF) || \ + (USBHAL_CRC16 != UEIR_CRC16 ) || \ + (USBHAL_DFN8 != UEIR_DFN8 ) || \ + (USBHAL_BTO_ERR != UEIR_BTO_ERR ) || \ + (USBHAL_DMA_ERR != UEIR_DMA_ERR ) || \ + (USBHAL_BTS_ERR != UEIR_BTS_ERR ) ) +#error "USBHAL ErrorHandler must translate error flags" +#endif + +// Assumes HAL flags shifted left 8 match core control flags (see USBHALSetEpConfiguration). +#if( ((USB_HAL_HANDSHAKE >> 8) != EP_HSHK) || \ + ((USB_HAL_TRANSMIT >> 8) != EP_EP_TX_EN) || \ + ((USB_HAL_RECEIVE >> 8) != EP_EP_RX_EN) || \ + ((USB_HAL_NO_RETRY >> 8) != EP_RETRY_DIS) || \ + ((USB_HAL_ALLOW_HUB >> 8) != EP_HOST_WOHUB) ) +#error "USBHALSetEpConfiguration must translate control flags" +#endif + +#define ERROR_MASK (UEIR_PID_ERR|UEIR_CRC5|UEIR_HOST_EOF|UEIR_CRC16| \ + UEIR_DFN8|UEIR_BTO_ERR|UEIR_DMA_ERR|UEIR_BTS_ERR) + +#define CTRL_MASK (EP_HSHK|EP_EP_TX_EN|EP_EP_RX_EN|EP_RETRY_DIS|EP_HOST_WOHUB) + +#define RESISTOR_CTRL_MASK (UOTGCTRL_DM_LOW | UOTGCTRL_DP_LOW | \ + UOTGCTRL_DM_HIGH | UOTGCTRL_DP_HIGH) + +#define DATA_PTR_SIZE uint32_t + +// USBHALConfigureDescriptor flags +#define USBHAL_DESC_BSTALL 0x04 // Stall the endpoint. +#define USBHAL_DESC_DTS 0x08 // Require Data Toggle Synchronization +#define USBHAL_DESC_NINC 0x10 // No Incrementing of DMA address +#define USBHAL_DESC_KEEP 0x20 // HW keeps buffer & descriptor +#define USBHAL_DESC_DATA1 0x40 // Indicates data packet 1 +#define USBHAL_DESC_DATA0 0x00 // Indicates data packet 0 +#define USBHAL_DESC_UOWN 0x80 // USB HW owns buffer & descriptor + +/* Buffer Descriptor Table (BDT) definition + ************************************************************************* + * These data structures define the buffer descriptor table used by the + * USB OTG Core to manage endpoint DMA. + */ + +/* + * This is union describes the bitmap of + * the Setup & Status entry in the BDT. + */ +typedef union _BDT_SETUP +{ + struct // Status Entry + { + #if defined(__18CXX) || defined(__XC8) + unsigned short BC_MSB: 2; + #else + unsigned short spare: 2; + #endif + unsigned short TOK_PID: 4; // Packit Identifier + unsigned short DAT01: 1; // Data-toggle bit + unsigned short UOWN: 1; // Descriptor owner: 0=SW, 1=HW + #if !defined(__18CXX) && !defined(__XC8) + unsigned short resvd: 8; + #endif + }; + + struct // Setup Entry + { + #if defined(__18CXX) || defined(__XC8) + unsigned short BC_MSB: 2; + #else + unsigned short spare: 2; + #endif + unsigned short BSTALL: 1; // Stalls EP if this descriptor needed + unsigned short DTS: 1; // Require data-toggle sync + unsigned short NINC: 1; // No Increment of DMA address + unsigned short KEEP: 1; // HW Keeps this buffer & descriptor + unsigned short DAT01: 1; // Data-toggle number (0 or 1) + unsigned short UOWN: 1; // Descriptor owner: 0=SW, 1=HW + #if !defined(__18CXX) && !defined(__XC8) + unsigned short resvd: 8; + #endif + }; + + #if !defined(__18CXX) && !defined(__XC8) + uint16_t Val; + #else + uint8_t Val; + #endif + +} BDT_SETUP; + +/* + * This union describes the byte-count + * entry in the BDT. + */ +typedef union _uint8_tCOUNT +{ + struct // Byte-count bitmap + { + unsigned short BC0: 1; + unsigned short BC1: 1; + unsigned short BC2: 1; + unsigned short BC3: 1; + unsigned short BC4: 1; + unsigned short BC5: 1; + unsigned short BC6: 1; + unsigned short BC7: 1; + #if !defined(__18CXX) && !defined(__XC8) + unsigned short BC8: 1; + unsigned short BC9: 1; + unsigned short resvd: 6; + #endif + }; + + #if defined(__18CXX) || defined(__XC8) + //MCHP - here BC is only an unsigned char. This is not large enough for larger transfers + struct // Byte-count field + { + unsigned char BC; // Number of bytes in data buffer (really only 10 bits) + }; + #else + struct // Byte-count field + { + unsigned short BC: 10; // Number of bytes in data buffer + unsigned short resvd: 6; + }; + #endif + +} uint8_tCOUNT; + +/* + * Buffer Descriptor + * + * This union describes a single buffer descriptor. Each descriptor + * manages a single buffer. Each endpoint has 4 such descriptors, 2 + * for receive and 2 for trasmit. Having two descriptors (odd and even, + * or ping and pong) per direction allows the HW to operate on one + * while the SW operates on the other. + */ +typedef union _BUFFER_DESCRIPTOR +{ + uint32_t dword[2]; // Double-word access + + uint16_t word[4]; // Word Access + + uint8_t byte[8]; // Byte Access + + struct + { + BDT_SETUP setup; // Setup & status entry + uint8_tCOUNT byte_cnt; // Byte count entry + unsigned int addr; // Physical address of data buffer + }; + +} BUF_DESC, *pBUF_DESC; + + +/* USB_HAL_PIPE + ************************************************************************* + * A pipe is a virtual connection between two endpoints, one in the host + * and one the device. Data flows through a pipe in a single direction + * from one endpoint to the other. This structure defines the data that + * the USB HAL must track to manage a pipe. + */ + +typedef union +{ + uint8_t bitmap; + + struct + { + uint8_t zero_pkt: 1; // Ensure transfer ends w/short or zero packet + uint8_t data_toggle: 1; // Data toggle: 0=DATA0/1=DATA1 + uint8_t ping_pong: 1; // Current ping pong: 0=even/1=odd + uint8_t send_0_pkt: 1; // Flag indicating when to send a zero-sized packet + uint8_t reserved: 4; // Reserved + + }field; + +}PIPE_FLAGS; + +typedef struct _USB_HAL_PIPE_DATA +{ + uint8_t *buffer; // Pointer to the buffer + unsigned int max_pkt_size; // Max packet size of EP + unsigned int size; // Total number of bytes to transfer + unsigned int remaining; // Number of bytes remaining to transfer + unsigned int count; // Actual number of bytes transferred. + PIPE_FLAGS flags; + +} USB_HAL_PIPE, *PUSB_HAL_PIPE; + + +/* USB_ROLE + ************************************************************************* + * This enumeration identifies if the USB controller is currently acting + * as a USB device or as a USB host. + */ + +typedef enum +{ + DEVICE = 0, // USB controller is acting as a USB device + HOST = 1 // USB controller is acting as a USB host + +} USB_ROLE; + + +/****************************************************************************** + Function: + OTGCORE_IdentifyPacket + + Summary: + This provides the endpoint number, direction and ping-pong ID and other + information identifying the packet that was just completed. + + PreCondition: + Assumes that an UIR_TOK_DNE interrupt has occured. + + Parameters: + None + + Return Values: + flags Bitmapped flags identifying transfer (see below): + + 1 1 1 1 1 1 + 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 + | | \_____/ \_/ \_____/ | | \_/ + | | | | | | | +-- reserved1 + | | | | | | +----- ping_pong + | | | | | +------- direction + | | | | +------------ ep_num + | | | +------------------ reserved2 + | | +------------------------ pid + | +----------------------------- data_toggle + +------------------------------- reserved3 + + size Size of data actually transferred (in bytes). + TRUE if successful, FALSE any of the parameters were NULL. + + Remarks: + None + + ******************************************************************************/ + +typedef union +{ + uint16_t bitmap; + uint8_t byte[2]; + struct + { + // Byte 0 + uint16_t reserved1: 2; // Reserved, ignore + uint16_t ping_pong: 1; // Buffer ping pong: 0=even/1=odd + uint16_t direction: 1; // Transfer direction: 0=Receive, 1=Transmit + uint16_t ep_num: 4; // Endpoint number + + // Byte 1 + uint16_t reserved2: 2; // Reserved, ignore + uint16_t pid: 4; // Packet ID (See USBCh9.h, "Packet IDs") + uint16_t data_toggle: 1; // Data toggle: 0=DATA0 packet, 1=DATA1 packet + uint16_t reserved3: 1; // Reserved, ignore + + }field; + +} TRANSFER_ID_FLAGS; + + +/* USB Register Macros + ************************************************************************* + * These macros translate core registers across the different controller + * families. + */ + +#if defined(__18CXX) || defined(__XC8) + #if defined(__18F4550) || defined(__18F2455) || defined(__18F2550) || defined(__18F4455) + #error "Please define any necessary register translation macros." + #endif + + #define EnableUsbModule() + #define SetPingPongMode(m) U1CNFG1 |= (m) + + #error "Please define any necessary register translation macros." +#elif defined(__C30__) || defined __XC16__ + + #define EnableUsbModule() U1PWRCbits.USBPWR = 1 + #define SetPingPongMode(m) + + // Do we need any others??? #error "Please define any necessary register translation macros. +#else + #define EnableUsbModule() U1PWRCbits.USBPWR = 1 + #define SetPingPongMode(m) +#endif + +// Misc bits +#ifndef UPWRC_USB_OP_EN +#define UPWRC_USB_OP_EN 0x01 // USB Operation Enable +#endif + +#ifndef UPWRC_SUSPEND +#define UPWRC_SUSPEND 0x02 // Suspend bus activity +#endif + + + +/* USB_HAL_DATA + ************************************************************************* + * This structure contains the data that is required to manage an + * instance of the USB HAL. + */ + +/*#if defined( USB_SUPPORT_DEVICE ) + + typedef struct _USB_HAL_DATA + { + // Data transfer "pipe" array + USB_HAL_PIPE pipe[USB_DEV_HIGHEST_EP_NUMBER+1][2]; // Rx=0, Tx=1 + USB_ROLE current_role; // Acting as host or device? + unsigned long last_error; // Last error state detected + } USB_HAL_DATA, *PUSB_HAL_DATA; + + + // Macro to get a pointer to the desired pipe data. + #define FindPipe(e,d) &gHALData.pipe[(e)][(d)] + +#endif // defined( USB_SUPPORT_DEVICE )*/ + + +/****************************************************************************** + Function: + USBHALClearStatus + + Summary: + This routine clears the OTG Core's current status + + PreCondition: + None + + Parameters: + status Bitmap of status bits to clear (caller sets bits it + wishes to be cleared). + + Return Values: + None + + Remarks: + The status indicated have been cleared. + + ******************************************************************************/ + +#define USBHALClearStatus(s) (U1IR = (s)) + + +/****************************************************************************** + Function: + USBHALGetStatus + + Summary: + This routine reads the OTG Core's current status. + + PreCondition: + None + + Parameters: + None + + Return Values: + The contents of the USB OTG Core's interrupt status register. + + Remarks: + None + + ******************************************************************************/ + +#define USBHALGetStatus() U1IR + + +/****************************************************************************** + Function: + USBHALGetErrors + + Summary: + This routine reads the current error status. + + PreCondition: + None + + Parameters: + None + + Return Values: + The contents of the USB error-interrupt status register. + + Remarks: + None + + ******************************************************************************/ +#define USBHALGetErrors() U1EIR + + +/****************************************************************************** + Function: + USBHALClearErrors + + Summary: + This clears given error status. + + PreCondition: + None + + Paramters: + errors - Bitmap of the error status bits (caller sets the bets + it wishes to clear). + + Return Values: + None + + Side effects: + The errors indicated have been cleared. + + Remarks: + None + + ******************************************************************************/ +#define USBHALClearErrors(e) (U1EIR = (e)) + + +#endif // _USB_HAL_LOCAL_H_ +/************************************************************************* + * EOF usb_hal.h + */ + diff --git a/usb/inc/usb_hal_pic18.h b/usb/inc/usb_hal_pic18.h new file mode 100644 index 0000000..b666a71 --- /dev/null +++ b/usb/inc/usb_hal_pic18.h @@ -0,0 +1,611 @@ +// 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 + +#ifndef _USB_HAL_PIC18_H +#define _USB_HAL_PIC18_H + +// ***************************************************************************** +// ***************************************************************************** +// Section: Included Files +// ***************************************************************************** +// ***************************************************************************** +/* This section lists the other files that are included in this file. +*/ +#if defined(__XC8) + #include + #include +#elif defined(__C18) + #include + #ifndef uint8_t + #define uint8_t unsigned char + #endif + #ifndef uint16_t + #define uint16_t unsigned int + #endif + #ifndef uint32_t + #define uint32_t unsigned long int + #endif +#endif + +#include + +#include "usb_config.h" + +#ifdef __cplusplus // Provide C++ Compatability + extern "C" { +#endif + +// ***************************************************************************** +// ***************************************************************************** +// Section: Constants +// ***************************************************************************** +// ***************************************************************************** +#define USB_HAL_VBUSTristate() //No dedicated VBUS pin on these devices. + +//----- USBEnableEndpoint() input definitions ---------------------------------- +#define USB_HANDSHAKE_ENABLED 0x10 +#define USB_HANDSHAKE_DISABLED 0x00 + +#define USB_OUT_ENABLED 0x04 +#define USB_OUT_DISABLED 0x00 + +#define USB_IN_ENABLED 0x02 +#define USB_IN_DISABLED 0x00 + +#define USB_ALLOW_SETUP 0x00 +#define USB_DISALLOW_SETUP 0x08 + +#define USB_STALL_ENDPOINT 0x01 + +//----- usb_config.h input definitions ----------------------------------------- +#define USB_PULLUP_ENABLE 0x10 +#define USB_PULLUP_DISABLED 0x00 + +#define USB_INTERNAL_TRANSCEIVER 0x00 +#define USB_EXTERNAL_TRANSCEIVER 0x08 + +#define USB_FULL_SPEED 0x04 +#define USB_LOW_SPEED 0x00 + +//----- Interrupt Flag definitions -------------------------------------------- +#define USBTransactionCompleteIE UIEbits.TRNIE +#define USBTransactionCompleteIF UIRbits.TRNIF +#define USBTransactionCompleteIFReg UIR +#define USBTransactionCompleteIFBitNum 0xF7 //AND mask for clearing TRNIF bit position 4 + +#define USBResetIE UIEbits.URSTIE +#define USBResetIF UIRbits.URSTIF +#define USBResetIFReg UIR +#define USBResetIFBitNum 0xFE //AND mask for clearing URSTIF bit position 0 + +#define USBIdleIE UIEbits.IDLEIE +#define USBIdleIF UIRbits.IDLEIF +#define USBIdleIFReg UIR +#define USBIdleIFBitNum 0xEF //AND mask for clearing IDLEIF bit position 5 + +#define USBActivityIE UIEbits.ACTVIE +#define USBActivityIF UIRbits.ACTVIF +#define USBActivityIFReg UIR +#define USBActivityIFBitNum 0xFB //AND mask for clearing ACTVIF bit position 2 + +#define USBSOFIE UIEbits.SOFIE +#define USBSOFIF UIRbits.SOFIF +#define USBSOFIFReg UIR +#define USBSOFIFBitNum 0xBF //AND mask for clearing SOFIF bit position 6 + +#define USBStallIE UIEbits.STALLIE +#define USBStallIF UIRbits.STALLIF +#define USBStallIFReg UIR +#define USBStallIFBitNum 0xDF //AND mask for clearing STALLIF bit position 5 + +#define USBErrorIE UIEbits.UERRIE +#define USBErrorIF UIRbits.UERRIF +#define USBErrorIFReg UIR +#define USBErrorIFBitNum 0xFD //UERRIF bit position 1. Note: This bit is read only and is cleared by clearing the enabled UEIR flags + +//----- Event call back defintions -------------------------------------------- +#if defined(USB_DISABLE_SOF_HANDLER) + #define USB_SOF_INTERRUPT 0x00 +#else + #define USB_SOF_INTERRUPT 0x40 +#endif + +#if defined(USB_DISABLE_ERROR_HANDLER) + #define USB_ERROR_INTERRUPT 0x02 +#else + #define USB_ERROR_INTERRUPT 0x02 +#endif + +//----- USB module control bits ----------------------------------------------- +#define USBPingPongBufferReset UCONbits.PPBRST +#define USBSE0Event UCONbits.SE0 +#define USBSuspendControl UCONbits.SUSPND +#define USBPacketDisable UCONbits.PKTDIS +#define USBResumeControl UCONbits.RESUME + +//----- BDnSTAT bit definitions ----------------------------------------------- +#define _BSTALL 0x04 //Buffer Stall enable +#define _DTSEN 0x08 //Data Toggle Synch enable +#define _INCDIS 0x10 //Address increment disable +#define _KEN 0x20 //SIE keeps buff descriptors enable +#define _DAT0 0x00 //DATA0 packet expected next +#define _DAT1 0x40 //DATA1 packet expected next +#define _DTSMASK 0x40 //DTS Mask +#define _USIE 0x80 //SIE owns buffer +#define _UCPU 0x00 //CPU owns buffer +#define _STAT_MASK 0xFF + +#define USTAT_EP0_PP_MASK ~0x02 +#define USTAT_EP_MASK 0x7E +#define USTAT_EP0_OUT 0x00 +#define USTAT_EP0_OUT_EVEN 0x00 +#define USTAT_EP0_OUT_ODD 0x02 +#define USTAT_EP0_IN 0x04 +#define USTAT_EP0_IN_EVEN 0x04 +#define USTAT_EP0_IN_ODD 0x06 + +#define ENDPOINT_MASK 0b01111000 + +//----- U1EP bit definitions -------------------------------------------------- +#define UEP_STALL 0x0001 +// Cfg Control pipe for this ep +/* Endpoint configuration options for USBEnableEndpoint() function */ +#define EP_CTRL 0x06 // Cfg Control pipe for this ep +#define EP_OUT 0x0C // Cfg OUT only pipe for this ep +#define EP_IN 0x0A // Cfg IN only pipe for this ep +#define EP_OUT_IN 0x0E // Cfg both OUT & IN pipes for this ep + +//----- Remap the PIC18 register name space------------------------------------ +#define U1ADDR UADDR +#define U1IE UIE +#define U1IR UIR +#define U1EIR UEIR +#define U1EIE UEIE +#define U1CON UCON +#define U1EP0 UEP0 +#define U1CONbits UCONbits +#define U1EP1 UEP1 +#define U1CNFG1 UCFG +#define U1STAT USTAT +#define U1EP0bits UEP0bits + +//----- Defintions for BDT address -------------------------------------------- +#if defined(__16F1454) || defined(__16F1455) || defined(__16F1459) || defined(__16LF1454) || defined(__16LF1455) || defined(__16LF1459) + #define USB_BDT_ADDRESS 0x020 +#elif defined(__18F14K50) || defined(__18F13K50) || defined(__18LF14K50) || defined(__18LF13K50) + #define USB_BDT_ADDRESS 0x200 //See Linker Script, BDT in bank 2 on these devices - usb2:0x200-0x2FF(256-byte) +#elif defined(__18F24K50) || defined(__18F25K50) || defined(__18F45K50) || defined(__18LF24K50) || defined(__18LF25K50) || defined(__18LF45K50) + #define USB_BDT_ADDRESS 0x400 //See Linker Script, BDT in bank 4 +#elif defined(__18F47J53) || defined(__18F46J53) || defined(__18F27J53) || defined(__18F26J53) || defined(__18LF47J53) || defined(__18LF46J53) || defined(__18LF27J53) || defined(__18LF26J53) + #define USB_BDT_ADDRESS 0xD00 //BDT in Bank 13 on these devices +#elif defined(__18F97J94) || defined(__18F87J94) || defined(__18F67J94) || defined(__18F96J94) || defined(__18F86J94) || defined(__18F66J94) || defined(__18F96J99) || defined(__18F95J94) || defined(__18F86J99) || defined(__18F85J94) || defined(__18F66J99) || defined(__18F65J94) + #define USB_BDT_ADDRESS 0x100 //BDT in Bank 1 on these devices +#else + #define USB_BDT_ADDRESS 0x400 //All other PIC18 devices place the BDT in usb4:0x400-0x4FF(256-byte) +#endif + +#if (USB_PING_PONG_MODE == USB_PING_PONG__NO_PING_PONG) + #define BDT_NUM_ENTRIES ((USB_MAX_EP_NUMBER + 1) * 2) +#elif (USB_PING_PONG_MODE == USB_PING_PONG__EP0_OUT_ONLY) + #define BDT_NUM_ENTRIES (((USB_MAX_EP_NUMBER + 1) * 2)+1) +#elif (USB_PING_PONG_MODE == USB_PING_PONG__FULL_PING_PONG) + #define BDT_NUM_ENTRIES ((USB_MAX_EP_NUMBER + 1) * 4) +#elif (USB_PING_PONG_MODE == USB_PING_PONG__ALL_BUT_EP0) + #define BDT_NUM_ENTRIES (((USB_MAX_EP_NUMBER + 1) * 4)-2) +#else + #error "No ping pong mode defined." +#endif + +#if defined(__XC8) + #define CTRL_TRF_SETUP_ADDRESS (USB_BDT_ADDRESS+(BDT_NUM_ENTRIES*4)) + #define CTRL_TRF_DATA_ADDRESS (CTRL_TRF_SETUP_ADDRESS + USB_EP0_BUFF_SIZE) + + #define BDT_BASE_ADDR_TAG @USB_BDT_ADDRESS + #define CTRL_TRF_SETUP_ADDR_TAG @CTRL_TRF_SETUP_ADDRESS + #define CTRL_TRF_DATA_ADDR_TAG @CTRL_TRF_DATA_ADDRESS + + #if defined(USB_USE_MSD) + //MSD application specific USB endpoint buffer placement macros (so they + //get linked to a USB module accessible portion of RAM) + #define MSD_CBW_ADDRESS (CTRL_TRF_DATA_ADDRESS + USB_EP0_BUFF_SIZE) + #define MSD_CSW_ADDRESS (MSD_CBW_ADDRESS + MSD_OUT_EP_SIZE) + #define MSD_CBW_ADDR_TAG @MSD_CBW_ADDRESS + #define MSD_CSW_ADDR_TAG @MSD_CSW_ADDRESS + #endif +#else + #define BDT_BASE_ADDR_TAG __attribute__ ((aligned (512))) + #define CTRL_TRF_SETUP_ADDR_TAG + #define CTRL_TRF_DATA_ADDR_TAG + #define MSD_CBW_ADDR_TAG + #define MSD_CSW_ADDR_TAG +#endif + +//----- Deprecated definitions - will be removed at some point of time---------- +//--------- Deprecated in v2.2 +#define _LS 0x00 // Use Low-Speed USB Mode +#define _FS 0x04 // Use Full-Speed USB Mode +#define _TRINT 0x00 // Use internal transceiver +#define _TREXT 0x08 // Use external transceiver +#define _PUEN 0x10 // Use internal pull-up resistor +#define _OEMON 0x40 // Use SIE output indicator + +// ***************************************************************************** +// ***************************************************************************** +// Section: Data Types +// ***************************************************************************** +// ***************************************************************************** + +// Buffer Descriptor Status Register layout. +typedef union _BD_STAT +{ + uint8_t Val; + struct{ + //If the CPU owns the buffer then these are the values + unsigned BC8:1; //bit 8 of the byte count + unsigned BC9:1; //bit 9 of the byte count + unsigned BSTALL:1; //Buffer Stall Enable + unsigned DTSEN:1; //Data Toggle Synch Enable + unsigned INCDIS:1; //Address Increment Disable + unsigned KEN:1; //BD Keep Enable + unsigned DTS:1; //Data Toggle Synch Value + unsigned UOWN:1; //USB Ownership + }; + struct{ + //if the USB module owns the buffer then these are + // the values + unsigned :2; + unsigned PID0:1; //Packet Identifier + unsigned PID1:1; + unsigned PID2:1; + unsigned PID3:1; + unsigned :1; + }; + struct{ + unsigned :2; + unsigned PID:4; //Packet Identifier + unsigned :2; + }; +} BD_STAT; //Buffer Descriptor Status Register + +// BDT Entry Layout +typedef union __BDT +{ + struct + { + BD_STAT STAT; + uint8_t CNT; + uint8_t ADRL; //Buffer Address Low + uint8_t ADRH; //Buffer Address High + }; + struct + { + unsigned :8; + unsigned :8; + uint16_t ADR; //Buffer Address + }; + uint32_t Val; + uint8_t v[4]; +} BDT_ENTRY; + +// USTAT Register Layout +typedef union __USTAT +{ + struct + { + unsigned char filler1:1; + unsigned char ping_pong:1; + unsigned char direction:1; + unsigned char endpoint_number:4; + }; + uint8_t Val; +} USTAT_FIELDS; + +//Macros for fetching parameters from a USTAT_FIELDS variable. +#define USBHALGetLastEndpoint(stat) stat.endpoint_number +#define USBHALGetLastDirection(stat) stat.direction +#define USBHALGetLastPingPong(stat) stat.ping_pong + + +typedef union _POINTER +{ + struct + { + uint8_t bLow; + uint8_t bHigh; + //byte bUpper; + }; + uint16_t _word; // bLow & bHigh + + //pFunc _pFunc; // Usage: ptr.pFunc(); Init: ptr.pFunc = &; + + uint8_t* bRam; // Ram byte pointer: 2 bytes pointer pointing + // to 1 byte of data + uint16_t* wRam; // Ram word poitner: 2 bytes poitner pointing + // to 2 bytes of data + + const uint8_t* bRom; // Size depends on compiler setting + const uint16_t* wRom; + //rom near byte* nbRom; // Near = 2 bytes pointer + //rom near word* nwRom; + //rom far byte* fbRom; // Far = 3 bytes pointer + //rom far word* fwRom; +} POINTER; + +// ***************************************************************************** +// ***************************************************************************** +// Section: Interface Routines +// ***************************************************************************** +// ***************************************************************************** + +#define ConvertToPhysicalAddress(a) ((uint16_t)(a)) +#define ConvertToVirtualAddress(a) ((void *)(a)) + + +//------------------------------------------------------------------------------ +//This section is for the PIC18F45K50 Family microcontrollers +//------------------------------------------------------------------------------ +#if defined(__18F45K50) || defined(__18F25K50) || defined(__18F24K50) || defined(__18LF45K50) || defined(__18LF25K50) || defined(__18LF24K50) + #define USBClearUSBInterrupt() PIR3bits.USBIF = 0; + #if defined(USB_INTERRUPT) + #define USBMaskInterrupts() {PIE3bits.USBIE = 0;} + #define USBUnmaskInterrupts() {PIE3bits.USBIE = 1;} + #else + #define USBMaskInterrupts() + #define USBUnmaskInterrupts() + #endif + + #define USBInterruptFlag PIR3bits.USBIF + + //STALLIE, IDLEIE, TRNIE, and URSTIE are all enabled by default and are required + #if defined(USB_INTERRUPT) + #define USBEnableInterrupts() {RCONbits.IPEN = 1;IPR3bits.USBIP = 1;PIE3bits.USBIE = 1;INTCONbits.GIEH = 1;} + #else + #define USBEnableInterrupts() + #endif + + #define USBDisableInterrupts() {PIE3bits.USBIE = 0;} + + #define SetConfigurationOptions() {\ + U1CNFG1 = USB_PULLUP_OPTION | USB_TRANSCEIVER_OPTION | USB_SPEED_OPTION | USB_PING_PONG_MODE;\ + U1EIE = 0x9F;\ + UIE = 0x39 | USB_SOF_INTERRUPT | USB_ERROR_INTERRUPT;\ + } + +//------------------------------------------------------------------------------ +//This section is for the PIC16F145x Family Microcontrollers +//------------------------------------------------------------------------------ +#elif defined(__16F1454) || defined(__16F1455) || defined(__16F1459) || defined(__16LF1454) || defined(__16LF1455) || defined(__16LF1459) + #define USBClearUSBInterrupt() PIR2bits.USBIF = 0; + #if defined(USB_INTERRUPT) + #define USBMaskInterrupts() {PIE2bits.USBIE = 0;} + #define USBUnmaskInterrupts() {PIE2bits.USBIE = 1;} + #else + #define USBMaskInterrupts() + #define USBUnmaskInterrupts() + #endif + + #define USBInterruptFlag PIR2bits.USBIF + + //STALLIE, IDLEIE, TRNIE, and URSTIE are all enabled by default and are required + #if defined(USB_INTERRUPT) + #define USBEnableInterrupts() {PIE2bits.USBIE = 1;INTCONbits.PEIE = 1;INTCONbits.GIE = 1;} + #else + #define USBEnableInterrupts() + #endif + + #define USBDisableInterrupts() {PIE2bits.USBIE = 0;} + + #define SetConfigurationOptions() {\ + U1CNFG1 = USB_PULLUP_OPTION | USB_TRANSCEIVER_OPTION | USB_SPEED_OPTION | USB_PING_PONG_MODE;\ + U1EIE = 0x9F;\ + UIE = 0x39 | USB_SOF_INTERRUPT | USB_ERROR_INTERRUPT;\ + } +#else +//------------------------------------------------------------------------------ +//This section is for all other PIC18 USB microcontrollers +//------------------------------------------------------------------------------ + #define USBClearUSBInterrupt() {PIR2bits.USBIF = 0;} + #if defined(USB_INTERRUPT) + #define USBMaskInterrupts() {PIE2bits.USBIE = 0;} + #define USBUnmaskInterrupts() {PIE2bits.USBIE = 1;} + #else + #define USBMaskInterrupts() + #define USBUnmaskInterrupts() + #endif + + #define USBInterruptFlag PIR2bits.USBIF + + //STALLIE, IDLEIE, TRNIE, and URSTIE are all enabled by default and are required + #if defined(USB_INTERRUPT) + #define USBEnableInterrupts() {RCONbits.IPEN = 1;IPR2bits.USBIP = 1;PIE2bits.USBIE = 1;INTCONbits.GIEH = 1;} + #else + #define USBEnableInterrupts() + #endif + + #define USBDisableInterrupts() {PIE2bits.USBIE = 0;} + + #define SetConfigurationOptions() {\ + U1CNFG1 = USB_PULLUP_OPTION | USB_TRANSCEIVER_OPTION | USB_SPEED_OPTION | USB_PING_PONG_MODE;\ + U1EIE = 0x9F;\ + UIE = 0x39 | USB_SOF_INTERRUPT | USB_ERROR_INTERRUPT;\ + } +#endif //end of #if defined(__18F45K50) || defined(__18F25K50)... +//------------------------------------------------------------------------------ + + +/**************************************************************** + Function: + void USBPowerModule(void) + + Description: + This macro is used to power up the USB module if required
+ PIC18: defines as nothing
+ PIC24: defines as U1PWRCbits.USBPWR = 1;
+ + Parameters: + None + + Return Values: + None + + Remarks: + None + + ****************************************************************/ +#define USBPowerModule() + +/**************************************************************** + Function: + void USBModuleDisable(void) + + Description: + This macro is used to disable the USB module + + Parameters: + None + + Return Values: + None + + Remarks: + None + + ****************************************************************/ +#define USBModuleDisable() {\ + UCON = 0;\ + UIE = 0;\ + USBDeviceState = DETACHED_STATE;\ +} + +/**************************************************************** + Function: + USBSetBDTAddress(addr) + + Description: + This macro is used to power up the USB module if required + + Parameters: + None + + Return Values: + None + + Remarks: + None + + ****************************************************************/ +#define USBSetBDTAddress(addr) + +/******************************************************************** + * Function (macro): void USBClearInterruptFlag(register, uint8_t if_and_flag_mask) + * + * PreCondition: None + * + * Input: + * register - the register mnemonic for the register holding the interrupt + flag to be cleared + * uint8_t if_and_flag_mask - an AND mask for the interrupt flag that will be + cleared + * + * Output: None + * + * Side Effects: None + * + * Overview: Clears the specified USB interrupt flag. + * + * Note: + *******************************************************************/ +#define USBClearInterruptFlag(reg_name, if_and_flag_mask) (reg_name &= if_and_flag_mask) + +/******************************************************************** + Function: + void USBClearInterruptRegister(uint16_t reg) + + Summary: + Clears the specified interrupt register + + PreCondition: + None + + Parameters: + uint16_t reg - the register name that needs to be cleared + + Return Values: + None + + Remarks: + None + + *******************************************************************/ +#define USBClearInterruptRegister(reg) {reg = 0;} + +/******************************************************************** + Function: + void DisableNonZeroEndpoints(UINT8 last_ep_num) + + Summary: + Clears the control registers for the specified non-zero endpoints + + PreCondition: + None + + Parameters: + UINT8 last_ep_num - the last endpoint number to clear. This + number should include all endpoints used in any configuration. + + Return Values: + None + + Remarks: + None + + *******************************************************************/ +#define DisableNonZeroEndpoints(last_ep_num) memset((void*)&U1EP1,0x00,(last_ep_num)); + +/*****************************************************************************/ +/****** Compiler checks ******************************************************/ +/*****************************************************************************/ + +//Definitions for the BDT +#ifndef USB_PING_PONG_MODE + #error "No ping pong mode defined." +#endif + +/*****************************************************************************/ +/****** Extern variable definitions ******************************************/ +/*****************************************************************************/ + +#if !defined(USBDEVICE_C) + extern USB_VOLATILE uint8_t USBActiveConfiguration; + extern USB_VOLATILE IN_PIPE inPipes[1]; + extern USB_VOLATILE OUT_PIPE outPipes[1]; +#endif + +extern volatile BDT_ENTRY* pBDTEntryOut[USB_MAX_EP_NUMBER+1]; +extern volatile BDT_ENTRY* pBDTEntryIn[USB_MAX_EP_NUMBER+1]; + +#ifdef __cplusplus // Provide C++ Compatibility + } +#endif + +#endif //#ifndef _USB_HAL_PIC18_H + + diff --git a/usb/inc/usb_hid.h b/usb/inc/usb_hid.h new file mode 100644 index 0000000..3cdcd14 --- /dev/null +++ b/usb/inc/usb_hid.h @@ -0,0 +1,1945 @@ +// 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 + +#ifndef USB_HID_H +#define USB_HID_H + +#define USB_HID_CLASS_CODE 0x03 + +typedef struct __attribute__((packed)) +{ + uint8_t bLength; + uint8_t bDescriptorType; + uint16_t bcdHID; + uint8_t bCountryCode; + uint8_t bNumDescriptors; +} USB_HID_DESCRIPTOR; + +typedef struct __attribute__((packed)) +{ + uint8_t bDescriptorType; + uint16_t wDescriptorLength; +} USB_HID_DESCRIPTOR_SUBORDINATE; + +typedef struct __attribute__((packed)) +{ + unsigned bSize :2; + unsigned bType :2; + unsigned bTag :4; +} USB_HID_REPORT_ITEM_HEADER_SHORT; + +typedef struct __attribute__((packed)) +{ + unsigned bSize :2; + unsigned bType :2; + unsigned bTag :4; + uint8_t bDataSize; + uint8_t bLongItemTag; +} USB_HID_REPORT_ITEM_HEADER_LONG; + +typedef enum +{ + USB_HID_DESCRIPTOR_TYPES_HID = 0x21, + USB_HID_DESCRIPTOR_TYPES_REPORT = 0x22, + USB_HID_DESCRIPTOR_TYPES_PHYSICAL_DESCRIPTOR = 0x23 + /* Reserved = 0x24-0x2F */ +} USB_HID_DESCRIPTOR_TYPES; + +typedef enum +{ + USB_HID_REQUESTS_GET_REPORT = 0x01, + USB_HID_REQUESTS_GET_IDLE = 0x02, + USB_HID_REQUESTS_GET_PROTOCOL = 0x03, + /* Reserved = 0x04-0x08 */ + USB_HID_REQUESTS_SET_REPORT = 0x09, + USB_HID_REQUESTS_SET_IDLE = 0x0A, + USB_HID_REQUESTS_SET_PROTOCOL = 0x0B +} USB_HID_REQUESTS; + +typedef enum +{ + USB_HID_REPORT_TYPE_INPUT = 0x01, + USB_HID_REPORT_TYPE_OUTPUT = 0x02, + USB_HID_REPORT_TYPE_FEATURE = 0x03 + /* Reserved = 0x04-0xFF */ +} USB_HID_REPORT_TYPE; + + + +typedef enum +{ + USB_HID_REPORT_ITEM_HEADER_BTYPE_MAIN = 0, + USB_HID_REPORT_ITEM_HEADER_BTYPE_GLOBAL = 1, + USB_HID_REPORT_ITEM_HEADER_BTYPE_LOCAL = 2, + USB_HID_REPORT_ITEM_HEADER_BTYPE_RESERVED = 3 +} USB_HID_REPORT_ITEM_HEADER_BTYPE; + +typedef enum +{ + USB_HID_COUNTRY_CODE_NOT_SUPPORTED = 0, + USB_HID_COUNTRY_CODE_ARABIC = 1, + USB_HID_COUNTRY_CODE_BELGIAN = 2, + USB_HID_COUNTRY_CODE_CANADIAN_BILINGUAL = 3, + USB_HID_COUNTRY_CODE_CANADIAN_FRENCH = 4, + USB_HID_COUNTRY_CODE_CZECH_REPUBLIC = 5, + USB_HID_COUNTRY_CODE_DANISH = 6, + USB_HID_COUNTRY_CODE_FINNISH = 7, + USB_HID_COUNTRY_CODE_FRENCH = 8, + USB_HID_COUNTRY_CODE_GERMAN = 9, + USB_HID_COUNTRY_CODE_GREEK = 10, + USB_HID_COUNTRY_CODE_HEBREW = 11, + USB_HID_COUNTRY_CODE_HUNGARY = 12, + USB_HID_COUNTRY_CODE_INTERNATIONAL_ISO = 13, + USB_HID_COUNTRY_CODE_ITALIAN = 14, + USB_HID_COUNTRY_CODE_JAPAN_KATAKANA = 15, + USB_HID_COUNTRY_CODE_KOREAN = 16, + USB_HID_COUNTRY_CODE_LATIN_AMERICAN = 17, + USB_HID_COUNTRY_CODE_NETHERLANDS_DUTCH = 18, + USB_HID_COUNTRY_CODE_NORWEGIAN = 19, + USB_HID_COUNTRY_CODE_PERSIAN_FARSI = 20, + USB_HID_COUNTRY_CODE_POLAND = 21, + USB_HID_COUNTRY_CODE_PORTUGUESE = 22, + USB_HID_COUNTRY_CODE_RUSSIA = 23, + USB_HID_COUNTRY_CODE_SLOVAKIA = 24, + USB_HID_COUNTRY_CODE_SPANISH = 25, + USB_HID_COUNTRY_CODE_SWEDISH = 26, + USB_HID_COUNTRY_CODE_SWISS_FRENCH = 27, + USB_HID_COUNTRY_CODE_SWISS_GERMAN = 28, + USB_HID_COUNTRY_CODE_SWITZERLAND = 29, + USB_HID_COUNTRY_CODE_TAIWAN = 30, + USB_HID_COUNTRY_CODE_TURKISH_Q = 31, + USB_HID_COUNTRY_CODE_UK = 32, + USB_HID_COUNTRY_CODE_US = 33, + USB_HID_COUNTRY_CODE_YUGOSLAVIA = 34, + USB_HID_COUNTRY_CODE_TURKISH_F = 35 + /* Reserved = 36-255 */ +} USB_HID_COUNTRY_CODE; + +/* As defined in section 4.2 of the HID v1.11 specification. */ +typedef enum +{ + USB_HID_SUBCLASS_CODE_NO_SUBCLASS = 0x00, + USB_HID_SUBCLASS_CODE_BOOT_INTERFACE_SUBCLASS = 0x01 + /* Reserved = 0x02-0xFF */ +} USB_HID_SUBCLASS_CODE; + +/* As defined in section 4.3 of the HID v1.11 specification. */ +typedef enum +{ + USB_HID_PROTOCOL_CODE_NONE = 0x00, + USB_HID_PROTOCOL_CODE_KEYBOARD = 0x01, + USB_HID_PROTOCOL_CODE_MOUSE = 0x02 + /* Reserved = 0x03-0xFF */ +} USB_HID_PROTOCOL_CODE; + +typedef enum +{ + USB_HID_USAGE_PAGE_UNDEFINED = 0x00, + USB_HID_USAGE_PAGE_GENERIC_DESKTOP_CONTROLS = 0x01, + USB_HID_USAGE_PAGE_SIMULATION_CONTROLS = 0x02, + USB_HID_USAGE_PAGE_VR_CONTROLS = 0x03, + USB_HID_USAGE_PAGE_SPORT_CONTROLS = 0x04, + USB_HID_USAGE_PAGE_GAME_CONTROLS = 0x05, + USB_HID_USAGE_PAGE_GENERIC_DEVICE_CONTROLS = 0x06, + USB_HID_USAGE_PAGE_KEYBOARD_KEYPAD = 0x07, + USB_HID_USAGE_PAGE_LEDS = 0x08, + USB_HID_USAGE_PAGE_BUTTON = 0x09, + USB_HID_USAGE_PAGE_ORDINAL = 0x0A, + USB_HID_USAGE_PAGE_TELEPHONY = 0x0B, + USB_HID_USAGE_PAGE_CONSUMER = 0x0C, + USB_HID_USAGE_PAGE_DIGITIZER = 0x0D, + /* Reserved = 0x0E */ + USB_HID_USAGE_PAGE_PID_PAGE = 0x0F, + USB_HID_USAGE_PAGE_UNICODE = 0x10, + /* Reserved = 0x11-13 */ + USB_HID_USAGE_PAGE_ALPHANUMERIC_DISPLAY = 0x14, + /* Reserved = 0x15-3f */ + USB_HID_USAGE_PAGE_MEDICAL_INSTRUMENTS = 0x40, + /* Reserved = 0x41-7f */ + USB_HID_USAGE_PAGE_MONITOR = 0x80, + USB_HID_USAGE_PAGE_MONITOR_ENUMERATED_VALUES = 0x81, + USB_HID_USAGE_PAGE_MONITOR_VESA_VIRTUAL_CONTROLS = 0x82, + USB_HID_USAGE_PAGE_MONITOR_RESERVED = 0x83, + USB_HID_USAGE_PAGE_POWER_DEVICE = 0x84, + USB_HID_USAGE_PAGE_BATTERY_SYSTEM = 0x85, + USB_HID_USAGE_PAGE_POWER_PAGE_3 = 0x86, + USB_HID_USAGE_PAGE_POWER_PAGE_4 = 0x87, + /* Reserved = 0x88-8B */ + USB_HID_USAGE_PAGE_BAR_CODE_SCANNER = 0x8C, + USB_HID_USAGE_PAGE_WEIGHING_DEVICES = 0x8D, + USB_HID_USAGE_PAGE_MAGNETIC_STRIPE_READING_DEVICES = 0x8E, + USB_HID_USAGE_PAGE_RESERVED_POINT_OF_SALE_PAGES = 0x8F, + USB_HID_USAGE_PAGE_CAMERA_CONTROL_PAGE = 0x90, + USB_HID_USAGE_PAGE_ARCADE_PAGE = 0x91 + /* Reserved = 0x92-FEFF */ + /* Vendor-defined = 0xFF00-FFFF */ +} USB_HID_USAGE_PAGE; + +typedef enum +{ + USB_HID_GENERIC_DESKTOP_UNDEFINED = 0x00, + USB_HID_GENERIC_DESKTOP_POINTER = 0x01, + USB_HID_GENERIC_DESKTOP_MOUSE = 0x02, + /* Reserved = 0x03 */ + USB_HID_GENERIC_DESKTOP_JOYSTICK = 0x04, + USB_HID_GENERIC_DESKTOP_GAME_PAD = 0x05, + USB_HID_GENERIC_DESKTOP_KEYBOARD = 0x06, + USB_HID_GENERIC_DESKTOP_KEYPAD = 0x07, + USB_HID_GENERIC_DESKTOP_MULTI_AXIS_CONTROLLER = 0x08, + USB_HID_GENERIC_DESKTOP_TABLET_PC_SYSTEM_CONTROLS = 0x09, + + USB_HID_GENERIC_DESKTOP_X = 0x30, + USB_HID_GENERIC_DESKTOP_Y = 0x31, + USB_HID_GENERIC_DESKTOP_Z = 0x32, + USB_HID_GENERIC_DESKTOP_RX = 0x33, + USB_HID_GENERIC_DESKTOP_RY = 0x34, + USB_HID_GENERIC_DESKTOP_RZ = 0x35, + USB_HID_GENERIC_DESKTOP_SLIDER = 0x36, + USB_HID_GENERIC_DESKTOP_DIAL = 0x37, + USB_HID_GENERIC_DESKTOP_WHEEL = 0x38, + USB_HID_GENERIC_DESKTOP_HAT_SWITCH = 0x39, + USB_HID_GENERIC_DESKTOP_COUNTED_BUFFER = 0x3A, + USB_HID_GENERIC_DESKTOP_BYTE_COUNT = 0x3B, + USB_HID_GENERIC_DESKTOP_MOTION_WAKEUP = 0x3C, + USB_HID_GENERIC_DESKTOP_START = 0x3D, + USB_HID_GENERIC_DESKTOP_SELECT = 0x3E, + + USB_HID_GENERIC_DESKTOP_VX = 0x40, + USB_HID_GENERIC_DESKTOP_VY = 0x41, + USB_HID_GENERIC_DESKTOP_VZ = 0x42, + USB_HID_GENERIC_DESKTOP_VBRX = 0x43, + USB_HID_GENERIC_DESKTOP_VBRY = 0x44, + USB_HID_GENERIC_DESKTOP_VBRZ = 0x45, + USB_HID_GENERIC_DESKTOP_VNO = 0x46, + USB_HID_GENERIC_DESKTOP_FEATURE_NOTIFICATION = 0x47, + USB_HID_GENERIC_DESKTOP_RESOLUTION_MULTIPLIER = 0x48, + + USB_HID_GENERIC_DESKTOP_SYSTEM_CONTROL = 0x80, + USB_HID_GENERIC_DESKTOP_SYSTEM_POWER_DOWN = 0x81, + USB_HID_GENERIC_DESKTOP_SYSTEM_SLEEP = 0x82, + USB_HID_GENERIC_DESKTOP_WAKE_UP = 0x83, + USB_HID_GENERIC_DESKTOP_CONTEXT_MENU = 0x84, + USB_HID_GENERIC_DESKTOP_MAIN_MENU = 0x85, + USB_HID_GENERIC_DESKTOP_APP_MENU = 0x86, + USB_HID_GENERIC_DESKTOP_MENU_HELP = 0x87, + USB_HID_GENERIC_DESKTOP_MENU_EXIT = 0x88, + USB_HID_GENERIC_DESKTOP_MENU_SELECT = 0x89, + USB_HID_GENERIC_DESKTOP_MENU_RIGHT = 0x8A, + USB_HID_GENERIC_DESKTOP_MENU_LEFT = 0x8B, + USB_HID_GENERIC_DESKTOP_MENU_UP = 0x8C, + USB_HID_GENERIC_DESKTOP_MENU_DOWN = 0x8D, + USB_HID_GENERIC_DESKTOP_MENU_COLD_RESTART = 0x8E, + USB_HID_GENERIC_DESKTOP_MENU_WARM_RESTART = 0x8F, + USB_HID_GENERIC_DESKTOP_DPAD_UP = 0x90, + USB_HID_GENERIC_DESKTOP_DPAD_DOWN = 0x91, + USB_HID_GENERIC_DESKTOP_DPAD_RIGHT = 0x92, + USB_HID_GENERIC_DESKTOP_DPAD_LEFT = 0x93, + + USB_HID_GENERIC_DESKTOP_SYSTEM_DOCK = 0xA0, + USB_HID_GENERIC_DESKTOP_SYSTEM_UNDOCK = 0xA1, + USB_HID_GENERIC_DESKTOP_SYSTEM_SETUP = 0xA2, + USB_HID_GENERIC_DESKTOP_SYSTEM_BREAK = 0xA3, + USB_HID_GENERIC_DESKTOP_SYSTEM_DEBUGGER_BREAK = 0xA4, + USB_HID_GENERIC_DESKTOP_APPLICATION_BREAK = 0xA5, + USB_HID_GENERIC_DESKTOP_APPLICATION_DEBUGGER_BREAK = 0xA6, + USB_HID_GENERIC_DESKTOP_SYSTEM_SPEAKER_MUTE = 0xA7, + USB_HID_GENERIC_DESKTOP_SYSTEM_HIBERNATE = 0xA8, + + USB_HID_GENERIC_DESKTOP_SYSTEM_DISPLAY_INVERT = 0xB0, + USB_HID_GENERIC_DESKTOP_SYSTEM_DISPLAY_INTERNAL = 0xB1, + USB_HID_GENERIC_DESKTOP_SYSTEM_DISPLAY_EXTERNAL = 0xB2, + USB_HID_GENERIC_DESKTOP_SYSTEM_DISPLAY_BOTH = 0xB3, + USB_HID_GENERIC_DESKTOP_SYSTEM_DISPLAY_DUAL = 0xB4, + USB_HID_GENERIC_DESKTOP_SYSTEM_DISPLAY_TOGGLE_INT_EXT = 0xB5, + USB_HID_GENERIC_DESKTOP_SYSTEM_DISPLAY_SWAP_PRIMARY_SECONDARY = 0xB6, + USB_HID_GENERIC_DESKTOP_SYSTEM_DISPLAY_LCD_AUTOSCALE = 0xB7 + /* Reserved = 0xB6-0xFFFF*/ + +} USB_HID_GENERIC_DESKTOP; + +typedef enum +{ + USB_HID_SIMULATION_CONTROLS_UNDEFINED = 0x00, + USB_HID_SIMULATION_CONTROLS_FLIGHT_SIMULATION_DEVICE = 0x01, + USB_HID_SIMULATION_CONTROLS_AUTOMOBILE_SIMULATION_DEVICE = 0x02, + USB_HID_SIMULATION_CONTROLS_TANK_SIMULATION_DEVICE = 0x03, + USB_HID_SIMULATION_CONTROLS_SPACESHIP_SIMULATION_DEVICE = 0x04, + USB_HID_SIMULATION_CONTROLS_SUBMARINE_SIMULATION_DEVICE = 0x05, + USB_HID_SIMULATION_CONTROLS_SAILING_SIMULATION_DEVICE = 0x06, + USB_HID_SIMULATION_CONTROLS_MOTORCYCLE_SIMULATION_DEVICE = 0x07, + USB_HID_SIMULATION_CONTROLS_SPORTS_SIMLUATION_DEVICE = 0x08, + USB_HID_SIMULATION_CONTROLS_AIRPLANE_SIMULATION_DEVICE = 0x09, + USB_HID_SIMULATION_CONTROLS_HELICOPTER_SIMULATION_DEVICE = 0x0A, + USB_HID_SIMULATION_CONTROLS_MAGIC_CARPET_SIMULATION_DEVICE = 0x0B, + USB_HID_SIMULATION_CONTROLS_BICYCLE_SIMULATION_DEVICE = 0x0C, + /* Reserved = 0x0D-0x1F */ + USB_HID_SIMULATION_CONTROLS_FLIGHT_CONTROL_STICK = 0x20, + USB_HID_SIMULATION_CONTROLS_FLIGHT_STICK = 0x21, + USB_HID_SIMULATION_CONTROLS_CYCLIC_CONTROL = 0x22, + USB_HID_SIMULATION_CONTROLS_CYCLIC_TRIM = 0x23, + USB_HID_SIMULATION_CONTROLS_FLIGHT_YOKE = 0x24, + USB_HID_SIMULATION_CONTROLS_TRACK_CONTROL = 0x25, + /* Reserved = 0x26-0xAF */ + USB_HID_SIMULATION_CONTROLS_AILERON = 0xB0, + USB_HID_SIMULATION_CONTROLS_AILERON_TRIM = 0xB1, + USB_HID_SIMULATION_CONTROLS_ANTI_TORQUE_CONTROL = 0xB2, + USB_HID_SIMULATION_CONTROLS_AUTOPILOT_ENABLE = 0xB3, + USB_HID_SIMULATION_CONTROLS_CHAFF_RELEASE = 0xB4, + USB_HID_SIMULATION_CONTROLS_COLLECTIVE_CONTROL = 0xB5, + USB_HID_SIMULATION_CONTROLS_DIVE_BRAKE = 0xB6, + USB_HID_SIMULATION_CONTROLS_ELECTRONIC_COUNTERMEASURES = 0xB7, + USB_HID_SIMULATION_CONTROLS_ELEVATOR = 0xB8, + USB_HID_SIMULATION_CONTROLS_ELEVATOR_TRIM = 0xB9, + USB_HID_SIMULATION_CONTROLS_RUDDER = 0xBA, + USB_HID_SIMULATION_CONTROLS_THROTTLE = 0xBB, + USB_HID_SIMULATION_CONTROLS_FLIGHT_COMMUNICATIONS = 0xBC, + USB_HID_SIMULATION_CONTROLS_FLARE_RELEASE = 0xBD, + USB_HID_SIMULATION_CONTROLS_LANDING_GEAR = 0xBE, + USB_HID_SIMULATION_CONTROLS_TOE_BRAKE = 0xBF, + USB_HID_SIMULATION_CONTROLS_TRIGGER = 0xC0, + USB_HID_SIMULATION_CONTROLS_WEAPONS_ARM = 0xC1, + USB_HID_SIMULATION_CONTROLS_WEAPONS_SELECT = 0xC2, + USB_HID_SIMULATION_CONTROLS_WING_FLAPS = 0xC3, + USB_HID_SIMULATION_CONTROLS_ACCELERATOR = 0xC4, + USB_HID_SIMULATION_CONTROLS_BRAKE = 0xC5, + USB_HID_SIMULATION_CONTROLS_CLUTCH = 0xC6, + USB_HID_SIMULATION_CONTROLS_SHIFTER = 0xC7, + USB_HID_SIMULATION_CONTROLS_STEERING = 0xC8, + USB_HID_SIMULATION_CONTROLS_TURRET_DIRECTION = 0xC9, + USB_HID_SIMULATION_CONTROLS_BARREL_ELEVATION = 0xCA, + USB_HID_SIMULATION_CONTROLS_DIVE_PLANE = 0xCB, + USB_HID_SIMULATION_CONTROLS_BALLAST = 0xCC, + USB_HID_SIMULATION_CONTROLS_BICYCLE_CRANK = 0xCD, + USB_HID_SIMULATION_CONTROLS_HANDLE_BARS = 0xCE, + USB_HID_SIMULATION_CONTROLS_FRONT_BRAKE = 0xCF, + USB_HID_SIMULATION_CONTROLS_REAR_BRAKE = 0xD0 + /* Reserved = 0xD1-0xFFFF*/ +} USB_HID_SIMULATION_CONTROLS; + + +typedef enum +{ + USB_HID_VR_CONTROLS_UNIDENTIFIED = 0x00, + USB_HID_VR_CONTROLS_BELT = 0x01, + USB_HID_VR_CONTROLS_BODY_SUIT = 0x02, + USB_HID_VR_CONTROLS_FLEXOR = 0x03, + USB_HID_VR_CONTROLS_GLOVE = 0x04, + USB_HID_VR_CONTROLS_HEAD_TRACKER = 0x05, + USB_HID_VR_CONTROLS_HEAD_MOUNTED_DISPLAY = 0x06, + USB_HID_VR_CONTROLS_HAND_TRACKER = 0x07, + USB_HID_VR_CONTROLS_OCULOMETER = 0x08, + USB_HID_VR_CONTROLS_VEST = 0x09, + USB_HID_VR_CONTROLS_ANIMATRONIC_DEVICE = 0x0A, + /* Reserved = 0x0B-0x1F */ + USB_HID_VR_CONTROLS_STEREO_ENABLE = 0x20, + USB_HID_VR_CONTROLS_DISPLAY_ENABLE = 0x21 + /* Reserved = 0x22-0xFFFF */ +} USB_HID_VR_CONTROLS; + +typedef enum +{ + USB_HID_SPORT_CONTROLS_UNIDENTIFIED = 0x00, + USB_HID_SPORT_CONTROLS_BASEBALL_BAT = 0x01, + USB_HID_SPORT_CONTROLS_GOLF_CLUB = 0x02, + USB_HID_SPORT_CONTROLS_ROWING_MACHINE = 0x03, + USB_HID_SPORT_CONTROLS_TREADMILL = 0x04, + /* Reserved = 0x05-0x2F */ + USB_HID_SPORT_CONTROLS_OAR = 0x30, + USB_HID_SPORT_CONTROLS_SLOPE = 0x31, + USB_HID_SPORT_CONTROLS_RATE = 0x32, + USB_HID_SPORT_CONTROLS_STICK_SPEED = 0x33, + USB_HID_SPORT_CONTROLS_STICK_FACE_ANGLE = 0x34, + USB_HID_SPORT_CONTROLS_STICK_HEEL_TOE = 0x35, + USB_HID_SPORT_CONTROLS_STICK_FOLLOW_THROUGH = 0x36, + USB_HID_SPORT_CONTROLS_STICK_TEMPO = 0x37, + USB_HID_SPORT_CONTROLS_STICK_TYPE = 0x38, + USB_HID_SPORT_CONTROLS_STICK_HEIGHT = 0x39, + /* Reserved = 0x3A-4F */ + USB_HID_SPORT_CONTROLS_PUTTER = 0x50, + USB_HID_SPORT_CONTROLS_1_IRON = 0x51, + USB_HID_SPORT_CONTROLS_2_IRON = 0x52, + USB_HID_SPORT_CONTROLS_3_IRON = 0x53, + USB_HID_SPORT_CONTROLS_4_IRON = 0x54, + USB_HID_SPORT_CONTROLS_5_IRON = 0x55, + USB_HID_SPORT_CONTROLS_6_IRON = 0x56, + USB_HID_SPORT_CONTROLS_7_IRON = 0x57, + USB_HID_SPORT_CONTROLS_8_IRON = 0x58, + USB_HID_SPORT_CONTROLS_9_IRON = 0x59, + USB_HID_SPORT_CONTROLS_10_IRON = 0x5A, + USB_HID_SPORT_CONTROLS_11_IRON = 0x5B, + USB_HID_SPORT_CONTROLS_SAND_WEDGE = 0x5C, + USB_HID_SPORT_CONTROLS_LOFT_WEDGE = 0x5D, + USB_HID_SPORT_CONTROLS_POWER_WEDGE = 0x5E, + USB_HID_SPORT_CONTROLS_1_WOOD = 0x5F, + USB_HID_SPORT_CONTROLS_3_WOOD = 0x60, + USB_HID_SPORT_CONTROLS_5_WOOD = 0x61, + USB_HID_SPORT_CONTROLS_7_WOOD = 0x62, + USB_HID_SPORT_CONTROLS_9_WOOD = 0x63 + /* Reserved = 0x64-0xFFFF */ +} USB_HID_SPORT_CONTROLS; + +typedef enum +{ + USB_HID_GAME_CONTROLS_UNDEFINED = 0x00, + USB_HID_GAME_CONTROLS_3D_GAME_CONTROLLER = 0x01, + USB_HID_GAME_CONTROLS_PINBALL_DEVICE = 0x02, + USB_HID_GAME_CONTROLS_GUN_DEVICE = 0x03, + /* Reserved = 0x04-0x1F */ + USB_HID_GAME_CONTROLS_POINT_OF_VIEW = 0x20, + USB_HID_GAME_CONTROLS_TURN_RIGHT_LEFT = 0x21, + USB_HID_GAME_CONTROLS_PITCH_FORWARD_BACKWARD = 0x22, + USB_HID_GAME_CONTROLS_ROLL_RIGHT_LEFT = 0x23, + USB_HID_GAME_CONTROLS_MOVE_RIGHT_LEFT = 0x24, + USB_HID_GAME_CONTROLS_MOVE_FORWARD_BACKWARD = 0x25, + USB_HID_GAME_CONTROLS_MOVE_UP_DOWN = 0x26, + USB_HID_GAME_CONTROLS_LEAN_RIGHT_LEFT = 0x27, + USB_HID_GAME_CONTROLS_LEAN_FORWARD_BACKWARD = 0x28, + USB_HID_GAME_CONTROLS_HEIGHT_OF_POV = 0x29, + USB_HID_GAME_CONTROLS_FLIPPER = 0x2A, + USB_HID_GAME_CONTROLS_SECONDARY_FLIPPER = 0x2B, + USB_HID_GAME_CONTROLS_BUMP = 0x2C, + USB_HID_GAME_CONTROLS_NEW_GAME = 0x2D, + USB_HID_GAME_CONTROLS_SHOOT_BALL = 0x2E, + USB_HID_GAME_CONTROLS_PLAYER = 0x2F, + USB_HID_GAME_CONTROLS_GUN_BOLT = 0x30, + USB_HID_GAME_CONTROLS_GUN_CLIP = 0x31, + USB_HID_GAME_CONTROLS_GUN_SELECTOR = 0x32, + USB_HID_GAME_CONTROLS_GUN_SINGLE_SHOT = 0x33, + USB_HID_GAME_CONTROLS_GUN_BURST = 0x34, + USB_HID_GAME_CONTROLS_GUN_AUTOMATIC = 0x35, + USB_HID_GAME_CONTROLS_GUN_SAFETY = 0x36, + USB_HID_GAME_CONTROLS_GAMEPAD_FIRE_JUMP = 0x37, + /* Unspecified in spec = 0x38 */ + USB_HID_GAME_CONTROLS_GAMEPAD_TRIGGER = 0x39 + /* Reserved = 0x3A-0xFFFF */ +} USB_HID_GAME_CONTROLS; + +typedef enum +{ + USB_HID_GENERIC_DEVICE_CONTROLS_UNIDENTIFIED = 0x00, + /* Reserved = 0x01-0x1F */ + USB_HID_GENERIC_DEVICE_CONTROLS_BATTERY_STRENGTH = 0x20, + USB_HID_GENERIC_DEVICE_CONTROLS_WIRELESS_CHANNEL = 0x21, + USB_HID_GENERIC_DEVICE_CONTROLS_WIRELESS_ID = 0x22, + USB_HID_GENERIC_DEVICE_CONTROLS_DISCOVER_WIRELESS_CONTROL = 0x23, + USB_HID_GENERIC_DEVICE_CONTROLS_SECURITY_CODE_CHARACTER_ENTERED = 0x24, + USB_HID_GENERIC_DEVICE_CONTROLS_SECURITY_CODE_CHARACTER_ERASED = 0x25, + USB_HID_GENERIC_DEVICE_CONTROLS_SECURITY_CODE_CLEARED = 0x26 + /* Reserved = 0x27-0xFFFF */ +} USB_HID_GENERIC_DEVICE_CONTROLS; + +typedef enum +{ + USB_HID_KEYBOARD_KEYPAD_RESERVED_NO_EVENT_INDICATED = 0x00, + USB_HID_KEYBOARD_KEYPAD_KEYBOARD_ERROR_ROLL_OVER = 0x01, + USB_HID_KEYBOARD_KEYPAD_KEYBOARD_POST_FAIL = 0x02, + USB_HID_KEYBOARD_KEYPAD_KEYBOARD_ERROR_UNDEFINED = 0x03, + USB_HID_KEYBOARD_KEYPAD_KEYBOARD_A = 0x04, + USB_HID_KEYBOARD_KEYPAD_KEYBOARD_B = 0x05, + USB_HID_KEYBOARD_KEYPAD_KEYBOARD_C = 0x06, + USB_HID_KEYBOARD_KEYPAD_KEYBOARD_D = 0x07, + USB_HID_KEYBOARD_KEYPAD_KEYBOARD_E = 0x08, + USB_HID_KEYBOARD_KEYPAD_KEYBOARD_F = 0x09, + USB_HID_KEYBOARD_KEYPAD_KEYBOARD_G = 0x0A, + USB_HID_KEYBOARD_KEYPAD_KEYBOARD_H = 0x0B, + USB_HID_KEYBOARD_KEYPAD_KEYBOARD_I = 0x0C, + USB_HID_KEYBOARD_KEYPAD_KEYBOARD_J = 0x0D, + USB_HID_KEYBOARD_KEYPAD_KEYBOARD_K = 0x0E, + USB_HID_KEYBOARD_KEYPAD_KEYBOARD_L = 0x0F, + USB_HID_KEYBOARD_KEYPAD_KEYBOARD_M = 0x10, + USB_HID_KEYBOARD_KEYPAD_KEYBOARD_N = 0x11, + USB_HID_KEYBOARD_KEYPAD_KEYBOARD_O = 0x12, + USB_HID_KEYBOARD_KEYPAD_KEYBOARD_P = 0x13, + USB_HID_KEYBOARD_KEYPAD_KEYBOARD_Q = 0x14, + USB_HID_KEYBOARD_KEYPAD_KEYBOARD_R = 0x15, + USB_HID_KEYBOARD_KEYPAD_KEYBOARD_S = 0x16, + USB_HID_KEYBOARD_KEYPAD_KEYBOARD_T = 0x17, + USB_HID_KEYBOARD_KEYPAD_KEYBOARD_U = 0x18, + USB_HID_KEYBOARD_KEYPAD_KEYBOARD_V = 0x19, + USB_HID_KEYBOARD_KEYPAD_KEYBOARD_W = 0x1A, + USB_HID_KEYBOARD_KEYPAD_KEYBOARD_X = 0x1B, + USB_HID_KEYBOARD_KEYPAD_KEYBOARD_Y = 0x1C, + USB_HID_KEYBOARD_KEYPAD_KEYBOARD_Z = 0x1D, + USB_HID_KEYBOARD_KEYPAD_KEYBOARD_1_AND_EXCLAMATION_POINT = 0x1E, + USB_HID_KEYBOARD_KEYPAD_KEYBOARD_2_AND_AT = 0x1F, + USB_HID_KEYBOARD_KEYPAD_KEYBOARD_3_AND_HASH = 0x20, + USB_HID_KEYBOARD_KEYPAD_KEYBOARD_4_AND_DOLLAR = 0x21, + USB_HID_KEYBOARD_KEYPAD_KEYBOARD_5_AND_PERCENT = 0x22, + USB_HID_KEYBOARD_KEYPAD_KEYBOARD_6_AND_CARROT = 0x23, + USB_HID_KEYBOARD_KEYPAD_KEYBOARD_7_AND_AMPERSAND = 0x24, + USB_HID_KEYBOARD_KEYPAD_KEYBOARD_8_AND_ASTERISK = 0x25, + USB_HID_KEYBOARD_KEYPAD_KEYBOARD_9_AND_OPEN_PARENTHESIS = 0x26, + USB_HID_KEYBOARD_KEYPAD_KEYBOARD_0_AND_CLOSE_PARENTHESIS = 0x27, + USB_HID_KEYBOARD_KEYPAD_KEYBOARD_RETURN_ENTER = 0x28, + USB_HID_KEYBOARD_KEYPAD_KEYBOARD_ESCAPE = 0x29, + USB_HID_KEYBOARD_KEYPAD_KEYBOARD_DELETE = 0x2A, + USB_HID_KEYBOARD_KEYPAD_KEYBOARD_TAB = 0x2B, + USB_HID_KEYBOARD_KEYPAD_KEYBOARD_SPACEBAR = 0x2C, + USB_HID_KEYBOARD_KEYPAD_KEYBOARD_MINUS_AND_UNDERSCORE = 0x2D, + USB_HID_KEYBOARD_KEYPAD_KEYBOARD_EQUAL_AND_PLUS = 0x2E, + USB_HID_KEYBOARD_KEYPAD_KEYBOARD_OPEN_BRACKET_AND_OPEN_CURLY_BRACE = 0x2F, + USB_HID_KEYBOARD_KEYPAD_KEYBOARD_CLOSE_BRACKET_AND_CLOSE_CURLY_BRACE = 0x30, + USB_HID_KEYBOARD_KEYPAD_KEYBOARD_BACK_SLASH_AND_PIPE = 0x31, + USB_HID_KEYBOARD_KEYPAD_KEYBOARD_NON_US_HASH_AND_TILDE = 0x32, + USB_HID_KEYBOARD_KEYPAD_KEYBOARD_SEMICOLON_AND_COLON = 0x33, + USB_HID_KEYBOARD_KEYPAD_KEYBOARD_APOSTROPHE_AND_QUOTE = 0x34, + USB_HID_KEYBOARD_KEYPAD_KEYBOARD_GRAVE_ACCENT_AND_TILDE = 0x35, + USB_HID_KEYBOARD_KEYPAD_KEYBOARD_COMMA_AND_LESS_THAN = 0x36, + USB_HID_KEYBOARD_KEYPAD_KEYBOARD_PERIOD_AND_GREATER_THAN = 0x37, + USB_HID_KEYBOARD_KEYPAD_KEYBOARD_FORWARD_SLASH_AND_QUESTION_MARK = 0x38, + USB_HID_KEYBOARD_KEYPAD_KEYBOARD_CAPS_LOCK = 0x39, + USB_HID_KEYBOARD_KEYPAD_KEYBOARD_F1 = 0x3A, + USB_HID_KEYBOARD_KEYPAD_KEYBOARD_F2 = 0x3B, + USB_HID_KEYBOARD_KEYPAD_KEYBOARD_F3 = 0x3C, + USB_HID_KEYBOARD_KEYPAD_KEYBOARD_F4 = 0x3D, + USB_HID_KEYBOARD_KEYPAD_KEYBOARD_F5 = 0x3E, + USB_HID_KEYBOARD_KEYPAD_KEYBOARD_F6 = 0x3F, + USB_HID_KEYBOARD_KEYPAD_KEYBOARD_F7 = 0x40, + USB_HID_KEYBOARD_KEYPAD_KEYBOARD_F8 = 0x41, + USB_HID_KEYBOARD_KEYPAD_KEYBOARD_F9 = 0x42, + USB_HID_KEYBOARD_KEYPAD_KEYBOARD_F10 = 0x43, + USB_HID_KEYBOARD_KEYPAD_KEYBOARD_F11 = 0x44, + USB_HID_KEYBOARD_KEYPAD_KEYBOARD_F12 = 0x45, + USB_HID_KEYBOARD_KEYPAD_KEYBOARD_PRINT_SCREEN = 0x46, + USB_HID_KEYBOARD_KEYPAD_KEYBOARD_SCROLL_LOCK = 0x47, + USB_HID_KEYBOARD_KEYPAD_KEYBOARD_PAUSE = 0x48, + USB_HID_KEYBOARD_KEYPAD_KEYBOARD_INSERT = 0x49, + USB_HID_KEYBOARD_KEYPAD_KEYBOARD_HOME = 0x4A, + USB_HID_KEYBOARD_KEYPAD_KEYBOARD_PAGE_UP = 0x4B, + USB_HID_KEYBOARD_KEYPAD_KEYBOARD_DELETE_FORWARD = 0x4C, + USB_HID_KEYBOARD_KEYPAD_KEYBOARD_END = 0x4D, + USB_HID_KEYBOARD_KEYPAD_KEYBOARD_PAGE_DOWN = 0x4E, + USB_HID_KEYBOARD_KEYPAD_KEYBOARD_RIGHT_ARROW = 0x4F, + USB_HID_KEYBOARD_KEYPAD_KEYBOARD_LEFT_ARROW = 0x50, + USB_HID_KEYBOARD_KEYPAD_KEYBOARD_DOWN_ARROW = 0x51, + USB_HID_KEYBOARD_KEYPAD_KEYBOARD_UP_ARROW = 0x52, + USB_HID_KEYBOARD_KEYPAD_KEYPAD_NUM_LOCK_AND_CLEAR = 0x53, + USB_HID_KEYBOARD_KEYPAD_KEYPAD_BACK_SLASH = 0x54, + USB_HID_KEYBOARD_KEYPAD_KEYPAD_ASTERISK = 0x55, + USB_HID_KEYBOARD_KEYPAD_KEYPAD_MINUS = 0x56, + USB_HID_KEYBOARD_KEYPAD_KEYPAD_PLUS = 0x57, + USB_HID_KEYBOARD_KEYPAD_KEYPAD_ENTER = 0x58, + USB_HID_KEYBOARD_KEYPAD_KEYPAD_1_AND_END = 0x59, + USB_HID_KEYBOARD_KEYPAD_KEYPAD_2_AND_DOWN_ARROW = 0x5A, + USB_HID_KEYBOARD_KEYPAD_KEYPAD_3_AND_PAGE_DOWN = 0x5B, + USB_HID_KEYBOARD_KEYPAD_KEYPAD_4_AND_LEFT_ARROW = 0x5C, + USB_HID_KEYBOARD_KEYPAD_KEYPAD_5 = 0x5D, + USB_HID_KEYBOARD_KEYPAD_KEYPAD_6_AND_RIGHT_ARROW = 0x5E, + USB_HID_KEYBOARD_KEYPAD_KEYPAD_7_AND_HOME = 0x5F, + USB_HID_KEYBOARD_KEYPAD_KEYPAD_8_AND_UP_ARROW = 0x60, + USB_HID_KEYBOARD_KEYPAD_KEYPAD_9_AND_PAGE_UP = 0x61, + USB_HID_KEYBOARD_KEYPAD_KEYPAD_0_AND_INSERT = 0x62, + USB_HID_KEYBOARD_KEYPAD_KEYPAD_PERIOD_AND_DELETE = 0x63, + USB_HID_KEYBOARD_KEYPAD_KEYBOARD_NON_US_FORWARD_SLASH_AND_PIPE = 0x64, + USB_HID_KEYBOARD_KEYPAD_KEYBOARD_APPLICATION = 0x65, + USB_HID_KEYBOARD_KEYPAD_KEYBOARD_POWER = 0x66, + USB_HID_KEYBOARD_KEYPAD_KEYBOARD_EQUAL_SIZE = 0x67, + USB_HID_KEYBOARD_KEYPAD_KEYBOARD_F13 = 0x68, + USB_HID_KEYBOARD_KEYPAD_KEYBOARD_F14 = 0x69, + USB_HID_KEYBOARD_KEYPAD_KEYBOARD_F15 = 0x6A, + USB_HID_KEYBOARD_KEYPAD_KEYBOARD_F16 = 0x6B, + USB_HID_KEYBOARD_KEYPAD_KEYBOARD_F17 = 0x6C, + USB_HID_KEYBOARD_KEYPAD_KEYBOARD_F18 = 0x6D, + USB_HID_KEYBOARD_KEYPAD_KEYBOARD_F19 = 0x6E, + USB_HID_KEYBOARD_KEYPAD_KEYBOARD_F20 = 0x6F, + USB_HID_KEYBOARD_KEYPAD_KEYBOARD_F21 = 0x70, + USB_HID_KEYBOARD_KEYPAD_KEYBOARD_F22 = 0x71, + USB_HID_KEYBOARD_KEYPAD_KEYBOARD_F23 = 0x72, + USB_HID_KEYBOARD_KEYPAD_KEYBOARD_F24 = 0x73, + USB_HID_KEYBOARD_KEYPAD_KEYBOARD_EXECUTE = 0x74, + USB_HID_KEYBOARD_KEYPAD_KEYBOARD_HELP = 0x75, + USB_HID_KEYBOARD_KEYPAD_KEYBOARD_MENU = 0x76, + USB_HID_KEYBOARD_KEYPAD_KEYBOARD_SELECT = 0x77, + USB_HID_KEYBOARD_KEYPAD_KEYBOARD_STOP = 0x78, + USB_HID_KEYBOARD_KEYPAD_KEYBOARD_AGAIN = 0x79, + USB_HID_KEYBOARD_KEYPAD_KEYBOARD_UNDO = 0x7A, + USB_HID_KEYBOARD_KEYPAD_KEYBOARD_CUT = 0x7B, + USB_HID_KEYBOARD_KEYPAD_KEYBOARD_COPY = 0x7C, + USB_HID_KEYBOARD_KEYPAD_KEYBOARD_PASTE = 0x7D, + USB_HID_KEYBOARD_KEYPAD_KEYBOARD_FIND = 0x7E, + USB_HID_KEYBOARD_KEYPAD_KEYBOARD_MUTE = 0x7F, + USB_HID_KEYBOARD_KEYPAD_KEYBOARD_VOLUME_UP = 0x80, + USB_HID_KEYBOARD_KEYPAD_KEYBOARD_VOLUME_DOWN = 0x81, + USB_HID_KEYBOARD_KEYPAD_KEYBOARD_LOCKING_CAPS_LOCK = 0x82, + USB_HID_KEYBOARD_KEYPAD_KEYBOARD_LOCKING_NUM_LOCK = 0x83, + USB_HID_KEYBOARD_KEYPAD_KEYBOARD_LOCKING_SCROLL_LOCK = 0x84, + USB_HID_KEYBOARD_KEYPAD_KEYPAD_COMMA = 0x85, + USB_HID_KEYBOARD_KEYPAD_KEYPAD_EQUAL_SIGN = 0x86, + USB_HID_KEYBOARD_KEYPAD_KEYBOARD_INTERNATIONAL1 = 0x87, + USB_HID_KEYBOARD_KEYPAD_KEYBOARD_INTERNATIONAL2 = 0x88, + USB_HID_KEYBOARD_KEYPAD_KEYBOARD_INTERNATIONAL3 = 0x89, + USB_HID_KEYBOARD_KEYPAD_KEYBOARD_INTERNATIONAL4 = 0x8A, + USB_HID_KEYBOARD_KEYPAD_KEYBOARD_INTERNATIONAL5 = 0x8B, + USB_HID_KEYBOARD_KEYPAD_KEYBOARD_INTERNATIONAL6 = 0x8C, + USB_HID_KEYBOARD_KEYPAD_KEYBOARD_INTERNATIONAL7 = 0x8D, + USB_HID_KEYBOARD_KEYPAD_KEYBOARD_INTERNATIONAL8 = 0x8E, + USB_HID_KEYBOARD_KEYPAD_KEYBOARD_INTERNATIONAL9 = 0x8F, + USB_HID_KEYBOARD_KEYPAD_KEYBOARD_LANG1 = 0x90, + USB_HID_KEYBOARD_KEYPAD_KEYBOARD_LANG2 = 0x91, + USB_HID_KEYBOARD_KEYPAD_KEYBOARD_LANG3 = 0x92, + USB_HID_KEYBOARD_KEYPAD_KEYBOARD_LANG4 = 0x93, + USB_HID_KEYBOARD_KEYPAD_KEYBOARD_LANG5 = 0x94, + USB_HID_KEYBOARD_KEYPAD_KEYBOARD_LANG6 = 0x95, + USB_HID_KEYBOARD_KEYPAD_KEYBOARD_LANG7 = 0x96, + USB_HID_KEYBOARD_KEYPAD_KEYBOARD_LANG8 = 0x97, + USB_HID_KEYBOARD_KEYPAD_KEYBOARD_LANG9 = 0x98, + USB_HID_KEYBOARD_KEYPAD_KEYBOARD_ALTERNATE_ERASE = 0x99, + USB_HID_KEYBOARD_KEYPAD_KEYBOARD_SYS_REQ_ATTENTION = 0x9A, + USB_HID_KEYBOARD_KEYPAD_KEYBOARD_CANCEL = 0x9B, + USB_HID_KEYBOARD_KEYPAD_KEYBOARD_CLEAR = 0x9C, + USB_HID_KEYBOARD_KEYPAD_KEYBOARD_PRIOR = 0x9D, + USB_HID_KEYBOARD_KEYPAD_KEYBOARD_RETURN = 0x9E, + USB_HID_KEYBOARD_KEYPAD_KEYBOARD_SEPARATOR = 0x9F, + USB_HID_KEYBOARD_KEYPAD_KEYBOARD_OUT = 0xA0, + USB_HID_KEYBOARD_KEYPAD_KEYBOARD_OPER = 0xA1, + USB_HID_KEYBOARD_KEYPAD_KEYBOARD_CLEAR_AGAIN = 0xA2, + USB_HID_KEYBOARD_KEYPAD_KEYBOARD_CR_SEL_PROPS = 0xA3, + USB_HID_KEYBOARD_KEYPAD_KEYBOARD_EX_SEL = 0xA4, + /* Reserved = 0xA5-0xAF */ + USB_HID_KEYBOARD_KEYPAD_KEYPAD_00 = 0xB0, + USB_HID_KEYBOARD_KEYPAD_KEYPAD_000 = 0xB1, + USB_HID_KEYBOARD_KEYPAD_THOUSANDS_SEPARATOR = 0xB2, + USB_HID_KEYBOARD_KEYPAD_DECIMAL_SEPARATOR = 0xB3, + USB_HID_KEYBOARD_KEYPAD_CURRENCY_UNIT = 0xB4, + USB_HID_KEYBOARD_KEYPAD_CURRENTY_SUB_UNIT = 0xB5, + USB_HID_KEYBOARD_KEYPAD_KEYPAD_OPEN_PARENTHESIS = 0xB6, + USB_HID_KEYBOARD_KEYPAD_KEYPAD_CLOSE_PARENTHESIS = 0xB7, + USB_HID_KEYBOARD_KEYPAD_KEYPAD_OPEN_CURLY_BRACE = 0xB8, + USB_HID_KEYBOARD_KEYPAD_KEYPAD_CLOSE_CURLY_BRACE = 0xB9, + USB_HID_KEYBOARD_KEYPAD_KEYPAD_TAB = 0xBA, + USB_HID_KEYBOARD_KEYPAD_KEYPAD_BACKSPACE = 0xBB, + USB_HID_KEYBOARD_KEYPAD_KEYPAD_A = 0xBC, + USB_HID_KEYBOARD_KEYPAD_KEYPAD_B = 0xBD, + USB_HID_KEYBOARD_KEYPAD_KEYPAD_C = 0xBE, + USB_HID_KEYBOARD_KEYPAD_KEYPAD_D = 0xBF, + USB_HID_KEYBOARD_KEYPAD_KEYPAD_E = 0xC0, + USB_HID_KEYBOARD_KEYPAD_KEYPAD_F = 0xC1, + USB_HID_KEYBOARD_KEYPAD_KEYPAD_XOR = 0xC2, + USB_HID_KEYBOARD_KEYPAD_KEYPAD_CARROT = 0xC3, + USB_HID_KEYBOARD_KEYPAD_KEYPAD_PERCENT_SIGN = 0xC4, + USB_HID_KEYBOARD_KEYPAD_KEYPAD_LESS_THAN = 0xC5, + USB_HID_KEYBOARD_KEYPAD_KEYPAD_GREATER_THAN = 0xC6, + USB_HID_KEYBOARD_KEYPAD_KEYPAD_AMPERSAND = 0xC7, + USB_HID_KEYBOARD_KEYPAD_KEYPAD_DOUBLE_AMPERSAND = 0xC8, + USB_HID_KEYBOARD_KEYPAD_KEYPAD_PIPE = 0xC9, + USB_HID_KEYBOARD_KEYPAD_KEYPAD_DOUBLE_PIPE = 0xCA, + USB_HID_KEYBOARD_KEYPAD_KEYPAD_COLON = 0xCB, + USB_HID_KEYBOARD_KEYPAD_KEYPAD_HASH = 0xCC, + USB_HID_KEYBOARD_KEYPAD_KEYPAD_SPACE = 0xCD, + USB_HID_KEYBOARD_KEYPAD_KEYPAD_AT = 0xCE, + USB_HID_KEYBOARD_KEYPAD_KEYPAD_EXCLAMATION_POINT = 0xCF, + USB_HID_KEYBOARD_KEYPAD_KEYPAD_MEMORY_STORE = 0xD0, + USB_HID_KEYBOARD_KEYPAD_KEYPAD_MEMORY_RECALL = 0xD1, + USB_HID_KEYBOARD_KEYPAD_KEYPAD_MEMORY_CLEAR = 0xD2, + USB_HID_KEYBOARD_KEYPAD_KEYPAD_MEMORY_ADD = 0xD3, + USB_HID_KEYBOARD_KEYPAD_KEYPAD_MEMORY_SUBTRACT = 0xD4, + USB_HID_KEYBOARD_KEYPAD_KEYPAD_MEMORY_MULTIPLY = 0xD5, + USB_HID_KEYBOARD_KEYPAD_KEYPAD_MEMORY_DIVIDE = 0xD6, + USB_HID_KEYBOARD_KEYPAD_KEYPAD_PLUS_MINUS = 0xD7, + USB_HID_KEYBOARD_KEYPAD_KEYPAD_CLEAR = 0xD8, + USB_HID_KEYBOARD_KEYPAD_KEYPAD_CLEAR_ENTRY = 0xD9, + USB_HID_KEYBOARD_KEYPAD_KEYPAD_BINARY = 0xDA, + USB_HID_KEYBOARD_KEYPAD_KEYPAD_OCTAL = 0xDB, + USB_HID_KEYBOARD_KEYPAD_KEYPAD_DECIMAL = 0xDC, + USB_HID_KEYBOARD_KEYPAD_KEYPAD_HEXADECIMAL = 0xDD, + /* Reserved = 0xDE-0xDF */ + USB_HID_KEYBOARD_KEYPAD_KEYBOARD_LEFT_CONTROL = 0xE0, + USB_HID_KEYBOARD_KEYPAD_KEYBOARD_LEFT_SHIFT = 0xE1, + USB_HID_KEYBOARD_KEYPAD_KEYBOARD_LEFT_ALT = 0xE2, + USB_HID_KEYBOARD_KEYPAD_KEYBOARD_LEFT_GUI = 0xE3, + USB_HID_KEYBOARD_KEYPAD_KEYBOARD_RIGHT_CONTROL = 0xE4, + USB_HID_KEYBOARD_KEYPAD_KEYBOARD_RIGHT_SHIFT = 0xE5, + USB_HID_KEYBOARD_KEYPAD_KEYBOARD_RIGHT_ALT = 0xE6, + USB_HID_KEYBOARD_KEYPAD_KEYBOARD_RIGHT_GUI = 0xE7 + //0xE8-0xFFFF reserved +} USB_HID_KEYBOARD_KEYPAD; + +typedef enum +{ + USB_HID_LED_UNDEFINED = 0x00, + USB_HID_LED_NUM_LOCK = 0x01, + USB_HID_LED_CAPS_LOCK = 0x02, + USB_HID_LED_SCROLL_LOCK = 0x03, + USB_HID_LED_COMPOSE = 0x04, + USB_HID_LED_KANA = 0x05, + USB_HID_LED_POWER = 0x06, + USB_HID_LED_SHIFT = 0x07, + USB_HID_LED_DO_NOT_DISTURB = 0x08, + USB_HID_LED_MUTE = 0x09, + USB_HID_LED_TONE_ENABLE = 0x0A, + USB_HID_LED_HIGH_CUT_FILTER = 0x0B, + USB_HID_LED_LOW_CUT_FILTER = 0x0C, + USB_HID_LED_EQUALIZER_ENABLE = 0x0D, + USB_HID_LED_SOUND_FIELD_ON = 0x0E, + USB_HID_LED_SURROUND_ON = 0x0F, + USB_HID_LED_REPEAT = 0x10, + USB_HID_LED_STEREO = 0x11, + USB_HID_LED_SAMPLING_RATE_DETECT = 0x12, + USB_HID_LED_SPINNING = 0x13, + USB_HID_LED_CAV = 0x14, + USB_HID_LED_CLV = 0x15, + USB_HID_LED_RECORDING_FORMAT_DETECT = 0x16, + USB_HID_LED_OFF_HOOK = 0x17, + USB_HID_LED_RING = 0x18, + USB_HID_LED_MESSAGE_WAITING = 0x19, + USB_HID_LED_DATA_MODE = 0x1A, + USB_HID_LED_BATTERY_OPERATION = 0x1B, + USB_HID_LED_BATTERY_OK = 0x1C, + USB_HID_LED_BATTERY_LOW = 0x1D, + USB_HID_LED_SPEAKER = 0x1E, + USB_HID_LED_HEAD_SET = 0x1F, + USB_HID_LED_HOLD = 0x20, + USB_HID_LED_MICROPHONE = 0x21, + USB_HID_LED_COVERAGE = 0x22, + USB_HID_LED_NIGHT_MODE = 0x23, + USB_HID_LED_SEND_CALLS = 0x24, + USB_HID_LED_CALL_PICKUP = 0x25, + USB_HID_LED_CONFERENCE = 0x26, + USB_HID_LED_STANDBY = 0x27, + USB_HID_LED_CAMERA_ON = 0x28, + USB_HID_LED_CAMERA_OFF = 0x29, + USB_HID_LED_ON_LINE = 0x2A, + USB_HID_LED_OFF_LINE = 0x2B, + USB_HID_LED_BUSY = 0x2C, + USB_HID_LED_READY = 0x2D, + USB_HID_LED_PAPER_OUT = 0x2E, + USB_HID_LED_PAPER_JAM = 0x2F, + USB_HID_LED_REMOTE = 0x30, + USB_HID_LED_FORWARD = 0x31, + USB_HID_LED_REVERSE = 0x32, + USB_HID_LED_STOP = 0x33, + USB_HID_LED_REWIND = 0x34, + USB_HID_LED_FAST_FORWARD = 0x35, + USB_HID_LED_PLAY = 0x36, + USB_HID_LED_PAUSE = 0x37, + USB_HID_LED_RECORD = 0x38, + USB_HID_LED_ERROR = 0x39, + USB_HID_LED_USAGE_SELECTED_INDICATOR = 0x3A, + USB_HID_LED_USAGE_IN_USE_INDICATOR = 0x3B, + USB_HID_LED_USAGE_MULTI_MODE_INDICATOR = 0x3C, + USB_HID_LED_INDICATOR_ON = 0x3D, + USB_HID_LED_INDICATOR_FLASH = 0x3E, + USB_HID_LED_INDICATOR_SLOW_BLINK = 0x3F, + USB_HID_LED_INDICATOR_FAST_BLINK = 0x40, + USB_HID_LED_INDICATOR_OFF = 0x41, + USB_HID_LED_FLASH_ON_TIME = 0x42, + USB_HID_LED_SLOW_BLINK_ON_TIME = 0x43, + USB_HID_LED_SLOW_BLINK_OFF_TIME = 0x44, + USB_HID_LED_FAST_BLINK_ON_TIME = 0x45, + USB_HID_LED_FAST_BLINK_OFF_TIME = 0x46, + USB_HID_LED_USAGE_INDICATOR_COLOR = 0x47, + USB_HID_LED_INDICATOR_RED = 0x48, + USB_HID_LED_INDICATOR_GREEN = 0x49, + USB_HID_LED_INDICATOR_AMBER = 0x4A, + USB_HID_LED_GENERIC_INDICATOR = 0x4B, + USB_HID_LED_SYSTEM_SUSPEND = 0x4C, + USB_HID_LED_EXTERNAL_POWER_CONNECTED = 0x4D + /* Reserved = 0x4E-0xFFFF */ +} USB_HID_LED; + +typedef enum +{ + USB_HID_TELEPHONY_DEVICE_UNASSIGNED = 0x00, + USB_HID_TELEPHONY_DEVICE_PHONE = 0x01, + USB_HID_TELEPHONY_DEVICE_ANSWERING_MACHINE = 0x02, + USB_HID_TELEPHONY_DEVICE_MESSAGE_CONTROLS = 0x03, + USB_HID_TELEPHONY_DEVICE_HANDSET = 0x04, + USB_HID_TELEPHONY_DEVICE_HEADSET = 0x05, + USB_HID_TELEPHONY_DEVICE_TELEPHONY_KEY_PAD = 0x06, + USB_HID_TELEPHONY_DEVICE_PROGRAMMABLE_BUTTON = 0x07, + /* Reserved = 0x08-0x1F */ + USB_HID_TELEPHONY_DEVICE_HOOK_SWITCH = 0x20, + USB_HID_TELEPHONY_DEVICE_FLASH = 0x21, + USB_HID_TELEPHONY_DEVICE_FEATURE = 0x22, + USB_HID_TELEPHONY_DEVICE_HOLD = 0x23, + USB_HID_TELEPHONY_DEVICE_REDIAL = 0x24, + USB_HID_TELEPHONY_DEVICE_TRANSFER = 0x25, + USB_HID_TELEPHONY_DEVICE_DROP = 0x26, + USB_HID_TELEPHONY_DEVICE_PARK = 0x27, + USB_HID_TELEPHONY_DEVICE_FORWARD_CALLS = 0x28, + USB_HID_TELEPHONY_DEVICE_ALTERNATE_FUNCTION = 0x29, + USB_HID_TELEPHONY_DEVICE_LINE = 0x2A, + USB_HID_TELEPHONY_DEVICE_SPEAKER_PHONE = 0x2B, + USB_HID_TELEPHONY_DEVICE_CONFERENCE = 0x2C, + USB_HID_TELEPHONY_DEVICE_RING_ENABLE = 0x2D, + USB_HID_TELEPHONY_DEVICE_RING_SELECT = 0x2E, + USB_HID_TELEPHONY_DEVICE_PHONE_MUTE = 0x2F, + USB_HID_TELEPHONY_DEVICE_CALLER_ID = 0x30, + USB_HID_TELEPHONY_DEVICE_SEND = 0x31, + /* Reserved = 0x32-0x4F */ + USB_HID_TELEPHONY_DEVICE_SPEED_DIAL = 0x50, + USB_HID_TELEPHONY_DEVICE_STORE_NUMBER = 0x51, + USB_HID_TELEPHONY_DEVICE_RECALL_NUMBER = 0x52, + USB_HID_TELEPHONY_DEVICE_PHONE_DIRECTORY = 0x53, + /* Reserved = 0x54-0x6F */ + USB_HID_TELEPHONY_DEVICE_VOICE_MAIL = 0x70, + USB_HID_TELEPHONY_DEVICE_SCREEN_CALLS = 0x71, + USB_HID_TELEPHONY_DEVICE_DO_NOT_DISTURB = 0x72, + USB_HID_TELEPHONY_DEVICE_MESSAGE = 0x73, + USB_HID_TELEPHONY_DEVICE_ANSWER_ON_OFF = 0x74, + /* Reserved = 0x75-0x8F */ + USB_HID_TELEPHONY_DEVICE_INSIDE_DIAL_TONE = 0x90, + USB_HID_TELEPHONY_DEVICE_OUTSIDE_DIAL_TONE = 0x91, + USB_HID_TELEPHONY_DEVICE_INSIDE_RING_TONE = 0x92, + USB_HID_TELEPHONY_DEVICE_OUTSIDE_RING_TONE = 0x93, + USB_HID_TELEPHONY_DEVICE_PRIORITY_RING_TONE = 0x94, + USB_HID_TELEPHONY_DEVICE_INSIDE_RINGBACK = 0x95, + USB_HID_TELEPHONY_DEVICE_PRIORITY_RINGBACK = 0x96, + USB_HID_TELEPHONY_DEVICE_LINE_BUSY_TONE = 0x97, + USB_HID_TELEPHONY_DEVICE_REORDER_TONE = 0x98, + USB_HID_TELEPHONY_DEVICE_CALL_WAITING_TONE = 0x99, + USB_HID_TELEPHONY_DEVICE_CONFIRMATION_TONE_1 = 0x9A, + USB_HID_TELEPHONY_DEVICE_CONFIRMATION_TONE_2 = 0x9B, + USB_HID_TELEPHONY_DEVICE_TONES_OFF = 0x9C, + USB_HID_TELEPHONY_DEVICE_OUTSIDE_RINGBACK = 0x9D, + USB_HID_TELEPHONY_DEVICE_RINGER = 0x9E, + /* Reserved = 0x9F-0xAF */ + USB_HID_TELEPHONY_DEVICE_PHONE_KEY_0 = 0xB0, + USB_HID_TELEPHONY_DEVICE_PHONE_KEY_1 = 0xB1, + USB_HID_TELEPHONY_DEVICE_PHONE_KEY_2 = 0xB2, + USB_HID_TELEPHONY_DEVICE_PHONE_KEY_3 = 0xB3, + USB_HID_TELEPHONY_DEVICE_PHONE_KEY_4 = 0xB4, + USB_HID_TELEPHONY_DEVICE_PHONE_KEY_5 = 0xB5, + USB_HID_TELEPHONY_DEVICE_PHONE_KEY_6 = 0xB6, + USB_HID_TELEPHONY_DEVICE_PHONE_KEY_7 = 0xB7, + USB_HID_TELEPHONY_DEVICE_PHONE_KEY_8 = 0xB8, + USB_HID_TELEPHONY_DEVICE_PHONE_KEY_9 = 0xB9, + USB_HID_TELEPHONY_DEVICE_PHONE_KEY_STAR = 0xBA, + USB_HID_TELEPHONY_DEVICE_PHONE_KEY_POUND = 0xBB, + USB_HID_TELEPHONY_DEVICE_PHONE_KEY_A = 0xBC, + USB_HID_TELEPHONY_DEVICE_PHONE_KEY_B = 0xBD, + USB_HID_TELEPHONY_DEVICE_PHONE_KEY_C = 0xBE, + USB_HID_TELEPHONY_DEVICE_PHONE_KEY_D = 0xBF + /* Reserved = 0xC0-0xFFFF */ +} USB_HID_TELEPHONY_DEVICE; + +typedef enum +{ + USB_HID_CONSUMER_UNASSIGNED = 0x00, + USB_HID_CONSUMER_CONSUMER_CONTROL = 0x01, + USB_HID_CONSUMER_NUMERIC_KEY_PAD = 0x02, + USB_HID_CONSUMER_PROGRAMMABLE_BUTTONS = 0x03, + USB_HID_CONSUMER_MICROPHONE = 0x04, + USB_HID_CONSUMER_HEADPHONE = 0x05, + USB_HID_CONSUMER_GRAPHIC_EQUALIZER = 0x06, + /* Reserved = 0x07-0x1F */ + USB_HID_CONSUMER_PLUS_10 = 0x20, + USB_HID_CONSUMER_PLUS_100 = 0x21, + USB_HID_CONSUMER_AM_PM = 0x22, + /* Reserved = 0x23-0x2F */ + USB_HID_CONSUMER_POWER = 0x30, + USB_HID_CONSUMER_RESET = 0x31, + USB_HID_CONSUMER_SLEEP = 0x32, + USB_HID_CONSUMER_SLEEP_AFTER = 0x33, + USB_HID_CONSUMER_SLEEP_MODE = 0x34, + USB_HID_CONSUMER_ILLUMINATION = 0x35, + USB_HID_CONSUMER_FUNCTION_BUTTONS = 0x36, + /* Reserved = 0x37-0x3F */ + USB_HID_CONSUMER_MENU = 0x40, + USB_HID_CONSUMER_MENU_PICK = 0x41, + USB_HID_CONSUMER_MENU_UP = 0x42, + USB_HID_CONSUMER_MENU_DOWN = 0x43, + USB_HID_CONSUMER_MENU_LEFT = 0x44, + USB_HID_CONSUMER_MENU_RIGHT = 0x45, + USB_HID_CONSUMER_MENU_ESCAPE = 0x46, + USB_HID_CONSUMER_MENU_VALUE_INCREASE = 0x47, + USB_HID_CONSUMER_MENU_VALUE_DECREASE = 0x48, + /* Reserved = 0x49-0x5F */ + USB_HID_CONSUMER_DATA_ON_SCREEN = 0x60, + USB_HID_CONSUMER_CLOSED_CAPTION = 0x61, + USB_HID_CONSUMER_CLOSED_CAPTION_SELECT = 0x62, + USB_HID_CONSUMER_VCR_TV = 0x63, + USB_HID_CONSUMER_BROADCAST_MODE = 0x64, + USB_HID_CONSUMER_SNAPSHOT = 0x65, + USB_HID_CONSUMER_STILL = 0x66, + /* Reserved = 0x67-0x7F */ + USB_HID_CONSUMER_SELECTION = 0x80, + USB_HID_CONSUMER_ASSIGN_SELECTION = 0x81, + USB_HID_CONSUMER_MODE_STEP = 0x82, + USB_HID_CONSUMER_RECALL_LAST = 0x83, + USB_HID_CONSUMER_ENTER_CHANNEL = 0x84, + USB_HID_CONSUMER_ORDER_MOVIE = 0x85, + USB_HID_CONSUMER_CHANNEL = 0x86, + USB_HID_CONSUMER_MEDIA_SELECTION = 0x87, + USB_HID_CONSUMER_MEDIA_SELECT_COMPUTER = 0x88, + USB_HID_CONSUMER_MEDIA_SELECT_TV = 0x89, + USB_HID_CONSUMER_MEDIA_SELECT_WWW = 0x8A, + USB_HID_CONSUMER_MEDIA_SELECT_DVD = 0x8B, + USB_HID_CONSUMER_MEDIA_SELECT_TELEPHONE = 0x8C, + USB_HID_CONSUMER_MEDIA_SELECT_PROGRAM_GUIDE = 0x8D, + USB_HID_CONSUMER_MEDIA_SELECT_VIDEO_PHONE = 0x8E, + USB_HID_CONSUMER_MEDIA_SELECT_GAMES = 0x8F, + USB_HID_CONSUMER_MEDIA_SELECT_MESSAGES = 0x90, + USB_HID_CONSUMER_MEDIA_SELECT_CD = 0x91, + USB_HID_CONSUMER_MEDIA_SELECT_VCR = 0x92, + USB_HID_CONSUMER_MEDIA_SELECT_TUNER = 0x93, + USB_HID_CONSUMER_QUIT = 0x94, + USB_HID_CONSUMER_HELP = 0x95, + USB_HID_CONSUMER_MEDIA_SELECT_TAPE = 0x96, + USB_HID_CONSUMER_MEDIA_SELECT_CABLE = 0x97, + USB_HID_CONSUMER_MEDIA_SELECT_SATELLITE = 0x98, + USB_HID_CONSUMER_MEDIA_SELECT_SECURITY = 0x99, + USB_HID_CONSUMER_MEDIA_SELECT_HOME = 0x9A, + USB_HID_CONSUMER_MEDIA_SELECT_CALL = 0x9B, + USB_HID_CONSUMER_CHANNEL_INCREMENT = 0x9C, + USB_HID_CONSUMER_CHANNEL_DECREMENT = 0x9D, + USB_HID_CONSUMER_MEDIA_SELECT_SAP = 0x9E, + /* Reserved = 0x9F */ + USB_HID_CONSUMER_VCR_PLUS = 0xA0, + USB_HID_CONSUMER_ONCE = 0xA1, + USB_HID_CONSUMER_DAILY = 0xA2, + USB_HID_CONSUMER_WEEKLY = 0xA3, + USB_HID_CONSUMER_MONTHLY = 0xA4, + /* Reserved = 0xA5-0xAF */ + USB_HID_CONSUMER_PLAY = 0xB0, + USB_HID_CONSUMER_PAUSE = 0xB1, + USB_HID_CONSUMER_RECORD = 0xB2, + USB_HID_CONSUMER_FAST_FORWARD = 0xB3, + USB_HID_CONSUMER_REWIND = 0xB4, + USB_HID_CONSUMER_SCAN_NEXT_TRACK = 0xB5, + USB_HID_CONSUMER_SCAN_PREVIOUS_TRACK = 0xB6, + USB_HID_CONSUMER_STOP = 0xB7, + USB_HID_CONSUMER_EJECT = 0xB8, + USB_HID_CONSUMER_RANDOM_PLAY = 0xB9, + USB_HID_CONSUMER_SELECT_DISC = 0xBA, + USB_HID_CONSUMER_ENTER_DISC = 0xBB, + USB_HID_CONSUMER_REPEAT = 0xBC, + USB_HID_CONSUMER_TRACKING = 0xBD, + USB_HID_CONSUMER_TRACK_NORMAL = 0xBE, + USB_HID_CONSUMER_SLOW_TRACKING = 0xBF, + USB_HID_CONSUMER_FRAME_FORWARD = 0xC0, + USB_HID_CONSUMER_FRAME_BACK = 0xC1, + USB_HID_CONSUMER_MARK = 0xC2, + USB_HID_CONSUMER_CLEAR_MARK = 0xC3, + USB_HID_CONSUMER_REPEAT_FROM_MARK = 0xC4, + USB_HID_CONSUMER_RETURN_TO_MARK = 0xC5, + USB_HID_CONSUMER_SEARCH_MARK_FORWARD = 0xC6, + USB_HID_CONSUMER_SEARCH_MARK_BACKWARDS = 0xC7, + USB_HID_CONSUMER_COUNTER_RESET = 0xC8, + USB_HID_CONSUMER_SHOW_COUNTER = 0xC9, + USB_HID_CONSUMER_TRACKING_INCREMENT = 0xCA, + USB_HID_CONSUMER_TRACKING_DECREMENT = 0xCB, + USB_HID_CONSUMER_STOP_EJECT = 0xCC, + USB_HID_CONSUMER_PLAY_PAUSE = 0xCD, + USB_HID_CONSUMER_PLAY_SKIP = 0xCE, + /* Reserved = 0xCF-0xDF */ + USB_HID_CONSUMER_VOLUME = 0xE0, + USB_HID_CONSUMER_BALANCE = 0xE1, + USB_HID_CONSUMER_MUTE = 0xE2, + USB_HID_CONSUMER_BASS = 0xE3, + USB_HID_CONSUMER_TREBLE = 0xE4, + USB_HID_CONSUMER_BASS_BOOST = 0xE5, + USB_HID_CONSUMER_SURROUND_MODE = 0xE6, + USB_HID_CONSUMER_LOUDNESS = 0xE7, + USB_HID_CONSUMER_MPX = 0xE8, + USB_HID_CONSUMER_VOLUME_INCREMENT = 0xE9, + USB_HID_CONSUMER_VOLUME_DECREMENT = 0xEA, + /* Reserved = 0xEB-0xEF */ + USB_HID_CONSUMER_SPEED_SELECT = 0xF0, + USB_HID_CONSUMER_PLAYBACK_SPEED = 0xF1, + USB_HID_CONSUMER_STANDARD_PLAY = 0xF2, + USB_HID_CONSUMER_LONG_PLAY = 0xF3, + USB_HID_CONSUMER_EXTENDED_PLAY = 0xF4, + USB_HID_CONSUMER_SLOW = 0xF5, + /* Reserved = 0xF6-0xFF */ + USB_HID_CONSUMER_FAN_ENABLE = 0x100, + USB_HID_CONSUMER_FAN_SPEED = 0x101, + USB_HID_CONSUMER_LIGHT_ENABLE = 0x102, + USB_HID_CONSUMER_LIGHT_ILLUMINATION_LEVEL = 0x103, + USB_HID_CONSUMER_CLIMATE_CONTROL_ENABLE = 0x104, + USB_HID_CONSUMER_ROOM_TEMPERATURE = 0x105, + USB_HID_CONSUMER_SECURITY_ENABLE = 0x106, + USB_HID_CONSUMER_FIRE_ALARM = 0x107, + USB_HID_CONSUMER_POLICE_ALARM = 0x108, + USB_HID_CONSUMER_PROXIMITY = 0x109, + USB_HID_CONSUMER_MOTION = 0x10A, + USB_HID_CONSUMER_DURESS_ALARM = 0x10B, + USB_HID_CONSUMER_HOLDUP_ALARM = 0x10C, + USB_HID_CONSUMER_MEDICAL_ALARM = 0x10D, + /* Reserved = 0x10E-0x14F */ + USB_HID_CONSUMER_BALANCE_RIGHT = 0x150, + USB_HID_CONSUMER_BALANCE_LEFT = 0x151, + USB_HID_CONSUMER_BASS_INCREMENT = 0x152, + USB_HID_CONSUMER_BASS_DECREMENT = 0x153, + USB_HID_CONSUMER_TREBLE_INCREMENT = 0x154, + USB_HID_CONSUMER_TREBLE_DECREMENT = 0x155, + /* Reserved = 0x156-0x15F */ + USB_HID_CONSUMER_SPEAKER_SYSTEM = 0x160, + USB_HID_CONSUMER_CHANNEL_LEFT = 0x161, + USB_HID_CONSUMER_CHANNEL_RIGHT = 0x162, + USB_HID_CONSUMER_CHANNEL_CENTER = 0x163, + USB_HID_CONSUMER_CHANNEL_FRONT = 0x164, + USB_HID_CONSUMER_CHANNEL_CENTER_FRONT = 0x165, + USB_HID_CONSUMER_CHANNEL_SIDE = 0x166, + USB_HID_CONSUMER_CHANNEL_SURROUND = 0x167, + USB_HID_CONSUMER_CHANNEL_LOW_FREQUENCY_ENHANCEMENT = 0x168, + USB_HID_CONSUMER_CHANNEL_TOP = 0x169, + USB_HID_CONSUMER_CHANNEL_UNKNOWN = 0x16A, + /* Reserved = 0x16B-0x16F */ + USB_HID_CONSUMER_SUBCHANNEL = 0x170, + USB_HID_CONSUMER_SUBCHANNEL_INCREMENT = 0x171, + USB_HID_CONSUMER_SUBCHANNEL_DECREMENT = 0x172, + USB_HID_CONSUMER_ALTERNATE_AUDIO_INCREMENT = 0x173, + USB_HID_CONSUMER_ALTERNATE_AUDIO_DECREMENT = 0x174, + /* Reserved = 0x175-0x17F */ + USB_HID_CONSUMER_APPLICATION_LAUNCH_BUTTONS = 0x180, + USB_HID_CONSUMER_AL_LAUNCH_BUTTON_CONFIGURATION_TOOL = 0x181, + USB_HID_CONSUMER_AL_PROGRAMMABLE_BUTTON_CONFIGURATION = 0x182, + USB_HID_CONSUMER_AL_CONSUMER_CONTROL_CONFIGURATION = 0x183, + USB_HID_CONSUMER_AL_WORD_PROCESSOR = 0x184, + USB_HID_CONSUMER_AL_TEXT_EDITOR = 0x185, + USB_HID_CONSUMER_AL_SPREADSHEET = 0x186, + USB_HID_CONSUMER_AL_GRAPHICS_EDITOR = 0x187, + USB_HID_CONSUMER_AL_PRESENTATION_APP = 0x188, + USB_HID_CONSUMER_AL_DATABASE_APP = 0x189, + USB_HID_CONSUMER_AL_EMAIL_READER = 0x18A, + USB_HID_CONSUMER_AL_NEWSREADER = 0x18B, + USB_HID_CONSUMER_AL_VOICEMAIL = 0x18C, + USB_HID_CONSUMER_AL_CONTACT_ADDRESS_BOOK = 0x18D, + USB_HID_CONSUMER_AL_CALENDAR_SCHEDULE = 0x18E, + USB_HID_CONSUMER_AL_TASK_PROJECT_MANAGER = 0x18F, + USB_HID_CONSUMER_AL_LOG_JOURNAL_TIMECARD = 0x190, + USB_HID_CONSUMER_AL_CHECKBOOK_FINANCE = 0x191, + USB_HID_CONSUMER_AL_CALCULATOR = 0x192, + USB_HID_CONSUMER_AL_AV_CAPTURE_PLAYBACK = 0x193, + USB_HID_CONSUMER_AL_LOCAL_MACHINE_BROWSER = 0x194, + USB_HID_CONSUMER_AL_LAN_WAN_BROWSER = 0x195, + USB_HID_CONSUMER_AL_INTERNET_BROWSER = 0x196, + USB_HID_CONSUMER_AL_REMOTE_NETOWORKING_ISP_CONNECT = 0x197, + USB_HID_CONSUMER_AL_NETWORK_CONFERENCE = 0x198, + USB_HID_CONSUMER_AL_NETOWRK_CHAT = 0x199, + USB_HID_CONSUMER_AL_TELEPHONY_DIALER = 0x19A, + USB_HID_CONSUMER_AL_LOGON = 0x19B, + USB_HID_CONSUMER_AL_LOGOFF = 0x19C, + USB_HID_CONSUMER_AL_LOGON_LOGOFF = 0x19D, + USB_HID_CONSUMER_AL_TERMINAL_LOCK_SCREENSAVER = 0x19E, + USB_HID_CONSUMER_AL_CONTROL_PANEL = 0x19F, + USB_HID_CONSUMER_AL_COMMAND_LINE_PROCESSOR_RUN = 0x1A0, + USB_HID_CONSUMER_AL_PROCESS_TASK_MANAGER = 0x1A1, + USB_HID_CONSUMER_AL_SELECT_TASK_APPLICATION = 0x1A2, + USB_HID_CONSUMER_AL_NEXT_TASK_APPLICATION = 0x1A3, + USB_HID_CONSUMER_AL_PREVIOUS_TASK_APPLICATION = 0x1A4, + USB_HID_CONSUMER_AL_PREEMPTIVE_HALT_TASK_APPLICATION = 0x1A5, + USB_HID_CONSUMER_AL_INTEGRATED_HELP_CENTER = 0x1A6, + USB_HID_CONSUMER_AL_DOCUMENTS = 0x1A7, + USB_HID_CONSUMER_AL_THESAURUS = 0x1A8, + USB_HID_CONSUMER_AL_DICTIONARY = 0x1A9, + USB_HID_CONSUMER_AL_DESKTOP = 0x1AA, + USB_HID_CONSUMER_AL_SPELL_CHECK = 0x1AB, + USB_HID_CONSUMER_AL_GRAMMER_CHECK = 0x1AC, + USB_HID_CONSUMER_AL_WIRELESS_STATUS = 0x1AD, + USB_HID_CONSUMER_AL_KEYBOARD_LAYOUT = 0x1AE, + USB_HID_CONSUMER_AL_VIRUS_PROTECTION = 0x1AF, + USB_HID_CONSUMER_AL_ENCRYPTION = 0x1B0, + USB_HID_CONSUMER_AL_SCREEN_SAVER = 0x1B1, + USB_HID_CONSUMER_AL_ALARMS = 0x1B2, + USB_HID_CONSUMER_AL_CLOCK = 0x1B3, + USB_HID_CONSUMER_AL_FILE_BROWSER = 0x1B4, + USB_HID_CONSUMER_AL_POWER_STATUS = 0x1B5, + USB_HID_CONSUMER_AL_IMAGE_BROWSER = 0x1B6, + USB_HID_CONSUMER_AL_AUDIO_BROWSER = 0x1B7, + USB_HID_CONSUMER_AL_MOVIE_BROWSER = 0x1B8, + USB_HID_CONSUMER_AL_DIGITAL_RIGHTS_MANAGER = 0x1B9, + USB_HID_CONSUMER_AL_DIGITAL_WALLET = 0x1BA, + /* Reserved = 0x1BB */ + USB_HID_CONSUMER_AL_INSTANT_MESSAGING = 0x1BC, + USB_HID_CONSUMER_AL_OEM_FEATURES_TIPS_TUTORIAL_BROWSER = 0x1BD, + USB_HID_CONSUMER_AL_OEM_HELP = 0x1BE, + USB_HID_CONSUMER_AL_ONLINE_COMMUNITY = 0x1BF, + USB_HID_CONSUMER_AL_ENTERTAINMENT_CONTENT_BROWSER = 0x1C0, + USB_HID_CONSUMER_AL_ONLINE_SHOPPING_BROWSER = 0x1C1, + USB_HID_CONSUMER_AL_SMARTCARD_INFORMATION_HELP = 0x1C2, + USB_HID_CONSUMER_AL_MARKET_MONITOR_FINANCE_BROWSER = 0x1C3, + USB_HID_CONSUMER_AL_CUSTOMIZED_CORPORATE_NEWS_BROWSER = 0x1C4, + USB_HID_CONSUMER_AL_ONLINE_ACTIVITY_BROWSER = 0x1C5, + USB_HID_CONSUMER_AL_RESEARCH_SERACH_BROWSER = 0x1C6, + USB_HID_CONSUMER_AL_AUDIO_PLAYER = 0x1C7, + /* Reserved = 0x1C8-0x1FF */ + USB_HID_CONSUMER_GENERIC_GUI_APPLICATION_CONTROLS = 0x200, + USB_HID_CONSUMER_AC_NEW = 0x201, + USB_HID_CONSUMER_AC_OPEN = 0x202, + USB_HID_CONSUMER_AC_CLOSE = 0x203, + USB_HID_CONSUMER_AC_EXIT = 0x204, + USB_HID_CONSUMER_AC_MAXIMIZE = 0x205, + USB_HID_CONSUMER_AC_MINIMIZE = 0x206, + USB_HID_CONSUMER_AC_SAVE = 0x207, + USB_HID_CONSUMER_AC_PRINT = 0x208, + USB_HID_CONSUMER_AC_PROPERTIES = 0x209, + /* Unspecified = 0x20A-0x219 */ + USB_HID_CONSUMER_AC_UNDO = 0x21A, + USB_HID_CONSUMER_AC_COPY = 0x21B, + USB_HID_CONSUMER_AC_CUT = 0x21C, + USB_HID_CONSUMER_AC_PASTE = 0x21D, + USB_HID_CONSUMER_AC_SELECT_ALL = 0x21E, + USB_HID_CONSUMER_AC_FIND = 0x21F, + USB_HID_CONSUMER_AC_FIND_AND_REPLACE = 0x220, + USB_HID_CONSUMER_AC_SEARCH = 0x221, + USB_HID_CONSUMER_AC_GO_TO = 0x222, + USB_HID_CONSUMER_AC_HOME = 0x223, + USB_HID_CONSUMER_AC_BACK = 0x224, + USB_HID_CONSUMER_AC_FORWARD = 0x225, + USB_HID_CONSUMER_AC_STOP = 0x226, + USB_HID_CONSUMER_AC_REFRESH = 0x227, + USB_HID_CONSUMER_AC_PREVIOUS_LINK = 0x228, + USB_HID_CONSUMER_AC_NEXT_LINK = 0x229, + USB_HID_CONSUMER_AC_BOOKMARKS = 0x22A, + USB_HID_CONSUMER_AC_HISTORY = 0x22B, + USB_HID_CONSUMER_AC_SUBSCRIPTIONS = 0x22C, + USB_HID_CONSUMER_AC_ZOOM_IN = 0x22D, + USB_HID_CONSUMER_AC_ZOOM_OUT = 0x22E, + USB_HID_CONSUMER_AC_ZOOM = 0x22F, + USB_HID_CONSUMER_AC_FULL_SCREEN_VIEW = 0x230, + USB_HID_CONSUMER_AC_NORMAL_VIEW = 0x231, + USB_HID_CONSUMER_AC_VIEW_TOGGLE = 0x232, + USB_HID_CONSUMER_AC_SCROLL_UP = 0x233, + USB_HID_CONSUMER_AC_SCROLL_DOWN = 0x234, + USB_HID_CONSUMER_AC_SCROLL = 0x235, + USB_HID_CONSUMER_AC_PAN_LEFT = 0x236, + USB_HID_CONSUMER_AC_PAN_RIGHT = 0x237, + USB_HID_CONSUMER_AC_PAN = 0x238, + USB_HID_CONSUMER_AC_NEW_WINDOW = 0x239, + USB_HID_CONSUMER_AC_TILE_HORIZONTALLY = 0x23A, + USB_HID_CONSUMER_AC_TILE_VERTICALLY = 0x23B, + USB_HID_CONSUMER_AC_FORMAT = 0x23C, + USB_HID_CONSUMER_AC_EDIT = 0x23D, + USB_HID_CONSUMER_AC_BOLD = 0x23E, + USB_HID_CONSUMER_AC_ITALICS = 0x23F, + USB_HID_CONSUMER_AC_UNDERLINE = 0x240, + USB_HID_CONSUMER_AC_STRIKETHROUGH = 0x241, + USB_HID_CONSUMER_AC_SUBSCRIPT = 0x242, + USB_HID_CONSUMER_AC_SUPERSCRIPT = 0x243, + USB_HID_CONSUMER_AC_ALL_CAPS = 0x244, + USB_HID_CONSUMER_AC_ROTATE = 0x245, + USB_HID_CONSUMER_AC_RESIZE = 0x246, + USB_HID_CONSUMER_AC_FLIP_HORIZONTAL = 0x247, + USB_HID_CONSUMER_AC_FLIP_VERTICALLY = 0x248, + USB_HID_CONSUMER_AC_MIRROR_HORIZONTAL = 0x249, + USB_HID_CONSUMER_AC_MIRROR_VERTICAL = 0x24A, + USB_HID_CONSUMER_AC_FONT_SELECT = 0x24B, + USB_HID_CONSUMER_AC_FONT_COLOR = 0x24C, + USB_HID_CONSUMER_AC_FONT_SIZE = 0x24D, + USB_HID_CONSUMER_AC_JUSTIFY_LEFT = 0x24E, + USB_HID_CONSUMER_AC_JUSTIFY_CENTER_H = 0x24F, + USB_HID_CONSUMER_AC_JUSTIFY_RIGHT = 0x250, + USB_HID_CONSUMER_AC_JUSTIFY_BLOCK_H = 0x251, + USB_HID_CONSUMER_AC_JUSTIFY_TOP = 0x252, + USB_HID_CONSUMER_AC_JUSTIFY_CENTER_V = 0x253, + USB_HID_CONSUMER_AC_JUSTIFY_BOTTOM = 0x254, + USB_HID_CONSUMER_AC_JUSTIFY_BLOCK_V = 0x255, + USB_HID_CONSUMER_AC_INDENT_DESCREASE = 0x256, + USB_HID_CONSUMER_AC_INDENT_INCREASE = 0x257, + USB_HID_CONSUMER_AC_NUMBERED_LIST = 0x258, + USB_HID_CONSUMER_AC_RESTART_NUMBERING = 0x259, + USB_HID_CONSUMER_AC_BULLETED_LIST = 0x25A, + USB_HID_CONSUMER_AC_PROMOTE = 0x25B, + USB_HID_CONSUMER_AC_DEMOTE = 0x25C, + USB_HID_CONSUMER_AC_YES = 0x25D, + USB_HID_CONSUMER_AC_NO = 0x25E, + USB_HID_CONSUMER_AC_CANCEL = 0x25F, + USB_HID_CONSUMER_AC_CATALOG = 0x260, + USB_HID_CONSUMER_AC_BUY_CHECKOUT = 0x261, + USB_HID_CONSUMER_AC_ADD_TO_CART = 0x262, + USB_HID_CONSUMER_AC_EXPAND = 0x263, + USB_HID_CONSUMER_AC_EXPAND_ALL = 0x264, + USB_HID_CONSUMER_AC_COLLAPSE = 0x265, + USB_HID_CONSUMER_AC_COLLAPSE_ALL = 0x266, + USB_HID_CONSUMER_AC_PRINT_PREVIEW = 0x267, + USB_HID_CONSUMER_AC_PASTE_SPECIAL = 0x268, + USB_HID_CONSUMER_AC_INSERT_MODE = 0x269, + USB_HID_CONSUMER_AC_DELETE = 0x26A, + USB_HID_CONSUMER_AC_LOCK = 0x26B, + USB_HID_CONSUMER_AC_UNLOCK = 0x26C, + USB_HID_CONSUMER_AC_PROTECT = 0x26D, + USB_HID_CONSUMER_AC_UNPROTECT = 0x26E, + USB_HID_CONSUMER_AC_ATTACH_COMMENT = 0x26F, + USB_HID_CONSUMER_AC_DELETE_COMMENT = 0x270, + USB_HID_CONSUMER_AC_VIEW_COMMENT = 0x271, + USB_HID_CONSUMER_AC_SELECT_WORD = 0x272, + USB_HID_CONSUMER_AC_SELECT_SENTENCE = 0x273, + USB_HID_CONSUMER_AC_SELECT_PARAGRAPH = 0x274, + USB_HID_CONSUMER_AC_SELECT_COLUMN = 0x275, + USB_HID_CONSUMER_AC_SELECT_ROW = 0x276, + USB_HID_CONSUMER_AC_SELECT_TABLE = 0x277, + USB_HID_CONSUMER_AC_SELECT_OBJECT = 0x278, + USB_HID_CONSUMER_AC_SELECT_REDO_REPEAT = 0x279, + USB_HID_CONSUMER_AC_SORT = 0x27A, + USB_HID_CONSUMER_AC_SORT_ASCENDING = 0x27B, + USB_HID_CONSUMER_AC_SORT_DESCENDING = 0x27C, + USB_HID_CONSUMER_AC_FILTER = 0x27D, + USB_HID_CONSUMER_AC_SET_CLOCK = 0x27E, + USB_HID_CONSUMER_AC_VIEW_CLOCK = 0x27F, + USB_HID_CONSUMER_AC_SELECT_TIME_ZONE = 0x280, + USB_HID_CONSUMER_AC_EDIT_TIME_ZONE = 0x281, + USB_HID_CONSUMER_AC_SET_ALARM = 0x282, + USB_HID_CONSUMER_AC_CLEAR_ALARM = 0x283, + USB_HID_CONSUMER_AC_SNOOZE_ALARM = 0x284, + USB_HID_CONSUMER_AC_RESET_ALARM = 0x285, + USB_HID_CONSUMER_AC_SYNCHRONIZE = 0x286, + USB_HID_CONSUMER_AC_SEND_RECEIVE = 0x287, + USB_HID_CONSUMER_AC_SEND_TO = 0x288, + USB_HID_CONSUMER_AC_REPLY = 0x289, + USB_HID_CONSUMER_AC_REPLY_ALL = 0x28A, + USB_HID_CONSUMER_AC_FORWARD_MSG = 0x28B, + USB_HID_CONSUMER_AC_SEND = 0x28C, + USB_HID_CONSUMER_AC_ATTACH_FILE = 0x28D, + USB_HID_CONSUMER_AC_UPLOAD = 0x28E, + USB_HID_CONSUMER_AC_DOWNLOAD_SAVE_TARGET_AS = 0x28F, + USB_HID_CONSUMER_AC_SET_BORDERS = 0x290, + USB_HID_CONSUMER_AC_INSERT_ROW = 0x291, + USB_HID_CONSUMER_AC_INSERT_COLUMN = 0x292, + USB_HID_CONSUMER_AC_INSERT_FILE = 0x293, + USB_HID_CONSUMER_AC_INSERT_PICTURE = 0x294, + USB_HID_CONSUMER_AC_INSERT_OBJECT = 0x295, + USB_HID_CONSUMER_AC_INSERT_SYMBOL = 0x296, + USB_HID_CONSUMER_AC_SAVE_AND_CLOSE = 0x297, + USB_HID_CONSUMER_AC_RENAME = 0x298, + USB_HID_CONSUMER_AC_MERGE = 0x299, + USB_HID_CONSUMER_AC_SPLIT = 0x29A, + USB_HID_CONSUMER_AC_DISTRIBUTE_HORIZONTALLY = 0x29B, + USB_HID_CONSUMER_AC_DISTRIBUTE_VERTICALLY = 0x29C + /* Reserved = 0x29D-0xFFFF */ +} USB_HID_CONSUMER; + +typedef enum +{ + USB_HID_DIGITIZERS_UNDEFINED = 0x00, + USB_HID_DIGITIZERS_DIGITIZER = 0x01, + USB_HID_DIGITIZERS_PEN = 0x02, + USB_HID_DIGITIZERS_LIGHT_PEN = 0x03, + USB_HID_DIGITIZERS_TOUCH_SCREEN = 0x04, + USB_HID_DIGITIZERS_TOUCH_PAD = 0x05, + USB_HID_DIGITIZERS_WHITE_BOARD = 0x06, + USB_HID_DIGITIZERS_COORDINATE_MEASURING_MACHINE = 0x07, + USB_HID_DIGITIZERS_3D_DIGITIZER = 0x08, + USB_HID_DIGITIZERS_STEREO_PLOTTER = 0x09, + USB_HID_DIGITIZERS_ARTICULATED_ARM = 0x0A, + USB_HID_DIGITIZERS_ARMATURE = 0x0B, + USB_HID_DIGITIZERS_MULTIPLE_POINT_DIGITIZER = 0x0C, + USB_HID_DIGITIZERS_FREE_SPACE_WAND = 0x0D, + /* Reserved = 0x0E-0x1F */ + USB_HID_DIGITIZERS_STYLUS = 0x20, + USB_HID_DIGITIZERS_PUCK = 0x21, + USB_HID_DIGITIZERS_FINGER = 0x22, + /* Reserved = 0x23-0x2F */ + USB_HID_DIGITIZERS_TIP_PRESSURE = 0x30, + USB_HID_DIGITIZERS_BARREL_PRESSURE = 0x31, + USB_HID_DIGITIZERS_IN_RANGE = 0x32, + USB_HID_DIGITIZERS_TOUCH = 0x33, + USB_HID_DIGITIZERS_UNTOUCH = 0x34, + USB_HID_DIGITIZERS_TAP = 0x35, + USB_HID_DIGITIZERS_QUALITY = 0x36, + USB_HID_DIGITIZERS_DATA_VALID = 0x37, + USB_HID_DIGITIZERS_TRANSDUCER_INDEX = 0x38, + USB_HID_DIGITIZERS_TABLET_FUNCTION_KEYS = 0x39, + USB_HID_DIGITIZERS_PROGRAMMING_CHANGE_KEYS = 0x3A, + USB_HID_DIGITIZERS_BATTERY_STRENGTH = 0x3B, + USB_HID_DIGITIZERS_INVERT = 0x3C, + USB_HID_DIGITIZERS_X_TILT = 0x3D, + USB_HID_DIGITIZERS_Y_TILT = 0x3E, + USB_HID_DIGITIZERS_AZIMUTH = 0x3F, + USB_HID_DIGITIZERS_ALTITUDE = 0x40, + USB_HID_DIGITIZERS_TWIST = 0x41, + USB_HID_DIGITIZERS_TIP_SWITCH = 0x42, + USB_HID_DIGITIZERS_SECONDARY_TIP_SWITCH = 0x43, + USB_HID_DIGITIZERS_BARREL_SWITCH = 0x44, + USB_HID_DIGITIZERS_ERASER = 0x45, + USB_HID_DIGITIZERS_TABLET_PICK = 0x46 + /* Reserved = 0x47-0xFFFF */ +} USB_HID_DIGITIZERS; + +typedef enum +{ + USB_HID_ALPHANUMERIC_DISPLAY_UNDEFINED = 0x00, + USB_HID_ALPHANUMERIC_DISPLAY_ALPHANUMERIC_DISPLAY = 0x01, + USB_HID_ALPHANUMERIC_DISPLAY_BITMAPPED_DISPLAY = 0x02, + /* Reserved = 0x03-0x1F */ + USB_HID_ALPHANUMERIC_DISPLAY_DISPLAY_ATTRIBUTES_REPORT = 0x20, + USB_HID_ALPHANUMERIC_DISPLAY_ASCII_CHARACTER_SET = 0x21, + USB_HID_ALPHANUMERIC_DISPLAY_DATA_READ_BACK = 0x22, + USB_HID_ALPHANUMERIC_DISPLAY_FONT_READ_BACK = 0x23, + USB_HID_ALPHANUMERIC_DISPLAY_DISPLAY_CONTROL_REPORT = 0x24, + USB_HID_ALPHANUMERIC_DISPLAY_CLEAR_DISPLAY = 0x25, + USB_HID_ALPHANUMERIC_DISPLAY_DISPLAY_ENABLE = 0x26, + USB_HID_ALPHANUMERIC_DISPLAY_SCREEN_SAVER_DELAY = 0x27, + USB_HID_ALPHANUMERIC_DISPLAY_SCREEN_SAVER_ENABLE = 0x28, + USB_HID_ALPHANUMERIC_DISPLAY_VERTICAL_SCROLL = 0x29, + USB_HID_ALPHANUMERIC_DISPLAY_HORIZONTAL_SCROLL = 0x2A, + USB_HID_ALPHANUMERIC_DISPLAY_CHARACTER_REPORT = 0x2B, + USB_HID_ALPHANUMERIC_DISPLAY_DISPLAY_DATA = 0x2C, + USB_HID_ALPHANUMERIC_DISPLAY_DISPLAY_STATUS = 0x2D, + USB_HID_ALPHANUMERIC_DISPLAY_STAT_NOT_READY = 0x2E, + USB_HID_ALPHANUMERIC_DISPLAY_STAT_READY = 0x2F, + USB_HID_ALPHANUMERIC_DISPLAY_ERR_NOT_A_LOADABLE_CHARACTER = 0x30, + USB_HID_ALPHANUMERIC_DISPLAY_ERR_FONT_DATA_CANNOT_BE_READ = 0x31, + USB_HID_ALPHANUMERIC_DISPLAY_CURSOR_POSITION_REPORT = 0x32, + USB_HID_ALPHANUMERIC_DISPLAY_ROW = 0x33, + USB_HID_ALPHANUMERIC_DISPLAY_COLUMN = 0x34, + USB_HID_ALPHANUMERIC_DISPLAY_ROWS = 0x35, + USB_HID_ALPHANUMERIC_DISPLAY_COLUMNS = 0x36, + USB_HID_ALPHANUMERIC_DISPLAY_CURSOR_PIXEL_POSITION = 0x37, + USB_HID_ALPHANUMERIC_DISPLAY_CURSOR_MODE = 0x38, + USB_HID_ALPHANUMERIC_DISPLAY_CURSOR_ENABLE = 0x39, + USB_HID_ALPHANUMERIC_DISPLAY_CURSOR_BLINK = 0x3A, + USB_HID_ALPHANUMERIC_DISPLAY_FONT_REPORT = 0x3B, + USB_HID_ALPHANUMERIC_DISPLAY_FONT_DATA = 0x3C, + USB_HID_ALPHANUMERIC_DISPLAY_CHARACTER_WIDTH = 0x3D, + USB_HID_ALPHANUMERIC_DISPLAY_CHARACTER_HEIGHT = 0x3E, + USB_HID_ALPHANUMERIC_DISPLAY_CHARACTER_SPACING_HORIZONTAL = 0x3F, + USB_HID_ALPHANUMERIC_DISPLAY_CHARACTER_SPACING_VERTICAL = 0x40, + USB_HID_ALPHANUMERIC_DISPLAY_UNICODE_CHARACTER_SET = 0x41, + USB_HID_ALPHANUMERIC_DISPLAY_FONT_7_SEGMENT = 0x42, + USB_HID_ALPHANUMERIC_DISPLAY_7_SEGMENT_DIRECT_MAP = 0x43, + USB_HID_ALPHANUMERIC_DISPLAY_FONT_14_SEGMENT = 0x44, + USB_HID_ALPHANUMERIC_DISPLAY_14_SEGMENT_DIRECT_MAP = 0x45, + USB_HID_ALPHANUMERIC_DISPLAY_DISPLAY_BRIGHTNESS = 0x46, + USB_HID_ALPHANUMERIC_DISPLAY_DISPLAY_CONTRAST = 0x47, + USB_HID_ALPHANUMERIC_DISPLAY_CHARACTER_ATTRIBUTE = 0x48, + USB_HID_ALPHANUMERIC_DISPLAY_ATTRIBUTE_READBACK = 0x49, + USB_HID_ALPHANUMERIC_DISPLAY_ATTRIBUTE_DATA = 0x4A, + USB_HID_ALPHANUMERIC_DISPLAY_CHAR_ATTR_ENHANCE = 0x4B, + USB_HID_ALPHANUMERIC_DISPLAY_CHAR_ATTR_UNDERLINE = 0x4C, + USB_HID_ALPHANUMERIC_DISPLAY_CHAR_ATTR_BLINK = 0x4D, + /* Reserved = 0x4E-0x7F */ + USB_HID_ALPHANUMERIC_DISPLAY_BITMAP_SIZE_X = 0x80, + USB_HID_ALPHANUMERIC_DISPLAY_BITMAP_SIZE_Y = 0x81, + /* Reserved = 0x82 */ + USB_HID_ALPHANUMERIC_DISPLAY_BIT_DEPTH_FORMAT = 0x83, + USB_HID_ALPHANUMERIC_DISPLAY_DISPLAY_ORIENTATION = 0x84, + USB_HID_ALPHANUMERIC_DISPLAY_PALETTE_REPORT = 0x85, + USB_HID_ALPHANUMERIC_DISPLAY_PALETTE_DATA_SIZE = 0x86, + USB_HID_ALPHANUMERIC_DISPLAY_PALETTE_DATA_OFFSET = 0x87, + USB_HID_ALPHANUMERIC_DISPLAY_PALETTE_DATA = 0x88, + /* Unspecified = 0x89 */ + USB_HID_ALPHANUMERIC_DISPLAY_BLIT_REPORT = 0x8A, + USB_HID_ALPHANUMERIC_DISPLAY_BLIT_RECTANGLE_X1 = 0x8B, + USB_HID_ALPHANUMERIC_DISPLAY_BLIT_RECTANGLE_Y1 = 0x8C, + USB_HID_ALPHANUMERIC_DISPLAY_BLIT_RECTANGLE_X2 = 0x8D, + USB_HID_ALPHANUMERIC_DISPLAY_BLIT_RECTANGLE_Y2 = 0x8E, + USB_HID_ALPHANUMERIC_DISPLAY_BLIT_DATA = 0x8F, + USB_HID_ALPHANUMERIC_DISPLAY_SOFT_BUTTON = 0x90, + USB_HID_ALPHANUMERIC_DISPLAY_SOFT_BUTTON_ID = 0x91, + USB_HID_ALPHANUMERIC_DISPLAY_SOFT_BUTTON_SIDE = 0x92, + USB_HID_ALPHANUMERIC_DISPLAY_SOFT_BUTTON_OFFSET_1 = 0x93, + USB_HID_ALPHANUMERIC_DISPLAY_SOFT_BUTTON_OFFSET_2 = 0x94, + USB_HID_ALPHANUMERIC_DISPLAY_SOFT_BUTTON_REPORT = 0x95 + /* Reserved = 0x96-0xFFFF */ +} USB_HID_ALPHANUMERIC_DISPLAY; + +typedef enum +{ + USB_HID_MEDICAL_INSTRUMENT_UNDEFINED = 0x00, + USB_HID_MEDICAL_INSTRUMENT_MEDICAL_ULTRASOUND = 0x01, + /* Reserved = 0x02-0x1F */ + USB_HID_MEDICAL_INSTRUMENT_VCR_ACQUISITION = 0x20, + USB_HID_MEDICAL_INSTRUMENT_FREEZE_THAW = 0x21, + USB_HID_MEDICAL_INSTRUMENT_CLIP_STORE = 0x22, + USB_HID_MEDICAL_INSTRUMENT_UPDATE = 0x23, + USB_HID_MEDICAL_INSTRUMENT_NEXT = 0x24, + USB_HID_MEDICAL_INSTRUMENT_SAVE = 0x25, + USB_HID_MEDICAL_INSTRUMENT_PRINT = 0x26, + USB_HID_MEDICAL_INSTRUMENT_MICROPHONE_ENABLE = 0x27, + /* Reserved = 0x28-0x3F */ + USB_HID_MEDICAL_INSTRUMENT_CINE = 0x40, + USB_HID_MEDICAL_INSTRUMENT_TRANSMIT_POWER = 0x41, + USB_HID_MEDICAL_INSTRUMENT_VOLUME = 0x42, + USB_HID_MEDICAL_INSTRUMENT_FOCUS = 0x43, + USB_HID_MEDICAL_INSTRUMENT_DEPTH = 0x44, + /* Reserved = 0x45-0x5F */ + USB_HID_MEDICAL_INSTRUMENT_SOFT_STEP_PRIMARY = 0x60, + USB_HID_MEDICAL_INSTRUMENT_SOFT_STEP_SECONDARY = 0x61, + /* Reserved = 0x62-0x6F */ + USB_HID_MEDICAL_INSTRUMENT_DEPTH_GAIN_COMPENSATION = 0x70, + /* Reserved = 0x71-0x7F */ + USB_HID_MEDICAL_INSTRUMENT_ZOOM_SELECT = 0x80, + USB_HID_MEDICAL_INSTRUMENT_ZOOM_ADJUST = 0x81, + USB_HID_MEDICAL_INSTRUMENT_SPECTRAL_DOPPLER_MODE_SELECT = 0x82, + USB_HID_MEDICAL_INSTRUMENT_SPECTRAL_DOPPLER_ADJUST = 0x83, + USB_HID_MEDICAL_INSTRUMENT_COLOR_DOPPLER_MODE_SELECT = 0x84, + USB_HID_MEDICAL_INSTRUMENT_COLOR_COPPLER_ADJUST = 0x85, + USB_HID_MEDICAL_INSTRUMENT_MOTION_MODE_SELECT = 0x86, + USB_HID_MEDICAL_INSTRUMENT_MOTION_MODE_ADJUST = 0x87, + USB_HID_MEDICAL_INSTRUMENT_2D_MODE_SELECT = 0x88, + USB_HID_MEDICAL_INSTRUMENT_2D_MODE_ADJUST = 0x89, + /* Reserved = 0x8A-0x9F */ + USB_HID_MEDICAL_INSTRUMENT_SOFT_CONTROL_SELECT = 0xA0, + USB_HID_MEDICAL_INSTRUMENT_SOFT_CONTROL_ADJUST = 0xA1 + /* Reserved = 0xA2-0xFFFF */ +} USB_HID_MEDICAL_INSTRUMENT; + +typedef enum +{ + USB_HID_MONITOR_RESERVED = 0x00, + USB_HID_MONITOR_MONITOR_CONTROL = 0x01, + USB_HID_MONITOR_EDID_INFORMATION = 0x02, + USB_HID_MONITOR_VDIF_INFORMATION = 0x03, + USB_HID_MONITOR_VESA_VERSION = 0x04 +} USB_HID_MONITOR; + +typedef enum +{ + /* Contiguous controls */ + USB_HID_MONITOR_VESA_VIRTUAL_CONTROLS_BRIGHTNESS = 0x10, + USB_HID_MONITOR_VESA_VIRTUAL_CONTROLS_CONTRAST = 0x12, + USB_HID_MONITOR_VESA_VIRTUAL_CONTROLS_RED_VIDEO_GAIN = 0x16, + USB_HID_MONITOR_VESA_VIRTUAL_CONTROLS_GREEN_VIDEO_GAIN = 0x18, + USB_HID_MONITOR_VESA_VIRTUAL_CONTROLS_BLUE_VIDEO_GAIN = 0x1A, + USB_HID_MONITOR_VESA_VIRTUAL_CONTROLS_FOCUS = 0x1C, + USB_HID_MONITOR_VESA_VIRTUAL_CONTROLS_HORIZONTAL_POSITION = 0x20, + USB_HID_MONITOR_VESA_VIRTUAL_CONTROLS_HORIZONTAL_SIZE = 0x22, + USB_HID_MONITOR_VESA_VIRTUAL_CONTROLS_HORIZONTAL_PINCUSHION = 0x24, + USB_HID_MONITOR_VESA_VIRTUAL_CONTROLS_HORIZONTAL_PINCUSHION_BALANCE = 0x26, + USB_HID_MONITOR_VESA_VIRTUAL_CONTROLS_HORIZONTAL_MISCONVERGENCE = 0x28, + USB_HID_MONITOR_VESA_VIRTUAL_CONTROLS_HORIZONTAL_LINEARITY = 0x2A, + USB_HID_MONITOR_VESA_VIRTUAL_CONTROLS_HORIZONTAL_LINEARITY_BALANCE = 0x2C, + USB_HID_MONITOR_VESA_VIRTUAL_CONTROLS_VERTICAL_POSITION = 0x30, + USB_HID_MONITOR_VESA_VIRTUAL_CONTROLS_VERITCAL_SIZE = 0x32, + USB_HID_MONITOR_VESA_VIRTUAL_CONTROLS_VERTICAL_PINCUSHION = 0x34, + USB_HID_MONITOR_VESA_VIRTUAL_CONTROLS_VERTICAL_PINCUSHION_BALANCE = 0x36, + USB_HID_MONITOR_VESA_VIRTUAL_CONTROLS_VERTICAL_MISCONVERGENCE = 0x38, + USB_HID_MONITOR_VESA_VIRTUAL_CONTROLS_VERTICAL_LINEARITY = 0x3A, + USB_HID_MONITOR_VESA_VIRTUAL_CONTROLS_VERTICAL_LINEARITY_BALANCE = 0x3C, + USB_HID_MONITOR_VESA_VIRTUAL_CONTROLS_PARALLELOGRAM_DISTORTION_KEY_BALANCE = 0x40, + USB_HID_MONITOR_VESA_VIRTUAL_CONTROLS_TRAPEZOIDAL_DISTORTION_KEY = 0x42, + USB_HID_MONITOR_VESA_VIRTUAL_CONTROLS_TILT_ROTATION = 0x44, + USB_HID_MONITOR_VESA_VIRTUAL_CONTROLS_TOP_CORNER_DISTORTION_CONTROL = 0x46, + USB_HID_MONITOR_VESA_VIRTUAL_CONTROLS_TOP_CORNER_DISTORTION_BALANCE = 0x48, + USB_HID_MONITOR_VESA_VIRTUAL_CONTROLS_BOTTOM_CORNER_DISTORTION_CONTROL = 0x4A, + USB_HID_MONITOR_VESA_VIRTUAL_CONTROLS_BOTTOM_CORNER_DISTORTION_BALANCE = 0x4C, + USB_HID_MONITOR_VESA_VIRTUAL_CONTROLS_HORIZONTAL_MOIRE = 0x56, + USB_HID_MONITOR_VESA_VIRTUAL_CONTROLS_VERTICAL_MOIRE = 0x58, + USB_HID_MONITOR_VESA_VIRTUAL_CONTROLS_RED_VIDEO_BLACK_LEVEL = 0x6C, + USB_HID_MONITOR_VESA_VIRTUAL_CONTROLS_GREEN_VIDEO_BLACK_LEVEL = 0x6E, + USB_HID_MONITOR_VESA_VIRTUAL_CONTROLS_BLUE_VIDEO_BLACK_LEVEL = 0x70, + + /* Non-contiguous controls (read/write) */ + USB_HID_MONITOR_VESA_VIRTUAL_CONTROLS_INPUT_LEVEL_SELECT = 0x5E, + USB_HID_MONITOR_VESA_VIRTUAL_CONTROLS_INPUT_SOURCE_SELECT = 0x60, + USB_HID_MONITOR_VESA_VIRTUAL_CONTROLS_ON_SCREEN_DISPLAY = 0xCA, + USB_HID_MONITOR_VESA_VIRTUAL_CONTROLS_STEREOMODE = 0xD4, + + /* Non-contiguous controls (read-only) */ + USB_HID_MONITOR_VESA_VIRTUAL_CONTROLS_AUDO_SIZE_CENTER = 0xA2, + USB_HID_MONITOR_VESA_VIRTUAL_CONTROLS_POLARITY_HORIZONTAL_SYNCHRONIZATION = 0xA4, + USB_HID_MONITOR_VESA_VIRTUAL_CONTROLS_POLARITY_VERTICAL_SYNCHRONIZATION = 0xA6, + USB_HID_MONITOR_VESA_VIRTUAL_CONTROLS_SYNCHRONIZATION_TYPE = 0xA8, + USB_HID_MONITOR_VESA_VIRTUAL_CONTROLS_SCREEN_ORIENTATION = 0xAA, + USB_HID_MONITOR_VESA_VIRTUAL_CONTROLS_HORIZONTAL_FREQUENCY = 0xAC, + USB_HID_MONITOR_VESA_VIRTUAL_CONTROLS_VERTICAL_FREQUENCY = 0xAE, + + /* Non-contiguous controls (write-only) */ + USB_HID_MONITOR_VESA_VIRTUAL_CONTROLS_DEGAUSS = 0x01, + USB_HID_MONITOR_VESA_VIRTUAL_CONTROLS_SETTINGS = 0xB0 + +} USB_HID_MONITOR_VESA_VIRTUAL_CONTROLS; + + +typedef enum +{ + USB_HID_BAR_CODE_SCANNER_UNDEFINED = 0x00, + USB_HID_BAR_CODE_SCANNER_BAR_CODE_BADGE_READER = 0x01, + USB_HID_BAR_CODE_SCANNER_BAR_CODE_SCANNER = 0x02, + USB_HID_BAR_CODE_SCANNER_DUMB_BAR_CODE_SCANNER = 0x03, + USB_HID_BAR_CODE_SCANNER_CORDLESS_SCANNER_BASE = 0x04, + USB_HID_BAR_CODE_SCANNER_BAR_CODE_SCANNER_CRADLE = 0x05, + /* Reserved = 0x06-0x0F */ + USB_HID_BAR_CODE_SCANNER_ATTRIBUTE_REPORT = 0x10, + USB_HID_BAR_CODE_SCANNER_SETTINGS_REPORT = 0x11, + USB_HID_BAR_CODE_SCANNER_SCANNED_DATA_REPORT = 0x12, + USB_HID_BAR_CODE_SCANNER_RAW_SCANNED_DATA_REPORT = 0x13, + USB_HID_BAR_CODE_SCANNER_TRIGGER_REPORT = 0x14, + USB_HID_BAR_CODE_SCANNER_STATUS_REPORT = 0x15, + USB_HID_BAR_CODE_SCANNER_UPC_EAN_CONTROL_REPORT = 0x16, + USB_HID_BAR_CODE_SCANNER_EAN_2_3_LABEL_CONTROL_REPORT = 0x17, + USB_HID_BAR_CODE_SCANNER_CODE_39_CONTROL_REPORT = 0x18, + USB_HID_BAR_CODE_SCANNER_INTERLEAVED_2_OF_5_CONTROL_REPORT = 0x19, + USB_HID_BAR_CODE_SCANNER_STANDARD_2_OF_5_CONTROL_REPORT = 0x1A, + USB_HID_BAR_CODE_SCANNER_MSI_PLESSEY_CONTROL_REPORT = 0x1B, + USB_HID_BAR_CODE_SCANNER_CODABAR_CONTROL_REPORT = 0x1C, + USB_HID_BAR_CODE_SCANNER_CODE_128_CONTROL_REPORT = 0x1D, + USB_HID_BAR_CODE_SCANNER_MISC_1D_CONTROL_REPORT = 0x1E, + USB_HID_BAR_CODE_SCANNER_2D_CONTROL_REPORT = 0x1F, + /* Reserved = 0x20-0x2F */ + USB_HID_BAR_CODE_SCANNER_AIMING_POINTER_MODE = 0x30, + USB_HID_BAR_CODE_SCANNER_BAR_CODE_PRESENT_SENSOR = 0x31, + USB_HID_BAR_CODE_SCANNER_CLASS_1A_LASER = 0x32, + USB_HID_BAR_CODE_SCANNER_CLASS_2_LASER = 0x33, + USB_HID_BAR_CODE_SCANNER_HEATER_PRESENT = 0x34, + USB_HID_BAR_CODE_SCANNER_CONTACT_SCANNER = 0x35, + USB_HID_BAR_CODE_SCANNER_ELECTRONIC_ARTICLE_SURVEILLANCE_NOTIFICATION = 0x36, + USB_HID_BAR_CODE_SCANNER_CONSTANT_ELECTRONIC_ARTICLE_SURVEILLANCE = 0x37, + USB_HID_BAR_CODE_SCANNER_ERROR_INDICATION = 0x38, + USB_HID_BAR_CODE_SCANNER_FIXED_BEEPER = 0x39, + USB_HID_BAR_CODE_SCANNER_GOOD_DECODE_INDICATION = 0x3A, + USB_HID_BAR_CODE_SCANNER_HANDS_FREE_SCANNING = 0x3B, + USB_HID_BAR_CODE_SCANNER_INTRINSICALLY_SAFE = 0x3C, + USB_HID_BAR_CODE_SCANNER_KLASSE_EINS_LASER = 0x3D, + USB_HID_BAR_CODE_SCANNER_LONG_RANGE_SCANNER = 0x3E, + USB_HID_BAR_CODE_SCANNER_MIRROR_SPEED_CONTROL = 0x3F, + USB_HID_BAR_CODE_SCANNER_NOT_ON_FILE_INDICATION = 0x40, + USB_HID_BAR_CODE_SCANNER_PROGRAMMABLE_BEEPER = 0x41, + USB_HID_BAR_CODE_SCANNER_TRIGGERLESS = 0x42, + USB_HID_BAR_CODE_SCANNER_WAND = 0x43, + USB_HID_BAR_CODE_SCANNER_WATER_RESISTANT = 0x44, + USB_HID_BAR_CODE_SCANNER_MULTI_RANGE_SCANNER = 0x45, + USB_HID_BAR_CODE_SCANNER_PROXIMITY_SENSOR = 0x46, + /* Reserved = 0x47-0x4C */ + USB_HID_BAR_CODE_SCANNER_FRAGMENT_DECODING = 0x4D, + USB_HID_BAR_CODE_SCANNER_SCANNER_READ_CONFIDENCE = 0x4E, + USB_HID_BAR_CODE_SCANNER_DATA_PREFIX = 0x4F, + USB_HID_BAR_CODE_SCANNER_PREFIX_AIMI = 0x50, + USB_HID_BAR_CODE_SCANNER_PREFIX_NONE = 0x51, + USB_HID_BAR_CODE_SCANNER_PREFIX_PROPRIETARY = 0x52, + /* Reserved = 0x53-0x54 */ + USB_HID_BAR_CODE_SCANNER_ACTIVE_TIME = 0x55, + USB_HID_BAR_CODE_SCANNER_AIMING_LASER_PATTERN = 0x56, + USB_HID_BAR_CODE_SCANNER_BAR_CODE_PRESENT = 0x57, + USB_HID_BAR_CODE_SCANNER_BEEPER_STATE = 0x58, + USB_HID_BAR_CODE_SCANNER_LASER_ON_TIME = 0x59, + USB_HID_BAR_CODE_SCANNER_LASER_STATE = 0x5A, + USB_HID_BAR_CODE_SCANNER_LOCKOUT_TIME = 0x5B, + USB_HID_BAR_CODE_SCANNER_MOTOR_STATE = 0x5C, + USB_HID_BAR_CODE_SCANNER_MOTOR_TIMEOUT = 0x5D, + USB_HID_BAR_CODE_SCANNER_POWER_ON_RESET_SCANNER = 0x5E, + USB_HID_BAR_CODE_SCANNER_PREVENT_READ_OF_BARCODES = 0x5F, + USB_HID_BAR_CODE_SCANNER_INITIATE_BARCODE_READ = 0x60, + USB_HID_BAR_CODE_SCANNER_TRIGGER_STATE = 0x61, + USB_HID_BAR_CODE_SCANNER_TRIGGER_MODE = 0x62, + USB_HID_BAR_CODE_SCANNER_TRIGGER_MODE_BLINKING_LASER_ON = 0x63, + USB_HID_BAR_CODE_SCANNER_TRIGGER_MODE_CONTINUOUS_LASER_ON = 0x64, + USB_HID_BAR_CODE_SCANNER_TRIGGER_MODE_LASER_ON_WHILE_PULLED = 0x65, + USB_HID_BAR_CODE_SCANNER_TRIGGER_MODE_LASER_STAYS_ON_AFTER_TRIGGER_RELEASE = 0x66, + /* Reserved = 0x67-0x6C */ + USB_HID_BAR_CODE_SCANNER_COMMIT_PARAMETERS_TO_NVM = 0x6D, + USB_HID_BAR_CODE_SCANNER_PARAMETER_SCANNING = 0x6E, + USB_HID_BAR_CODE_SCANNER_PARAMETERS_CHANGED = 0x6F, + USB_HID_BAR_CODE_SCANNER_SET_PARAMETER_DEFAULT_VALUES = 0x70, + /* Reserved = 0x71-0x74 */ + USB_HID_BAR_CODE_SCANNER_SCANNER_IN_CRADLE = 0x75, + USB_HID_BAR_CODE_SCANNER_SCANNER_IN_RANGE = 0x76, + /* Reserved = 0x77-0x79 */ + USB_HID_BAR_CODE_SCANNER_AIM_DURATION = 0x7A, + USB_HID_BAR_CODE_SCANNER_GOOD_READ_LAMP_DURATION = 0x7B, + USB_HID_BAR_CODE_SCANNER_GOOD_READ_LAMP_INTENSITY = 0x7C, + USB_HID_BAR_CODE_SCANNER_GOOD_READ_LED = 0x7D, + USB_HID_BAR_CODE_SCANNER_GOOD_READ_TONE_FREQUENCY = 0x7E, + USB_HID_BAR_CODE_SCANNER_GOOD_READ_TONE_LENGTH = 0x7F, + USB_HID_BAR_CODE_SCANNER_GOOD_READ_TONE_VOLUME = 0x80, + /* Reserved = 0x81 */ + USB_HID_BAR_CODE_SCANNER_NO_READ_MESSAGE = 0x82, + USB_HID_BAR_CODE_SCANNER_NOT_ON_FILE_VOLUME = 0x83, + USB_HID_BAR_CODE_SCANNER_POWERUP_BEEP = 0x84, + USB_HID_BAR_CODE_SCANNER_SOUND_ERROR_BEEP = 0x85, + USB_HID_BAR_CODE_SCANNER_SOUND_GOOD_READ_BEEP = 0x86, + USB_HID_BAR_CODE_SCANNER_SOUND_NOT_ON_FILE_BEEP = 0x87, + USB_HID_BAR_CODE_SCANNER_GOOD_READ_WHEN_TO_WRITE = 0x88, + USB_HID_BAR_CODE_SCANNER_GRWTI_AFTER_DECODE = 0x89, + USB_HID_BAR_CODE_SCANNER_GRWTI_BEEP_LAMP_AFTER_TRANSMIT = 0x8A, + USB_HID_BAR_CODE_SCANNER_GRWTI_NO_BEEP_LAMP_USE_AT_ALL = 0x8B, + /* Reserved = 0x8C-0x90 */ + USB_HID_BAR_CODE_SCANNER_BOOKLAND_EAN = 0x91, + USB_HID_BAR_CODE_SCANNER_CONVERT_EAN_8_TO_13_TYPE = 0x92, + USB_HID_BAR_CODE_SCANNER_CONVERT_UPC_A_TO_EAN_13 = 0x93, + USB_HID_BAR_CODE_SCANNER_CONVERT_UPC_E_TO_A = 0x94, + USB_HID_BAR_CODE_SCANNER_EAN_13 = 0x95, + USB_HID_BAR_CODE_SCANNER_EAN_8 = 0x96, + USB_HID_BAR_CODE_SCANNER_EAN_99_128_MANDATORY = 0x97, + USB_HID_BAR_CODE_SCANNER_EAN_99_P5_128_OPTIONAL = 0x98, + /* Reserved = 0x99 */ + USB_HID_BAR_CODE_SCANNER_UPC_EAN = 0x9A, + USB_HID_BAR_CODE_SCANNER_UPC_EAN_COUPON_CODE = 0x9B, + USB_HID_BAR_CODE_SCANNER_UPC_EAN_PERIODICALS = 0x9C, + USB_HID_BAR_CODE_SCANNER_UPC_A = 0x9D, + USB_HID_BAR_CODE_SCANNER_UPC_A_WITH_128_MANDATORY = 0x9E, + USB_HID_BAR_CODE_SCANNER_UPC_A_WITH_128_OPTIONAL = 0x9F, + USB_HID_BAR_CODE_SCANNER_UPC_A_WITH_P5_OPTIONAL = 0xA0, + USB_HID_BAR_CODE_SCANNER_UPC_E = 0xA1, + USB_HID_BAR_CODE_SCANNER_UPC_E1 = 0xA2, + /* Reserved = 0xA2-0xA8 */ + USB_HID_BAR_CODE_SCANNER_PERIODICAL = 0xA9, + USB_HID_BAR_CODE_SCANNER_PERIODICAL_AUTO_DISCRIMINATE_PLUS_2 = 0xAA, + USB_HID_BAR_CODE_SCANNER_PERIODICAL_ONLY_DECODE_WITH_PLUS_2 = 0xAB, + USB_HID_BAR_CODE_SCANNER_PERIODICAL_IGNORE_PLUS_2 = 0xAC, + USB_HID_BAR_CODE_SCANNER_PERIODICAL_AUTO_DISCRIMINATE_PLUS_5 = 0xAD, + USB_HID_BAR_CODE_SCANNER_PERIODICAL_ONLY_DECODE_WITH_PLUS_5 = 0xAE, + USB_HID_BAR_CODE_SCANNER_PERIODICAL_IGNORE_PLUS_5 = 0xAF, + USB_HID_BAR_CODE_SCANNER_CHECK = 0xB0, + USB_HID_BAR_CODE_SCANNER_CHECK_DISABLE_PRICE = 0xB1, + USB_HID_BAR_CODE_SCANNER_CHECK_ENABLE_4_DIGIT_PRICE = 0xB2, + USB_HID_BAR_CODE_SCANNER_CHECK_ENABLE_5_DIGIT_PRICE = 0xB3, + USB_HID_BAR_CODE_SCANNER_CHECK_ENABLE_EUROPEAN_4_DIGIT_PRICE = 0xB4, + USB_HID_BAR_CODE_SCANNER_CHECK_ENABLE_EUROPEAN_5_DIGIT_PRICE = 0xB5, + /* Reserved = 0xB6 */ + USB_HID_BAR_CODE_SCANNER_EAN_TWO_LABEL = 0xB7, + USB_HID_BAR_CODE_SCANNER_EAN_THREE_LABEL = 0xB8, + USB_HID_BAR_CODE_SCANNER_EAN_8_FLAG_DIGIT_1 = 0xB9, + USB_HID_BAR_CODE_SCANNER_EAN_8_FLAG_DIGIT_2 = 0xBA, + USB_HID_BAR_CODE_SCANNER_EAN_8_FLAG_DIGIT_3 = 0xBB, + USB_HID_BAR_CODE_SCANNER_EAN_13_FLAG_DIGIT_1 = 0xBC, + USB_HID_BAR_CODE_SCANNER_EAN_13_FLAG_DIGIT_2 = 0xBD, + USB_HID_BAR_CODE_SCANNER_EAN_13_FLAG_DIGIT_3 = 0xBE, + USB_HID_BAR_CODE_SCANNER_ADD_EAN_2_3_LABEL_DEFINITION = 0xBF, + USB_HID_BAR_CODE_SCANNER_CLEAR_ALL_EAN_2_3_LABEL_DEFINITIONS = 0xC0, + /* Reserved = 0xC1-0xC2 */ + USB_HID_BAR_CODE_SCANNER_CODABAR = 0xC3, + USB_HID_BAR_CODE_SCANNER_CODE_128 = 0xC4, + /* Reserved = 0xC5-0xC6 */ + USB_HID_BAR_CODE_SCANNER_CODE_39 = 0xC7, + USB_HID_BAR_CODE_SCANNER_CODE_93 = 0xC8, + USB_HID_BAR_CODE_SCANNER_FULL_ASCII_CONVERSION = 0xC9, + USB_HID_BAR_CODE_SCANNER_INTERLEAVED_2_OF_5 = 0xCA, + USB_HID_BAR_CODE_SCANNER_ITALIAN_PHARMACY_CODE = 0xCB, + USB_HID_BAR_CODE_SCANNER_MSI_PLESSEY = 0xCC, + USB_HID_BAR_CODE_SCANNER_STANDARD_2_OF_5_IATA = 0xCD, + USB_HID_BAR_CODE_SCANNER_STANDARD_2_of_5 = 0xCE, + /* Reserved = 0xCF-0xD2 */ + USB_HID_BAR_CODE_SCANNER_TRANSMIT_START_STOP = 0xD3, + USB_HID_BAR_CODE_SCANNER_TRI_OPTIC = 0xD4, + USB_HID_BAR_CODE_SCANNER_UCC_EAN_128 = 0xD5, + USB_HID_BAR_CODE_SCANNER_CHECK_DIGIT = 0xD6, + USB_HID_BAR_CODE_SCANNER_CHECK_DIGIT_DISABLE = 0xD7, + USB_HID_BAR_CODE_SCANNER_CHECK_DIGIT_ENABLE_INTERLEAVED_2_OF_5_OPCC = 0xD8, + USB_HID_BAR_CODE_SCANNER_CHECK_DIGIT_ENABLE_INTERLEAVED_2_OF_5_USS = 0xD9, + USB_HID_BAR_CODE_SCANNER_CHECK_DIGIT_ENABLE_STANDARD_2_OF_5_OPCC = 0xDA, + USB_HID_BAR_CODE_SCANNER_CHECK_DIGIT_ENABLE_STANDARD_2_OF_5_USS = 0xDB, + USB_HID_BAR_CODE_SCANNER_CHECK_DIGIT_ENABLE_ONE_MSI_PLESSEY = 0xDC, + USB_HID_BAR_CODE_SCANNER_CHECK_DIGIT_ENABLE_TWO_MSI_PLESSEY = 0xDD, + USB_HID_BAR_CODE_SCANNER_CHECK_DIGIT_CODABAR_ENABLE = 0xDE, + USB_HID_BAR_CODE_SCANNER_CHECK_DIGIT_CODE_39_ENABLE = 0xDF, + /* Reserved = 0xE0-0xEF */ + USB_HID_BAR_CODE_SCANNER_TRANSMIT_CHECK_DIGIT = 0xF0, + USB_HID_BAR_CODE_SCANNER_DISABLE_CHECK_DIGIT_TRANSMIT = 0xF1, + USB_HID_BAR_CODE_SCANNER_ENABLE_CHECK_DIGIT_TRANSMIT = 0xF2, + /* Reserved = 0xF3-0xFA */ + USB_HID_BAR_CODE_SCANNER_SYMBOLOGY_IDENTIFIER_1 = 0xFB, + USB_HID_BAR_CODE_SCANNER_SYMBOLOGY_IDENTIFIER_2 = 0xFC, + USB_HID_BAR_CODE_SCANNER_SYMBOLOTY_IDNETIFIER_3 = 0xFD, + USB_HID_BAR_CODE_SCANNER_DECODED_DATA = 0xFE, + USB_HID_BAR_CODE_SCANNER_DECODE_DATA_CONTINUED = 0xFF, + USB_HID_BAR_CODE_SCANNER_BAR_SPACE_DATA = 0x100, + USB_HID_BAR_CODE_SCANNER_SCANNER_DATA_ACCURACY = 0x101, + USB_HID_BAR_CODE_SCANNER_RAW_DATA_POLARITY = 0x102, + USB_HID_BAR_CODE_SCANNER_POLARITY_INVERTED_BAR_CODE = 0x103, + USB_HID_BAR_CODE_SCANNER_POLARITY_NORMAL_BAR_CODE = 0x104, + /* Reserved = 0x105 */ + USB_HID_BAR_CODE_SCANNER_MINIMUM_LENGTH_TO_DECODE = 0x106, + USB_HID_BAR_CODE_SCANNER_MAXIMUM_LENGTH_TO_DECODE = 0x107, + USB_HID_BAR_CODE_SCANNER_FIRST_DISCRETE_LENGTH_TO_DECODE = 0x108, + USB_HID_BAR_CODE_SCANNER_SECOND_DISCRETE_LENGTH_TO_DECODE = 0x109, + USB_HID_BAR_CODE_SCANNER_DATA_LENGTH_METHOD = 0x10A, + USB_HID_BAR_CODE_SCANNER_DL_METHOD_READ_ANY = 0x10B, + USB_HID_BAR_CODE_SCANNER_DL_METHOD_CHECK_IN_RANGE = 0x10C, + USB_HID_BAR_CODE_SCANNER_DL_METHOD_CHECK_FOR_DISCRETE = 0x10D, + /* Reserved = 0x10E-0x10F */ + USB_HID_BAR_CODE_SCANNER_AZTEC_CODE = 0x110, + USB_HID_BAR_CODE_SCANNER_BC412 = 0x111, + USB_HID_BAR_CODE_SCANNER_CHANNEL_CODE = 0x112, + USB_HID_BAR_CODE_SCANNER_CODE_16 = 0x113, + USB_HID_BAR_CODE_SCANNER_CODE_32 = 0x114, + USB_HID_BAR_CODE_SCANNER_CODE_49 = 0x115, + USB_HID_BAR_CODE_SCANNER_CODE_ONE = 0x116, + USB_HID_BAR_CODE_SCANNER_COLORCODE = 0x117, + USB_HID_BAR_CODE_SCANNER_DATA_MATRIX = 0x118, + USB_HID_BAR_CODE_SCANNER_MAXICODE = 0x119, + USB_HID_BAR_CODE_SCANNER_MICROPDF = 0x11A, + USB_HID_BAR_CODE_SCANNER_PDF417 = 0x11B, + USB_HID_BAR_CODE_SCANNER_POSICODE = 0x11C, + USB_HID_BAR_CODE_SCANNER_QR_CODE = 0x11D, + USB_HID_BAR_CODE_SCANNER_SUPERCODE = 0x11E, + USB_HID_BAR_CODE_SCANNER_ULTRA_CODE = 0x11F, + USB_HID_BAR_CODE_SCANNER_USD5_SLUG_CODE = 0x120, + USB_HID_BAR_CODE_SCANNER_VERICODE = 0x121 + /* Reserved = 0x122-0xFFFF */ +} USB_HID_BAR_CODE_SCANNER; + +typedef enum +{ + USB_HID_WEIGHING_DEVICES_UNDEFINED = 0x00, + USB_HID_WEIGHING_DEVICES_WEIGHING_DEVICES = 0x01, + /* Reserved = 0x02-0x1F */ + USB_HID_WEIGHING_DEVICES_SCALE_DEVICE = 0x20, + USB_HID_WEIGHING_DEVICES_SCALE_CLASS_I_METRIC = 0x21, + USB_HID_WEIGHING_DEVICES_SCALE_CLASS_I_METRIC_SEL = 0x22, + USB_HID_WEIGHING_DEVICES_SCALE_CLASS_II_METRIC = 0x23, + USB_HID_WEIGHING_DEVICES_SCALE_CLASS_III_METRIC = 0x24, + USB_HID_WEIGHING_DEVICES_SCALE_CLASS_IIIL_METRIC = 0x25, + USB_HID_WEIGHING_DEVICES_SCALE_CLASS_IV_METRIC = 0x26, + USB_HID_WEIGHING_DEVICES_SCALE_CLASS_III_ENGLISH = 0x27, + USB_HID_WEIGHING_DEVICES_SCALE_CLASS_IIIL_ENGLISH = 0x28, + USB_HID_WEIGHING_DEVICES_SCALE_CLASS_IV_ENGLISH = 0x29, + USB_HID_WEIGHING_DEVICES_SCALE_CLASS_GENERIC = 0x2A, + /* Reserved = 0x2B-0x2F */ + USB_HID_WEIGHING_DEVICES_SCALE_ATTRIBUTE_REPORT = 0x30, + USB_HID_WEIGHING_DEVICES_SCALE_CONTROL_REPORT = 0x31, + USB_HID_WEIGHING_DEVICES_SCALE_DATA_REPORT = 0x32, + USB_HID_WEIGHING_DEVICES_SCALE_STATUS_REPORT = 0x33, + USB_HID_WEIGHING_DEVICES_SCALE_WEIGHT_LIMIT_REPORT = 0x34, + USB_HID_WEIGHING_DEVICES_SCALE_STATISTICS_REPORT = 0x35, + /* Reserved = 0x36-0x3F */ + USB_HID_WEIGHING_DEVICES_DATA_WEIGHT = 0x40, + USB_HID_WEIGHING_DEVICES_DATA_SCALING = 0x41, + /* Reserved = 0x42-0x4F */ + USB_HID_WEIGHING_DEVICES_WEIGHT_UNIT = 0x50, + USB_HID_WEIGHING_DEVICES_WEIGHT_UNIT_MILLIGRAM = 0x51, + USB_HID_WEIGHING_DEVICES_WEIGHT_UNIT_GRAM = 0x52, + USB_HID_WEIGHING_DEVICES_WEIGHT_UNIT_KILOGRAM = 0x53, + USB_HID_WEIGHING_DEVICES_WEIGHT_UNIT_CARATS = 0x54, + USB_HID_WEIGHING_DEVICES_WEIGHT_UNIT_TAELS = 0x55, + USB_HID_WEIGHING_DEVICES_WEIGHT_UNIT_GRAINS = 0x56, + USB_HID_WEIGHING_DEVICES_WEIGHT_UNIT_PENNYWEIGHTS = 0x57, + USB_HID_WEIGHING_DEVICES_WEIGHT_UNIT_METRIC_TON = 0x58, + USB_HID_WEIGHING_DEVICES_WEIGHT_UNIT_AVOIR_TON = 0x59, + USB_HID_WEIGHING_DEVICES_WEIGHT_UNIT_TROY_OUNCE = 0x5A, + USB_HID_WEIGHING_DEVICES_WEIGHT_UNIT_OUNCE = 0x5B, + USB_HID_WEIGHING_DEVICES_WEIGHT_UNIT_POUND = 0x5C, + /* Reserved = 0x5D-0x5F */ + USB_HID_WEIGHING_DEVICES_CALIBRATION_COUNT = 0x60, + USB_HID_WEIGHING_DEVICES_REZERO_COUNT = 0x61, + /* Reserved = 0x62-0x6F */ + USB_HID_WEIGHING_DEVICES_SCALE_STATUS = 0x70, + USB_HID_WEIGHING_DEVICES_SCALE_STATUS_FAULT = 0x71, + USB_HID_WEIGHING_DEVICES_SCALE_STATUS_STABLE_AT_CENTER_OF_ZERO = 0x72, + USB_HID_WEIGHING_DEVICES_SCALE_STATUS_IN_MOTION = 0x73, + USB_HID_WEIGHING_DEVICES_SCALE_STATUS_WEIGHT_STABLE = 0x74, + USB_HID_WEIGHING_DEVICES_SCALE_STATUS_UNDER_ZERO = 0x75, + USB_HID_WEIGHING_DEVICES_SCALE_STATUS_OVER_WEIGHT_LIMIT = 0x76, + USB_HID_WEIGHING_DEVICES_SCALE_STATUS_REQUIRES_CALIBRATION = 0x77, + USB_HID_WEIGHING_DEVICES_SCALE_STATUS_REQUIRES_REZEROING = 0x78, + /* Reserved = 0x79-0x7F */ + USB_HID_WEIGHING_DEVICES_ZERO_SCALE = 0x80, + USB_HID_WEIGHING_DEVICES_ENFORCED_ZERO_RETURN = 0x81 + /* Reserved = 0x82-0xFFFF */ +} USB_HID_WEIGHING_DEVICES; + +typedef enum +{ + USB_HID_MAGNETIC_STRIPE_READING_DEVICES_UNDEFINED = 0x00, + USB_HID_MAGNETIC_STRIPE_READING_DEVICES_MSR_DEVICE_READ_ONLY = 0x01, + /* Reserved = 0x02-0x10 */ + USB_HID_MAGNETIC_STRIPE_READING_DEVICES_TRACK_1_LENGTH = 0x11, + USB_HID_MAGNETIC_STRIPE_READING_DEVICES_TRACK_2_LENGTH = 0x12, + USB_HID_MAGNETIC_STRIPE_READING_DEVICES_TRACK_3_LENGTH = 0x13, + USB_HID_MAGNETIC_STRIPE_READING_DEVICES_TRACK_JIS_LENGTH = 0x14, + /* Reserved = 0x15-0x1F */ + USB_HID_MAGNETIC_STRIPE_READING_DEVICES_TRACK_DATA = 0x20, + USB_HID_MAGNETIC_STRIPE_READING_DEVICES_TRACK_1_DATA = 0x21, + USB_HID_MAGNETIC_STRIPE_READING_DEVICES_TRACK_2_DATA = 0x22, + USB_HID_MAGNETIC_STRIPE_READING_DEVICES_TRACK_3_DATA = 0x23, + USB_HID_MAGNETIC_STRIPE_READING_DEVICES_TRACK_JIS_DATA = 0x24 + /* Reserved = 0x25-0xFFFF */ +} USB_HID_MAGNETIC_STRIPE_READING_DEVICES; + +typedef enum +{ + USB_HID_POWER_DEVICE_UNDEFINED = 0x00, + USB_HID_POWER_DEVICE_INAME = 0x01, + USB_HID_POWER_DEVICE_PRESENT_STATUS = 0x02, + USB_HID_POWER_DEVICE_CHANGED_STATUS = 0x03, + USB_HID_POWER_DEVICE_UPS = 0x04, + USB_HID_POWER_DEVICE_POWER_SUPPLY = 0x05, + /* Reserved = 0x06-0x0F */ + USB_HID_POWER_DEVICE_BATTERY_SYSTEM = 0x10, + USB_HID_POWER_DEVICE_BATTERY_SYSTEM_ID = 0x11, + USB_HID_POWER_DEVICE_BATTERY = 0x12, + USB_HID_POWER_DEVICE_BATTERY_ID = 0x13, + USB_HID_POWER_DEVICE_CHARGER = 0x14, + USB_HID_POWER_DEVICE_CHARGER_ID = 0x15, + USB_HID_POWER_DEVICE_POWER_CONVERTER = 0x16, + USB_HID_POWER_DEVICE_POWER_CONVERTER_ID = 0x17, + USB_HID_POWER_DEVICE_OUTLET_SYSTEM = 0x18, + USB_HID_POWER_DEVICE_OUTLET_SYSTEM_ID = 0x19, + USB_HID_POWER_DEVICE_INPUT = 0x1A, + USB_HID_POWER_DEVICE_INPUT_ID = 0x1B, + USB_HID_POWER_DEVICE_OUTPUT = 0x1C, + USB_HID_POWER_DEVICE_OUTPUT_ID = 0x1D, + USB_HID_POWER_DEVICE_FLOW = 0x1E, + USB_HID_POWER_DEVICE_FLOW_ID = 0x1F, + USB_HID_POWER_DEVICE_OUTLET = 0x20, + USB_HID_POWER_DEVICE_OUTLET_ID = 0x21, + USB_HID_POWER_DEVICE_GANG = 0x22, + USB_HID_POWER_DEVICE_GANG_ID = 0x23, + USB_HID_POWER_DEVICE_POWER_SUMMARY = 0x24, + USB_HID_POWER_DEVICE_POWER_SUMMARY_ID = 0x25, + /* Reserved = 0x26-0x2F */ + USB_HID_POWER_DEVICE_VOLTAGE = 0x30, + USB_HID_POWER_DEVICE_CURRENT = 0x31, + USB_HID_POWER_DEVICE_FREQUENCY = 0x32, + USB_HID_POWER_DEVICE_APPARENT_POWER = 0x33, + USB_HID_POWER_DEVICE_ACTIVE_POWER = 0x34, + USB_HID_POWER_DEVICE_PERCENT_LOAD = 0x35, + USB_HID_POWER_DEVICE_TEMPERATURE = 0x36, + USB_HID_POWER_DEVICE_HUMIDITY = 0x37, + USB_HID_POWER_DEVICE_BAD_COUNT = 0x38, + /* Reserved = 0x39-0x3F */ + USB_HID_POWER_DEVICE_CONFIG_VOLTAGE = 0x40, + USB_HID_POWER_DEVICE_CONFIG_CURRENT = 0x41, + USB_HID_POWER_DEVICE_CONFIG_FREQUENCY = 0x42, + USB_HID_POWER_DEVICE_CONFIG_APPARENT_POWER = 0x43, + USB_HID_POWER_DEVICE_CONFIG_ACTIVE_POWER = 0x44, + USB_HID_POWER_DEVICE_CONFIG_PERCENT_LOAD = 0x45, + USB_HID_POWER_DEVICE_CONFIG_TEMPERATURE = 0x46, + USB_HID_POWER_DEVICE_CONFIG_HUMIDITY = 0x47, + /* Reserved = 0x48-0x4F */ + USB_HID_POWER_DEVICE_SWITCH_ON_CONTROL = 0x50, + USB_HID_POWER_DEVICE_SWITCH_OFF_CONTROL = 0x51, + USB_HID_POWER_DEVICE_TOGGLE_CONTROL = 0x52, + USB_HID_POWER_DEVICE_LOW_VOLTAGE_TRANSFER = 0x53, + USB_HID_POWER_DEVICE_HIGH_VOLTAGE_TRANSFER = 0x54, + USB_HID_POWER_DEVICE_DELAY_BEFORE_REBOOT = 0x55, + USB_HID_POWER_DEVICE_DELAY_BEFORE_STARTUP = 0x56, + USB_HID_POWER_DEVICE_DELAY_BEFORE_SHUTDOWN = 0x57, + USB_HID_POWER_DEVICE_TEST = 0x58, + USB_HID_POWER_DEVICE_MODULE_RESET = 0x59, + USB_HID_POWER_DEVICE_AUDIBLE_ALARM_CONTROL = 0x5A, + /* Reserved = 0x5B-0x5F */ + USB_HID_POWER_DEVICE_PRESENT = 0x60, + USB_HID_POWER_DEVICE_GOOD = 0x61, + USB_HID_POWER_DEVICE_INTERNAL_FAILURE = 0x62, + USB_HID_POWER_DEVICE_VOLTAGE_OUT_OF_RANGE = 0x63, + USB_HID_POWER_DEVICE_FREQUENCY_OUT_OF_RANGE = 0x64, + USB_HID_POWER_DEVICE_OVERLOAD = 0x65, + USB_HID_POWER_DEVICE_OVER_CHARGED = 0x66, + USB_HID_POWER_DEVICE_OVER_TEMPERATURE = 0x67, + USB_HID_POWER_DEVICE_SHUTDOWN_REQUESTED = 0x68, + USB_HID_POWER_DEVICE_SHUTDOWN_IMMINENT = 0x69, + /* Reserved = 0x6A */ + USB_HID_POWER_DEVICE_SWITCH_ON_OFF = 0x6B, + USB_HID_POWER_DEVICE_SWITCHABLE = 0x6C, + USB_HID_POWER_DEVICE_USED = 0x6D, + USB_HID_POWER_DEVICE_BOOST = 0x6E, + USB_HID_POWER_DEVICE_BUCK = 0x6F, + USB_HID_POWER_DEVICE_INITIALIZED = 0x70, + USB_HID_POWER_DEVICE_TESTED = 0x71, + USB_HID_POWER_DEVICE_AWAITING_POWER = 0x72, + USB_HID_POWER_DEVICE_COMMUNICATION_LOST = 0x73, + /* Reserved = 0x74-0xFC */ + USB_HID_POWER_DEVICE_IMANUFACTURER = 0xFD, + USB_HID_POWER_DEVICE_IPRODUCT = 0xFE, + USB_HID_POWER_DEVICE_ISERIAL_NUMBER = 0xFF +} USB_HID_POWER_DEVICE; + +typedef enum +{ + USB_HID_BATTERY_SYSTEM_UNDEFINED = 0x00, + USB_HID_BATTERY_SYSTEM_SMB_BATTERY_MODE = 0x01, + USB_HID_BATTERY_SYSTEM_SMB_BATTERY_STATUS = 0x02, + USB_HID_BATTERY_SYSTEM_SMB_ALARM_WARNING = 0x03, + USB_HID_BATTERY_SYSTEM_SMB_CHARGER_MODE = 0x04, + USB_HID_BATTERY_SYSTEM_SMB_CHARGER_STATUS = 0x05, + USB_HID_BATTERY_SYSTEM_SMB_CHARGER_SPEC_INFO = 0x06, + USB_HID_BATTERY_SYSTEM_SMB_SELECTOR_STATE = 0x07, + USB_HID_BATTERY_SYSTEM_SMB_SELECTOR_PRESETS = 0x08, + USB_HID_BATTERY_SYSTEM_SMB_SELECTOR_INFO = 0x09, + /* Reserved = 0x0A-0x0F */ + USB_HID_BATTERY_SYSTEM_OPTIONAL_MFG_FUNCTION_1 = 0x10, + USB_HID_BATTERY_SYSTEM_OPTIONAL_MFG_FUNCTION_2 = 0x11, + USB_HID_BATTERY_SYSTEM_OPTIONAL_MFG_FUNCTION_3 = 0x12, + USB_HID_BATTERY_SYSTEM_OPTIONAL_MFG_FUNCTION_4 = 0x13, + USB_HID_BATTERY_SYSTEM_OPTIONAL_MFG_FUNCTION_5 = 0x14, + USB_HID_BATTERY_SYSTEM_CONNECTION_TO_SMBUS = 0x15, + USB_HID_BATTERY_SYSTEM_OUTPUT_CONNECTION = 0x16, + USB_HID_BATTERY_SYSTEM_CHARGER_CONNECTION = 0x17, + USB_HID_BATTERY_SYSTEM_BATTERY_INSERTION = 0x18, + USB_HID_BATTERY_SYSTEM_USENEXT = 0x19, + USB_HID_BATTERY_SYSTEM_OK_TO_USE = 0x1A, + USB_HID_BATTERY_SYSTEM_BATTERY_SUPPORTED = 0x1B, + USB_HID_BATTERY_SYSTEM_SELECTOR_REVISION = 0x1C, + USB_HID_BATTERY_SYSTEM_CHARGING_INDICATOR = 0x1D, + /* Reserved = 0x1E-0x27 */ + USB_HID_BATTERY_SYSTEM_MANUFACTURER_ACCESS = 0x28, + USB_HID_BATTERY_SYSTEM_REMAINING_CAPACITY_LIMIT = 0x29, + USB_HID_BATTERY_SYSTEM_REMAINING_TIME_LIMIT = 0x2A, + USB_HID_BATTERY_SYSTEM_AT_RATE = 0x2B, + USB_HID_BATTERY_SYSTEM_CAPACITY_MODE = 0x2C, + USB_HID_BATTERY_SYSTEM_BROADCAST_TO_CHARGER = 0x2D, + USB_HID_BATTERY_SYSTEM_PRIMARY_BATTERY = 0x2E, + USB_HID_BATTERY_SYSTEM_CHARGE_CONTROLLER = 0x2F, + /* Reserved = 0x30-0x3F */ + USB_HID_BATTERY_SYSTEM_TERMINATE_CHARGE = 0x40, + USB_HID_BATTERY_SYSTEM_TERMINATE_DISCHARGE = 0x41, + USB_HID_BATTERY_SYSTEM_BELOW_REMAINING_CAPACITY_LIMIT = 0x42, + USB_HID_BATTERY_SYSTEM_REMAINING_TIME_LIMIT_EXPIRED = 0x43, + USB_HID_BATTERY_SYSTEM_CHARGING = 0x44, + USB_HID_BATTERY_SYSTEM_DISCHARGING = 0x45, + USB_HID_BATTERY_SYSTEM_FULLY_CHARGED = 0x46, + USB_HID_BATTERY_SYSTEM_FULLY_DISCHARGED = 0x47, + USB_HID_BATTERY_SYSTEM_CONDITIONING_FLAG = 0x48, + USB_HID_BATTERY_SYSTEM_AT_RATE_OK = 0x49, + USB_HID_BATTERY_SYSTEM_SMB_ERROR_CODE = 0x4A, + USB_HID_BATTERY_SYSTEM_NEED_REPLACEMENT = 0x4B, + /* Reserved = 0x4C-0x5F */ + USB_HID_BATTERY_SYSTEM_AT_RATE_TIME_TO_FULL = 0x60, + USB_HID_BATTERY_SYSTEM_AT_RATE_TIME_TO_EMPTY = 0x61, + USB_HID_BATTERY_SYSTEM_AVERAGE_CURRENT = 0x62, + USB_HID_BATTERY_SYSTEM_MAXERROR = 0x63, + USB_HID_BATTERY_SYSTEM_RELATIVE_STATE_OF_CHARGE = 0x64, + USB_HID_BATTERY_SYSTEM_ABSOLUTE_STATE_OF_CHARGE = 0x65, + USB_HID_BATTERY_SYSTEM_REMAINING_CAPACITY = 0x66, + USB_HID_BATTERY_SYSTEM_FULL_CHARGE_CAPACITY = 0x67, + USB_HID_BATTERY_SYSTEM_RUN_TIME_TO_EMPTY = 0x68, + USB_HID_BATTERY_SYSTEM_AVERAGE_TIME_TO_EMPTY = 0x69, + USB_HID_BATTERY_SYSTEM_AVERAGE_TIME_TO_FULL = 0x6A, + USB_HID_BATTERY_SYSTEM_CYCLE_COUNT = 0x6B, + /* Reserved = 0x6C-0x7F */ + USB_HID_BATTERY_SYSTEM_BATT_PACK_MODEL_LEVEL = 0x80, + USB_HID_BATTERY_SYSTEM_INTERNAL_CHARGE_CONTROLLER = 0x81, + USB_HID_BATTERY_SYSTEM_PRIMARY_BATTERY_SUPPORT = 0x82, + USB_HID_BATTERY_SYSTEM_DESIGN_CAPACITY = 0x83, + USB_HID_BATTERY_SYSTEM_SPECIFICATION_INFO = 0x84, + USB_HID_BATTERY_SYSTEM_MANUFACTURER_DATE = 0x85, + USB_HID_BATTERY_SYSTEM_SERIAL_NUMBER = 0x86, + USB_HID_BATTERY_SYSTEM_IMANUFACTURER_NAME = 0x87, + USB_HID_BATTERY_SYSTEM_IDEVICE_NAME = 0x88, + USB_HID_BATTERY_SYSTEM_IDEVICE_CHEMISTERY = 0x89, + USB_HID_BATTERY_SYSTEM_MANUFACTURER_DATA = 0x8A, + USB_HID_BATTERY_SYSTEM_RECHARGABLE = 0x8B, + USB_HID_BATTERY_SYSTEM_WARNING_CAPACITY_LIMIT = 0x8C, + USB_HID_BATTERY_SYSTEM_CAPACITY_GRANULARITY_1 = 0x8D, + USB_HID_BATTERY_SYSTEM_CAPACITY_GRANULARITY_2 = 0x8E, + USB_HID_BATTERY_SYSTEM_IOEM_INFORMATION = 0x8F, + /* Reserved = 0x90-0xBF */ + USB_HID_BATTERY_SYSTEM_INHIBIT_CHARGE = 0xC0, + USB_HID_BATTERY_SYSTEM_ENABLE_POLLING = 0xC1, + USB_HID_BATTERY_SYSTEM_RESET_TO_ZERO = 0xC2, + /* Reserved = 0xC3-0xCF */ + USB_HID_BATTERY_SYSTEM_AC_PRESENT = 0xD0, + USB_HID_BATTERY_SYSTEM_BATTERY_PRESENT = 0xD1, + USB_HID_BATTERY_SYSTEM_POWER_FAIL = 0xD2, + USB_HID_BATTERY_SYSTEM_ALARM_INHIBITED = 0xD3, + USB_HID_BATTERY_SYSTEM_THERMISTOR_UNDER_RANGE = 0xD4, + USB_HID_BATTERY_SYSTEM_THERMISTOR_HOT = 0xD5, + USB_HID_BATTERY_SYSTEM_THERMISTOR_COLD = 0xD6, + USB_HID_BATTERY_SYSTEM_THERMISTOR_OVER_RANGE = 0xD7, + USB_HID_BATTERY_SYSTEM_VOLTAGE_OUT_OF_RANGE = 0xD8, + USB_HID_BATTERY_SYSTEM_CURRENT_OUT_OF_RANGE = 0xD9, + USB_HID_BATTERY_SYSTEM_CURRENT_NOT_REGULATED = 0xDA, + USB_HID_BATTERY_SYSTEM_VOLTAGE_NOT_REGULATED = 0xDB, + USB_HID_BATTERY_SYSTEM_MASTER_MODE = 0xDC, + /* Reserved = 0xDD-0xEF */ + USB_HID_BATTERY_SYSTEM_CHARGER_SELECTOR_SUPPORT = 0xF0, + USB_HID_BATTERY_SYSTEM_CHARGER_SPEC = 0xF1, + USB_HID_BATTERY_SYSTEM_LEVEL_2 = 0xF2, + USB_HID_BATTERY_SYSTEM_LEVEL_3 = 0xF3 + /* Reserved = 0xF2-0xFF */ +} USB_HID_BATTERY_SYSTEM; + +#endif diff --git a/usb/inc/usb_pic18_local.h b/usb/inc/usb_pic18_local.h new file mode 100644 index 0000000..b20b051 --- /dev/null +++ b/usb/inc/usb_pic18_local.h @@ -0,0 +1,236 @@ +// 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 +#include + +// To Do: Put all PIC18-specific USB HW definitions here, + +#define KVA_TO_PA(v) v +#define PA_TO_KVA0(pa) pa +#define PA_TO_KVA1(pa) pa +#define GET_PHYSICAL_ADDRESS(v) (v) + + +/* translate betwwen KSEG0 and KSEG1 virtual addresses */ +#define KVA0_TO_KVA1(v) ((v) | 0x20000000) +#define KVA1_TO_KVA0(v) ((v) & ~0x20000000) + + +/******************************************************************** + * USB - PIC Endpoint Definitions + * PIC Endpoint Address Format: X:EP3:EP2:EP1:EP0:DIR:PPBI:X + * This is used when checking the value read from USTAT + * + * NOTE: These definitions are not used in the descriptors. + * EP addresses used in the descriptors have different format. + *******************************************************************/ +#define USTAT_EP0_PP_MASK ~0x02 +#define USTAT_EP_MASK 0x7E +#define USTAT_EP0_OUT 0x00 +#define USTAT_EP0_OUT_EVEN 0x00 +#define USTAT_EP0_OUT_ODD 0x02 + +#define USTAT_EP0_IN 0x04 +#define USTAT_EP0_IN_EVEN 0x04 +#define USTAT_EP0_IN_ODD 0x06 + + +//****************************************************************************** +// USB Endpoint Control Registers +// +// In USB Host mode, only EP0 control registers are used. The other registers +// should be disabled. +//****************************************************************************** +typedef union +{ + uint8_t UEP[16]; +} _UEP; + +#define UEP_STALL 0x0002 + + +/******************************************************************** + * Buffer Descriptor Status Register + *******************************************************************/ + +/* Buffer Descriptor Status Register Initialization Parameters */ +#define _BSTALL 0x04 //Buffer Stall enable +#define _DTSEN 0x08 //Data Toggle Synch enable +#define _INCDIS 0x10 //Address increment disable +#define _KEN 0x20 //SIE keeps buff descriptors enable +#define _DAT0 0x00 //DATA0 packet expected next +#define _DAT1 0x40 //DATA1 packet expected next +#define _DTSMASK 0x40 //DTS Mask +#define _USIE 0x80 //SIE owns buffer +#define _UCPU 0x00 //CPU owns buffer + +#define _STAT_MASK 0xFF + +/* BDT entry structure definition */ +typedef union _BD_STAT +{ + uint8_t Val; + struct{ + //If the CPU owns the buffer then these are the values + unsigned BC8:1; //bit 8 of the byte count + unsigned BC9:1; //bit 9 of the byte count + unsigned BSTALL:1; //Buffer Stall Enable + unsigned DTSEN:1; //Data Toggle Synch Enable + unsigned INCDIS:1; //Address Increment Disable + unsigned KEN:1; //BD Keep Enable + unsigned DTS:1; //Data Toggle Synch Value + unsigned UOWN:1; //USB Ownership + }; + struct{ + //if the USB module owns the buffer then these are + // the values + unsigned BC8:1; //bit 8 of the byte count + unsigned BC9:1; //bit 9 of the byte count + unsigned PID0:1; //Packet Identifier + unsigned PID1:1; + unsigned PID2:1; + unsigned PID3:1; + unsigned :1; + unsigned UOWN:1; //USB Ownership + }; + struct{ + unsigned :2; + unsigned PID:4; //Packet Identifier + unsigned :2; + }; +} BD_STAT; //Buffer Descriptor Status Register + + +/******************************************************************** + * Buffer Descriptor Table Mapping + *******************************************************************/ + +// BDT Entry Layout +typedef union __BDT +{ + struct + { + BD_STAT STAT; + uint8_t CNT; + uint8_t ADRL; //Buffer Address Low + uint8_t ADRH; //Buffer Address High + }; + struct + { + unsigned :8; + unsigned :8; + uint8_t* ADR; //Buffer Address + }; + uint32_t Val; + uint8_t v[4]; +} BDT_ENTRY; + + +/**************************************************************** + Function: + void USBPowerModule(void) + + Description: + This macro is used to power up the USB module if required
+ PIC18: defines as nothing
+ PIC24: defines as U1PWRCbits.USBPWR = 1;
+ + Precondition: + None + + Parameters: + None + + Return Values: + None + + Remarks: + None + + ****************************************************************/ +#define USBPowerModule() + +/**************************************************************** + Function: + USBSetBDTAddress(addr) + + Description: + This macro is used to power up the USB module if required + + Precondition: + None + + Parameters: + None + + Return Values: + None + + Remarks: + None + + ****************************************************************/ +#define USBSetBDTAddress(addr) +#define USBPingPongBufferReset UCONbits.PPBRST + +#define USBTransactionCompleteIE UIEbits.TRNIE +#define USBTransactionCompleteIF UIRbits.TRNIF +#define USBTransactionCompleteIFReg (uint8_t*)&UIR +#define USBTransactionCompleteIFBitNum 3 + +#define USBResetIE UIEbits.URSTIE +#define USBResetIF UIRbits.URSTIF +#define USBResetIFReg (uint8_t*)&UIR +#define USBResetIFBitNum 0 + +#define USBIdleIE UIEbits.IDLEIE +#define USBIdleIF UIRbits.IDLEIF +#define USBIdleIFReg (uint8_t*)&UIR +#define USBIdleIFBitNum 4 + +#define USBActivityIE UIEbits.ACTVIE +#define USBActivityIF UIRbits.ACTVIF +#define USBActivityIFReg (uint8_t*)&UIR +#define USBActivityIFBitNum 2 + +#define USBSOFIE UIEbits.SOFIE +#define USBSOFIF UIRbits.SOFIF +#define USBSOFIFReg (uint8_t*)&UIR +#define USBSOFIFBitNum 6 + +#define USBStallIE UIEbits.STALLIE +#define USBStallIF UIRbits.STALLIF +#define USBStallIFReg (uint8_t*)&UIR +#define USBStallIFBitNum 5 + +#define USBErrorIE UIEbits.UERRIE +#define USBErrorIF UIRbits.UERRIF +#define USBErrorIFReg (uint8_t*)&UIR +#define USBErrorIFBitNum 1 + +#define USBSE0Event UCONbits.SE0 +#define USBSuspendControl UCONbits.SUSPND +#define USBPacketDisable UCONbits.PKTDIS +#define USBResumeControl UCONbits.RESUME + + + diff --git a/usb/inc/usb_struct_queue.h b/usb/inc/usb_struct_queue.h new file mode 100644 index 0000000..70ba08f --- /dev/null +++ b/usb/inc/usb_struct_queue.h @@ -0,0 +1,307 @@ +// 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 + +#ifndef STRUCT_QUEUE_H +#define STRUCT_QUEUE_H + + +/* StructQueueInit + ************************************************************************* + * Precondition: None + * + * Input: q Pointer to the queue data structure + * + * N Number of elements in the queue data buffer array + * + * Output: None + * + * Returns: zero (0) + * + * Side Effects: The queue structure has been initialized and is ready + * to use. + * + * Overview: This operation initializes a queue and makes it empty. + * + * Note: This operation is implemented with a macro that + * supports queues of any type of data items. + *************************************************************************/ + +#define StructQueueInit(q,N) ( (q)->head = (N), \ + (q)->tail = (N), \ + (q)->count = 0 ) + + +/* StructQueueAdd + ************************************************************************* + * Precondition: The queue must have been initialized and must not + * currently be full. + * + * Input: q Pointer to the queue data structure + * + * N Number of elements in the queue data buffer array + * + * Output: None + * + * Returns: The address of the new item in the queue. + * + * Side Effects: The item has been added to the queue. + * + * IMPORTANT! No data has been copied to the item. + * + * Overview: This operation adds (enqueues) a new item into the + * queue data buffer and updates the head index, + * handling buffer wrap correctly. + * + * Notes: The caller must first ensure that the queue is not + * full by performing one of the other operations (such + * as "StructQueueIsNotFull") before performing this + * operation. Adding an item into a full queue will + * cause an access violation. + * + * This operation is implemented with a macro that + * supports queues of any type of data items. + *************************************************************************/ + +#define StructQueueAdd(q,N) ( (q)->count++, \ + ( ((q)->head < (N-1)) ? \ + ((q)->head++) : \ + ((q)->head=0) ), \ + &(q)->buffer[(q)->head] ) + + +/* StructQueueRemove + ************************************************************************* + * Precondition: The queue must have been initialized and not currently + * be empty. + * + * Input: q Pointer to the queue data structure + * + * N Number of elements in the queue data buffer array + * + * Output: None + * + * Returns: The item removed. + * + * Side Effects: The item has been removed from the queue. + * + * IMPORTANT! No data has been copied from the item. + * + * Overview: This routine removes (dequeues) an item from the + * queue data buffer and updates the tail index, + * handling buffer wrap correctly. + * + * Notes: The caller must first ensure that the queue is not + * empty by calling one or more of the other operations + * (such as "StructQueueIsNotEmpty") before performing this + * operation. Dequeueing an item from an empty queue + * will cause an access violation. + * + * This operation is implemented with a macro that + * supports queues of any type of data items. + *************************************************************************/ + +#define StructQueueRemove(q,N) ( (q)->count--, \ + ( ((q)->tail < (N-1)) ? \ + ((q)->tail++) : \ + ((q)->tail=0) ), \ + &(q)->buffer[(q)->tail] ) + + +/* StructQueuePeekTail + ************************************************************************* + * Precondition: The queue must have been initialized and not currently + * be empty. + * + * Input: q Pointer to the queue data structure + * + * N Number of elements in the queue data buffer array + * + * Output: None + * + * Returns: The item at the tail of the queue. + * + * Side Effects: None + * + * IMPORTANT! No data has been copied from the item. + * + * Overview: This routine provides access to an item in the + * queue data buffer at the tail index position, + * handling buffer wrap correctly. + * + * Notes: The caller must first ensure that the queue is not + * empty by calling one or more of the other operations + * (such as "StructQueueIsNotEmpty") before performing this + * operation. + * + * This operation is implemented with a macro that + * supports queues of any type of data items. + *************************************************************************/ + +#define StructQueuePeekTail(q,N) ( ((q)->tail < (N-1)) ? \ + &(q)->buffer[(q)->tail+1] : \ + &(q)->buffer[0] ) + + +/* StructQueueIsFull + ************************************************************************* + * Precondition: The queue must be initialized. + * + * Input: q Pointer to the queue data structure + * + * N Number of elements in the queue data buffer array + * + * Output: None + * + * Returns: TRUE if the queue is full, FALSE otherwise. + * + * Side Effects: None + * + * Overview: This routine checks to see if the queue is full. + * + * Note: This operation is implemented with a macro that + * supports queues of any type of data items. + *************************************************************************/ + +#define StructQueueIsFull(q,N) ( (q)->count >= N ) + + +/* StructQueueIsNotFull + ************************************************************************* + * Precondition: The queue must be initialized. + * + * Input: q Pointer to the queue data structure + * + * N Number of elements in the queue data buffer array + * + * Output: None + * + * Returns: FALSE if the queue is full, TRUE otherwise. + * + * Side Effects: None + * + * Overview: This routine checks to see if the queue is full. + * + * Note: This operation is implemented with a macro that + * supports queues of any type of data items. + *************************************************************************/ + +#define StructQueueIsNotFull(q,N) ( (q)->count < N ) + + +/* StructQueueIsEmpty + ************************************************************************* + * Precondition: The queue must be initialized. + * + * Input: q Pointer to the queue data structure + * + * N Number of elements in the queue data buffer array + * + * Output: None + * + * Returns: TRUE if the queue is empty, FALSE otherwise. + * + * Side Effects: None + * + * Overview: This routine checks to see if the queue is empty. + * + * Note: This operation is implemented with a macro that + * supports queues of any type of data items. + *************************************************************************/ + +#define StructQueueIsEmpty(q,N) ( (q)->count == 0 ) + + +/* StructQueueIsNotEmpty + ************************************************************************* + * Precondition: The queue must be initialized. + * + * Input: q Pointer to the queue data structure + * + * N Number of elements in the queue data buffer array + * + * Output: None + * + * Returns: FALSE if the queue is empty, TRUE otherwise. + * + * Side Effects: None + * + * Overview: This routine checks to see if the queue is not empty. + * + * Note: This operation is implemented with a macro that + * supports queues of any type of data items. + *************************************************************************/ + +#define StructQueueIsNotEmpty(q,N) ( (q)->count != 0 ) + + +/* StructQueueSpaceAvailable + ************************************************************************* + * Precondition: The queue must be initialized. + * + * Input: q Pointer to the queue data structure + * + * N Number of elements in the queue data buffer array + * + * Output: None + * + * Returns: TRUE if the queue has the indicated number of slots + available, FALSE otherwise. + * + * Side Effects: None + * + * Overview: This routine checks to see if the queue has at least + * the specified number of slots free. + * + * Note: This operation is implemented with a macro that + * supports queues of any type of data items. + *************************************************************************/ + +#define StructQueueSpaceAvailable(c,q,N) ( ((q)->count + c) <= N ) + + +/* StructQueueCount + ************************************************************************* + * Precondition: The queue must be initialized. + * + * Input: q Pointer to the queue data structure + * + * N Number of elements in the queue data buffer array + * + * Output: None + * + * Returns: The number of items in the queue. + * + * Side Effects: None + * + * Overview: This routine provides the number of items in the queue. + * + * Note: This operation is implemented with a macro that + * supports queues of any type of data items. + *************************************************************************/ + +#define StructQueueCount(q,N) ( (q)->count ) + + +#endif // STRUCT_QUEUE_H +/************************************************************************* + * EOF struct_queue.c + */ + diff --git a/usb/src/app_button_matrix.c b/usb/src/app_button_matrix.c new file mode 100644 index 0000000..0d98f04 --- /dev/null +++ b/usb/src/app_button_matrix.c @@ -0,0 +1,57 @@ +#include "app_button_matrix.h" + +static int8_t keyIndex; + +int8_t APP_ButtonMatrixGetIndex() { + return keyIndex; +} + +void APP_ButtonMatrixScan(void) { + keyIndex = -1; + + BTN_ROW_1_SetLow(); + BTN_COL_1_GetValue(); // wait for row to transition to low + + if (!BTN_COL_1_GetValue()) { + keyIndex = 0; + } else if (!BTN_COL_2_GetValue()) { + keyIndex = 1; + } else if (!BTN_COL_3_GetValue()) { + keyIndex = 2; + } + + BTN_ROW_1_SetHigh(); + + if (keyIndex != -1) return; + + BTN_ROW_2_SetLow(); + BTN_COL_1_GetValue(); // wait for row to transition to low + + if (!BTN_COL_1_GetValue()) { + keyIndex = 3; + } else if (!BTN_COL_2_GetValue()) { + keyIndex = 4; + } else if (!BTN_COL_3_GetValue()) { + keyIndex = 5; + } + + BTN_ROW_2_SetHigh(); + if (keyIndex != -1) return; + + BTN_ROW_3_SetLow(); + BTN_COL_1_GetValue(); // wait for row to transition to low + + if (!BTN_COL_1_GetValue()) { + keyIndex = 6; + } else if (!BTN_COL_2_GetValue()) { + keyIndex = 7; + } else if (!BTN_COL_3_GetValue()) { + keyIndex = 8; + } + + BTN_ROW_3_SetHigh(); +} + +void APP_ButtonMatrixInit(void) { + keyIndex = -1; +} diff --git a/usb/src/app_page_selector.c b/usb/src/app_page_selector.c new file mode 100644 index 0000000..07b41db --- /dev/null +++ b/usb/src/app_page_selector.c @@ -0,0 +1,50 @@ +#include "app_page_selector.h" + +static uint8_t pageIndex; +static bool waitsKeyRelease; + +uint8_t APP_PageSelectorGetIndex() { + return pageIndex; +} + +static void APP_PageSelectorNext(void) { + switch (pageIndex) { + case 0: + pageIndex = 1; + LED_1_SetLow(); + LED_2_SetHigh(); + break; + case 1: + pageIndex = 2; + LED_2_SetLow(); + LED_3_SetHigh(); + break; + case 2: + pageIndex = 3; + LED_3_SetLow(); + LED_4_SetHigh(); + break; + case 3: + pageIndex = 0; + LED_4_SetLow(); + LED_1_SetHigh(); + break; + } +} +void APP_PageSelectorUpdate(void) { + if (!SWT_IN_GetValue()) { + if (!waitsKeyRelease) { + APP_PageSelectorNext(); + waitsKeyRelease = true; + } + } else { + waitsKeyRelease = false; + } +} + +void APP_PageSelectorInit(void) { + pageIndex = 0; + waitsKeyRelease = false; + LED_1_SetHigh(); +} + diff --git a/usb/src/usb_device.c b/usb/src/usb_device.c new file mode 100644 index 0000000..dd814fe --- /dev/null +++ b/usb/src/usb_device.c @@ -0,0 +1,3101 @@ +// 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 + +/******************************************************************************* + USB Device Layer + + Company: + Microchip Technology Inc. + + File Name: + usb_device.c + + Summary: + Provides basic USB device functionality, including enumeration and USB + chapter 9 required behavior. + + Description: + Provides basic USB device functionality, including enumeration and USB + chapter 9 required behavior. +*******************************************************************************/ + +// ***************************************************************************** +// ***************************************************************************** +// Section: Included Files +// ***************************************************************************** +// ***************************************************************************** +#include + +#include +#include +#include + +#include "usb_config.h" + +#include "usb.h" +#include "usb_ch9.h" +#include "usb_device.h" +#include "usb_device_local.h" + +#ifndef uintptr_t + #if defined(__XC8__) || defined(__XC16__) + #define uintptr_t uint16_t + #elif defined (__XC32__) + #define uintptr_t uint32_t + #endif +#endif + +// ***************************************************************************** +// ***************************************************************************** +// Section: File Scope or Global Constants +// ***************************************************************************** +// ***************************************************************************** +#if !defined(USE_USB_BUS_SENSE_IO) + //Assume the +5V VBUS is always present (like it would be in a bus powered + //only application), unless USE_USB_BUS_SENSE_IO and USB_BUS_SENSE have + //been properly defined elsewhere in the project. + #undef USB_BUS_SENSE + #define USB_BUS_SENSE 1 +#endif + +#if defined(USB_DEVICE_DISABLE_DTS_CHECKING) + #define _DTS_CHECKING_ENABLED 0 +#else + #define _DTS_CHECKING_ENABLED _DTSEN +#endif + +#if !defined(self_power) + //Assume the application is always bus powered, unless self_power has been + //defined elsewhere in the project + #define self_power 0 //0 = bus powered +#endif + +#if !defined(USB_MAX_NUM_CONFIG_DSC) + //Assume the application only implements one configuration descriptor, + //unless otherwise specified elsewhere in the project + #define USB_MAX_NUM_CONFIG_DSC 1 +#endif + +#if defined(__XC8) + //Suppress expected/harmless compiler warning message about unused RAM variables + //and certain function pointer usage. + //Certain variables and function pointers are not used if you don't use all + //of the USB stack APIs. However, these variables should not be + //removed (since they are still used/needed in some applications, and this + //is a common file shared by many projects, some of which rely on the "unused" + //variables/function pointers). + #pragma warning disable 1090 + #if __XC8_VERSION > 1300 + #pragma warning disable 1471 + #endif +#endif + +// ***************************************************************************** +// ***************************************************************************** +// Section: File Scope Data Types +// ***************************************************************************** +// ***************************************************************************** +typedef union +{ + uint8_t Val; + struct __PACKED + { + unsigned b0:1; + unsigned b1:1; + unsigned b2:1; + unsigned b3:1; + unsigned b4:1; + unsigned b5:1; + unsigned b6:1; + unsigned b7:1; + } bits; +} uint8_t_VAL, uint8_t_BITS; + +// ***************************************************************************** +// ***************************************************************************** +// Section: Variables +// ***************************************************************************** +// ***************************************************************************** +USB_VOLATILE USB_DEVICE_STATE USBDeviceState; +USB_VOLATILE uint8_t USBActiveConfiguration; +USB_VOLATILE uint8_t USBAlternateInterface[USB_MAX_NUM_INT]; +volatile BDT_ENTRY *pBDTEntryEP0OutCurrent; +volatile BDT_ENTRY *pBDTEntryEP0OutNext; +volatile BDT_ENTRY *pBDTEntryOut[USB_MAX_EP_NUMBER+1]; +volatile BDT_ENTRY *pBDTEntryIn[USB_MAX_EP_NUMBER+1]; +USB_VOLATILE uint8_t shortPacketStatus; +USB_VOLATILE uint8_t controlTransferState; +USB_VOLATILE IN_PIPE inPipes[1]; +USB_VOLATILE OUT_PIPE outPipes[1]; +USB_VOLATILE uint8_t *pDst; +USB_VOLATILE bool RemoteWakeup; +USB_VOLATILE bool USBBusIsSuspended; +USB_VOLATILE USTAT_FIELDS USTATcopy; +USB_VOLATILE uint8_t endpoint_number; +USB_VOLATILE bool BothEP0OutUOWNsSet; +USB_VOLATILE EP_STATUS ep_data_in[USB_MAX_EP_NUMBER+1]; +USB_VOLATILE EP_STATUS ep_data_out[USB_MAX_EP_NUMBER+1]; +USB_VOLATILE uint8_t USBStatusStageTimeoutCounter; +volatile bool USBDeferStatusStagePacket; +volatile bool USBStatusStageEnabledFlag1; +volatile bool USBStatusStageEnabledFlag2; +volatile bool USBDeferINDataStagePackets; +volatile bool USBDeferOUTDataStagePackets; +USB_VOLATILE uint32_t USB1msTickCount; +USB_VOLATILE uint8_t USBTicksSinceSuspendEnd; + +/** USB FIXED LOCATION VARIABLES ***********************************/ +#if defined(COMPILER_MPLAB_C18) + #pragma udata USB_BDT=USB_BDT_ADDRESS +#endif + +volatile BDT_ENTRY BDT[BDT_NUM_ENTRIES] BDT_BASE_ADDR_TAG; + +/******************************************************************** + * EP0 Buffer Space + *******************************************************************/ +volatile CTRL_TRF_SETUP SetupPkt CTRL_TRF_SETUP_ADDR_TAG; +volatile uint8_t CtrlTrfData[USB_EP0_BUFF_SIZE] CTRL_TRF_DATA_ADDR_TAG; + +//Depricated in v2.2 - will be removed in a future revision +#if !defined(USB_USER_DEVICE_DESCRIPTOR) + //Device descriptor + extern const USB_DEVICE_DESCRIPTOR device_dsc; +#else + USB_USER_DEVICE_DESCRIPTOR_INCLUDE; +#endif + +#if !defined(USB_USER_CONFIG_DESCRIPTOR) + //Array of configuration descriptors + extern const uint8_t *const USB_CD_Ptr[]; +#else + USB_USER_CONFIG_DESCRIPTOR_INCLUDE; +#endif + +extern const uint8_t *const USB_SD_Ptr[]; + + +// ***************************************************************************** +// ***************************************************************************** +// Section: Private and External Prototypes +// ***************************************************************************** +// ***************************************************************************** +extern bool USER_USB_CALLBACK_EVENT_HANDLER(USB_EVENT event, void *pdata, uint16_t size); + +static void USBCtrlEPService(void); +static void USBCtrlTrfSetupHandler(void); +static void USBCtrlTrfInHandler(void); +static void USBCheckStdRequest(void); +static void USBStdGetDscHandler(void); +static void USBCtrlEPServiceComplete(void); +static void USBCtrlTrfTxService(void); +static void USBCtrlTrfRxService(void); +static void USBStdSetCfgHandler(void); +static void USBStdGetStatusHandler(void); +static void USBStdFeatureReqHandler(void); +static void USBCtrlTrfOutHandler(void); +static void USBConfigureEndpoint(uint8_t EPNum, uint8_t direction); +static void USBWakeFromSuspend(void); +static void USBSuspend(void); +static void USBStallHandler(void); + +// ***************************************************************************** +// ***************************************************************************** +// Section: Macros or Functions +// ***************************************************************************** +// ***************************************************************************** + +/************************************************************************** + Function: + void USBDeviceInit(void) + + Description: + This function initializes the device stack it in the default state. The + USB module will be completely reset including all of the internal + variables, registers, and interrupt flags. + + Precondition: + This function must be called before any of the other USB Device + functions can be called, including USBDeviceTasks(). + + Parameters: + None + + Return Values: + None + + Remarks: + None + + ***************************************************************************/ +void USBDeviceInit(void) +{ + uint8_t i; + + USBDisableInterrupts(); + + //Make sure that if a GPIO output driver exists on VBUS, that it is + //tri-stated to avoid potential contention with the host + USB_HAL_VBUSTristate(); + + // Clear all USB error flags + USBClearInterruptRegister(U1EIR); + + // Clears all USB interrupts + USBClearInterruptRegister(U1IR); + + //Clear all of the endpoint control registers + U1EP0 = 0; + + DisableNonZeroEndpoints(USB_MAX_EP_NUMBER); + + SetConfigurationOptions(); + + //power up the module (if not already powered) + USBPowerModule(); + + //set the address of the BDT (if applicable) + USBSetBDTAddress(BDT); + + //Clear all of the BDT entries + for(i = 0; i < (sizeof(BDT)/sizeof(BDT_ENTRY)); i++) + { + BDT[i].Val = 0x00; + } + + // Assert reset request to all of the Ping Pong buffer pointers + USBPingPongBufferReset = 1; + + // Reset to default address + U1ADDR = 0x00; + + // Make sure packet processing is enabled + USBPacketDisable = 0; + + //Stop trying to reset ping pong buffer pointers + USBPingPongBufferReset = 0; + + // Flush any pending transactions + do + { + USBClearInterruptFlag(USBTransactionCompleteIFReg,USBTransactionCompleteIFBitNum); + //Initialize USB stack software state variables + inPipes[0].info.Val = 0; + outPipes[0].info.Val = 0; + outPipes[0].wCount.Val = 0; + }while(USBTransactionCompleteIF == 1); + + //Set flags to true, so the USBCtrlEPAllowStatusStage() function knows not to + //try and arm a status stage, even before the first control transfer starts. + USBStatusStageEnabledFlag1 = true; + USBStatusStageEnabledFlag2 = true; + //Initialize other flags + USBDeferINDataStagePackets = false; + USBDeferOUTDataStagePackets = false; + USBBusIsSuspended = false; + + //Initialize all pBDTEntryIn[] and pBDTEntryOut[] + //pointers to NULL, so they don't get used inadvertently. + for(i = 0; i < (uint8_t)(USB_MAX_EP_NUMBER+1u); i++) + { + pBDTEntryIn[i] = 0u; + pBDTEntryOut[i] = 0u; + ep_data_in[i].Val = 0u; + ep_data_out[i].Val = 0u; + } + + //Get ready for the first packet + pBDTEntryIn[0] = (volatile BDT_ENTRY*)&BDT[EP0_IN_EVEN]; + // Initialize EP0 as a Ctrl EP + U1EP0 = EP_CTRL|USB_HANDSHAKE_ENABLED; + //Prepare for the first SETUP on EP0 OUT + BDT[EP0_OUT_EVEN].ADR = ConvertToPhysicalAddress(&SetupPkt); + BDT[EP0_OUT_EVEN].CNT = USB_EP0_BUFF_SIZE; + BDT[EP0_OUT_EVEN].STAT.Val = _DAT0|_BSTALL; + BDT[EP0_OUT_EVEN].STAT.Val |= _USIE; + + // Clear active configuration + USBActiveConfiguration = 0; + + USB1msTickCount = 0; //Keeps track of total number of milliseconds since calling USBDeviceInit() when first initializing the USB module/stack code. + USBTicksSinceSuspendEnd = 0; //Keeps track of the number of milliseconds since a suspend condition has ended. + + //Indicate that we are now in the detached state + USBDeviceState = DETACHED_STATE; +} + + + +/************************************************************************** + Function: + void USBDeviceTasks(void) + + Summary: + This function is the main state machine/transaction handler of the USB + device side stack. When the USB stack is operated in "USB_POLLING" mode + (usb_config.h user option) the USBDeviceTasks() function should be called + periodically to receive and transmit packets through the stack. This + function also takes care of control transfers associated with the USB + enumeration process, and detecting various USB events (such as suspend). + This function should be called at least once every 1.8ms during the USB + enumeration process. After the enumeration process is complete (which can + be determined when USBGetDeviceState() returns CONFIGURED_STATE), the + USBDeviceTasks() handler may be called the faster of: either once + every 9.8ms, or as often as needed to make sure that the hardware USTAT + FIFO never gets full. A good rule of thumb is to call USBDeviceTasks() at + a minimum rate of either the frequency that USBTransferOnePacket() gets + called, or, once/1.8ms, whichever is faster. See the inline code comments + near the top of usb_device.c for more details about minimum timing + requirements when calling USBDeviceTasks(). + + When the USB stack is operated in "USB_INTERRUPT" mode, it is not necessary + to call USBDeviceTasks() from the main loop context. In the USB_INTERRUPT + mode, the USBDeviceTasks() handler only needs to execute when a USB + interrupt occurs, and therefore only needs to be called from the interrupt + context. + + Description: + This function is the main state machine/transaction handler of the USB + device side stack. When the USB stack is operated in "USB_POLLING" mode + (usb_config.h user option) the USBDeviceTasks() function should be called + periodically to receive and transmit packets through the stack. This + function also takes care of control transfers associated with the USB + enumeration process, and detecting various USB events (such as suspend). + This function should be called at least once every 1.8ms during the USB + enumeration process. After the enumeration process is complete (which can + be determined when USBGetDeviceState() returns CONFIGURED_STATE), the + USBDeviceTasks() handler may be called the faster of: either once + every 9.8ms, or as often as needed to make sure that the hardware USTAT + FIFO never gets full. A good rule of thumb is to call USBDeviceTasks() at + a minimum rate of either the frequency that USBTransferOnePacket() gets + called, or, once/1.8ms, whichever is faster. See the inline code comments + near the top of usb_device.c for more details about minimum timing + requirements when calling USBDeviceTasks(). + + When the USB stack is operated in "USB_INTERRUPT" mode, it is not necessary + to call USBDeviceTasks() from the main loop context. In the USB_INTERRUPT + mode, the USBDeviceTasks() handler only needs to execute when a USB + interrupt occurs, and therefore only needs to be called from the interrupt + context. + + Typical usage: + + void main(void) + { + USBDeviceInit(); + while(1) + { + USBDeviceTasks(); //Takes care of enumeration and other USB events + if((USBGetDeviceState() \< CONFIGURED_STATE) || + (USBIsDeviceSuspended() == true)) + { + //Either the device is not configured or we are suspended, + // so we don't want to execute any USB related application code + continue; //go back to the top of the while loop + } + else + { + //Otherwise we are free to run USB and non-USB related user + //application code. + UserApplication(); + } + } + } + + + Precondition: + Make sure the USBDeviceInit() function has been called prior to calling + USBDeviceTasks() for the first time. + Remarks: + USBDeviceTasks() does not need to be called while in the USB suspend mode, + if the user application firmware in the USBCBSuspend() callback function + enables the ACTVIF USB interrupt source and put the microcontroller into + sleep mode. If the application firmware decides not to sleep the + microcontroller core during USB suspend (ex: continues running at full + frequency, or clock switches to a lower frequency), then the USBDeviceTasks() + function must still be called periodically, at a rate frequent enough to + ensure the 10ms resume recovery interval USB specification is met. Assuming + a worst case primary oscillator and PLL start up time of less than 5ms, then + USBDeviceTasks() should be called once every 5ms in this scenario. + + When the USB cable is detached, or the USB host is not actively powering + the VBUS line to +5V nominal, the application firmware does not always have + to call USBDeviceTasks() frequently, as no USB activity will be taking + place. However, if USBDeviceTasks() is not called regularly, some + alternative means of promptly detecting when VBUS is powered (indicating + host attachment), or not powered (host powered down or USB cable unplugged) + is still needed. For self or dual self/bus powered USB applications, see + the USBDeviceAttach() and USBDeviceDetach() API documentation for additional + considerations. + ***************************************************************************/ +void USBDeviceTasks(void) +{ + uint8_t i; + + #ifdef USB_SUPPORT_OTG + //SRP Time Out Check + if (USBOTGSRPIsReady()) + { + if (USBT1MSECIF && USBT1MSECIE) + { + if (USBOTGGetSRPTimeOutFlag()) + { + if (USBOTGIsSRPTimeOutExpired()) + { + USB_OTGEventHandler(0,OTG_EVENT_SRP_FAILED,0,0); + } + } + + //Clear Interrupt Flag + USBClearInterruptFlag(USBT1MSECIFReg,USBT1MSECIFBitNum); + } + } + #endif + + #if defined(USB_POLLING) + //If the interrupt option is selected then the customer is required + // to notify the stack when the device is attached or removed from the + // bus by calling the USBDeviceAttach() and USBDeviceDetach() functions. + if (USB_BUS_SENSE != 1) + { + // Disable module & detach from bus + U1CON = 0; + + // Mask all USB interrupts + U1IE = 0; + + //Move to the detached state + USBDeviceState = DETACHED_STATE; + + #ifdef USB_SUPPORT_OTG + //Disable D+ Pullup + U1OTGCONbits.DPPULUP = 0; + + //Disable HNP + USBOTGDisableHnp(); + + //Deactivate HNP + USBOTGDeactivateHnp(); + + //If ID Pin Changed State + if (USBIDIF && USBIDIE) + { + //Re-detect & Initialize + USBOTGInitialize(); + + //Clear ID Interrupt Flag + USBClearInterruptFlag(USBIDIFReg,USBIDIFBitNum); + } + #endif + + #if defined __C30__ || defined __XC16__ + //USBClearInterruptFlag(U1OTGIR, 3); + #endif + //return so that we don't go through the rest of + //the state machine + USBClearUSBInterrupt(); + return; + } + + #ifdef USB_SUPPORT_OTG + //If Session Is Started Then + else + { + //If SRP Is Ready + if (USBOTGSRPIsReady()) + { + //Clear SRPReady + USBOTGClearSRPReady(); + + //Clear SRP Timeout Flag + USBOTGClearSRPTimeOutFlag(); + + //Indicate Session Started + UART2PrintString( "\r\n***** USB OTG B Event - Session Started *****\r\n" ); + } + } + #endif //#ifdef USB_SUPPORT_OTG + + //if we are in the detached state + if(USBDeviceState == DETACHED_STATE) + { + //Initialize register to known value + U1CON = 0; + + // Mask all USB interrupts + U1IE = 0; + + //Enable/set things like: pull ups, full/low-speed mode, + //set the ping pong mode, and set internal transceiver + SetConfigurationOptions(); + + // Enable module & attach to bus + while(!U1CONbits.USBEN){U1CONbits.USBEN = 1;} + + //moved to the attached state + USBDeviceState = ATTACHED_STATE; + + #ifdef USB_SUPPORT_OTG + U1OTGCON |= USB_OTG_DPLUS_ENABLE | USB_OTG_ENABLE; + #endif + } + #endif //#if defined(USB_POLLING) + + if(USBDeviceState == ATTACHED_STATE) + { + /* + * After enabling the USB module, it takes some time for the + * voltage on the D+ or D- line to rise high enough to get out + * of the SE0 condition. The USB Reset interrupt should not be + * unmasked until the SE0 condition is cleared. This helps + * prevent the firmware from misinterpreting this unique event + * as a USB bus reset from the USB host. + */ + + if(!USBSE0Event) + { + //We recently attached, make sure we are in a clean state + #if defined(__dsPIC33E__) || defined(_PIC24E__) || defined(__PIC32MM__) + U1IR = 0xFFEF; //Preserve IDLEIF info, so we can detect suspend + //during attach de-bounce interval + #else + USBClearInterruptRegister(U1IR); + #endif + + #if defined(USB_POLLING) + U1IE=0; // Mask all USB interrupts + #endif + USBResetIE = 1; // Unmask RESET interrupt + USBIdleIE = 1; // Unmask IDLE interrupt + USBDeviceState = POWERED_STATE; + } + } + + #ifdef USB_SUPPORT_OTG + //If ID Pin Changed State + if (USBIDIF && USBIDIE) + { + //Re-detect & Initialize + USBOTGInitialize(); + + USBClearInterruptFlag(USBIDIFReg,USBIDIFBitNum); + } + #endif + + /* + * Task A: Service USB Activity Interrupt + */ + if(USBActivityIF && USBActivityIE) + { + USBClearInterruptFlag(USBActivityIFReg,USBActivityIFBitNum); + #if defined(USB_SUPPORT_OTG) + U1OTGIR = 0x10; + #else + USBWakeFromSuspend(); + #endif + } + + /* + * Pointless to continue servicing if the device is in suspend mode. + */ + if(USBSuspendControl==1) + { + USBClearUSBInterrupt(); + return; + } + + /* + * Task B: Service USB Bus Reset Interrupt. + * When bus reset is received during suspend, ACTVIF will be set first, + * once the UCONbits.SUSPND is clear, then the URSTIF bit will be asserted. + * This is why URSTIF is checked after ACTVIF. + * + * The USB reset flag is masked when the USB state is in + * DETACHED_STATE or ATTACHED_STATE, and therefore cannot + * cause a USB reset event during these two states. + */ + if(USBResetIF && USBResetIE) + { + USBDeviceInit(); + + //Re-enable the interrupts since the USBDeviceInit() function will + // disable them. This will do nothing in a polling setup + USBUnmaskInterrupts(); + + USBDeviceState = DEFAULT_STATE; + + #ifdef USB_SUPPORT_OTG + //Disable HNP + USBOTGDisableHnp(); + + //Deactivate HNP + USBOTGDeactivateHnp(); + #endif + + USBClearInterruptFlag(USBResetIFReg,USBResetIFBitNum); + } + + /* + * Task C: Service other USB interrupts + */ + if(USBIdleIF && USBIdleIE) + { + #ifdef USB_SUPPORT_OTG + //If Suspended, Try to switch to Host + USBOTGSelectRole(ROLE_HOST); + USBClearInterruptFlag(USBIdleIFReg,USBIdleIFBitNum); + #else + USBSuspend(); + #endif + } + + #if defined(__XC16__) || defined(__C30__) || defined(__XC32__) + //Check if a 1ms interval has elapsed. + if(USBT1MSECIF) + { + USBClearInterruptFlag(USBT1MSECIFReg, USBT1MSECIFBitNum); + USBIncrement1msInternalTimers(); + } + #endif + + //Start-of-Frame Interrupt + if(USBSOFIF) + { + //Call the user SOF event callback if enabled. + if(USBSOFIE) + { + USB_SOF_HANDLER(EVENT_SOF,0,1); + } + USBClearInterruptFlag(USBSOFIFReg,USBSOFIFBitNum); + + #if defined(__XC8__) || defined(__C18__) + USBIncrement1msInternalTimers(); + #endif + + #if defined(USB_ENABLE_STATUS_STAGE_TIMEOUTS) + //Supporting this feature requires a 1ms time base for keeping track of the timeout interval. + #if(USB_SPEED_OPTION == USB_LOW_SPEED) + #warning "Double click this message. See inline code comments." + //The "USB_ENABLE_STATUS_STAGE_TIMEOUTS" feature is optional and is + //not strictly needed in all applications (ex: those that never call + //USBDeferStatusStage() and don't use host to device (OUT) control + //transfers with data stage). + //However, if this feature is enabled and used in a low speed application, + //it is required for the application code to periodically call the + //USBIncrement1msInternalTimers() function at a nominally 1ms rate. + #endif + + //Decrement our status stage counter. + if(USBStatusStageTimeoutCounter != 0u) + { + USBStatusStageTimeoutCounter--; + } + //Check if too much time has elapsed since progress was made in + //processing the control transfer, without arming the status stage. + //If so, auto-arm the status stage to ensure that the control + //transfer can [eventually] complete, within the timing limits + //dictated by section 9.2.6 of the official USB 2.0 specifications. + if(USBStatusStageTimeoutCounter == 0) + { + USBCtrlEPAllowStatusStage(); //Does nothing if the status stage was already armed. + } + #endif + } + + if(USBStallIF && USBStallIE) + { + USBStallHandler(); + } + + if(USBErrorIF && USBErrorIE) + { + USB_ERROR_HANDLER(EVENT_BUS_ERROR,0,1); + USBClearInterruptRegister(U1EIR); // This clears UERRIF + + //On PIC18, clearing the source of the error will automatically clear + // the interrupt flag. On other devices the interrupt flag must be + // manually cleared. + #if defined(__C32__) || defined(__C30__) || defined __XC16__ + USBClearInterruptFlag( USBErrorIFReg, USBErrorIFBitNum ); + #endif + } + + /* + * Pointless to continue servicing if the host has not sent a bus reset. + * Once bus reset is received, the device transitions into the DEFAULT + * state and is ready for communication. + */ + if(USBDeviceState < DEFAULT_STATE) + { + USBClearUSBInterrupt(); + return; + } + + /* + * Task D: Servicing USB Transaction Complete Interrupt + */ + if(USBTransactionCompleteIE) + { + for(i = 0; i < 4u; i++) //Drain or deplete the USAT FIFO entries. If the USB FIFO ever gets full, USB bandwidth + { //utilization can be compromised, and the device won't be able to receive SETUP packets. + if(USBTransactionCompleteIF) + { + //Save and extract USTAT register info. Will use this info later. + USTATcopy.Val = U1STAT; + endpoint_number = USBHALGetLastEndpoint(USTATcopy); + + USBClearInterruptFlag(USBTransactionCompleteIFReg,USBTransactionCompleteIFBitNum); + + //Keep track of the hardware ping pong state for endpoints other + //than EP0, if ping pong buffering is enabled. + #if (USB_PING_PONG_MODE == USB_PING_PONG__ALL_BUT_EP0) || (USB_PING_PONG_MODE == USB_PING_PONG__FULL_PING_PONG) + if(USBHALGetLastDirection(USTATcopy) == OUT_FROM_HOST) + { + ep_data_out[endpoint_number].bits.ping_pong_state ^= 1; + } + else + { + ep_data_in[endpoint_number].bits.ping_pong_state ^= 1; + } + #endif + + //USBCtrlEPService only services transactions over EP0. + //It ignores all other EP transactions. + if(endpoint_number == 0) + { + USBCtrlEPService(); + } + else + { + USB_TRANSFER_COMPLETE_HANDLER(EVENT_TRANSFER, (uint8_t*)&USTATcopy.Val, 0); + } + }//end if(USBTransactionCompleteIF) + else + { + break; //USTAT FIFO must be empty. + } + }//end for() + }//end if(USBTransactionCompleteIE) + + USBClearUSBInterrupt(); +}//end of USBDeviceTasks() + +/******************************************************************************* + Function: + void USBEnableEndpoint(uint8_t ep, uint8_t options) + + Summary: + This function will enable the specified endpoint with the specified + options + Description: + This function will enable the specified endpoint with the specified + options. + + Typical Usage: + + void USBCBInitEP(void) + { + USBEnableEndpoint(MSD_DATA_IN_EP,USB_IN_ENABLED|USB_OUT_ENABLED|USB_HANDSHAKE_ENABLED|USB_DISALLOW_SETUP); + USBMSDInit(); + } + + + In the above example endpoint number MSD_DATA_IN_EP is being configured + for both IN and OUT traffic with handshaking enabled. Also since + MSD_DATA_IN_EP is not endpoint 0 (MSD does not allow this), then we can + explicitly disable SETUP packets on this endpoint. + Conditions: + None + Input: + uint8_t ep - the endpoint to be configured + uint8_t options - optional settings for the endpoint. The options should + be ORed together to form a single options string. The + available optional settings for the endpoint. The + options should be ORed together to form a single options + string. The available options are the following\: + * USB_HANDSHAKE_ENABLED enables USB handshaking (ACK, + NAK) + * USB_HANDSHAKE_DISABLED disables USB handshaking (ACK, + NAK) + * USB_OUT_ENABLED enables the out direction + * USB_OUT_DISABLED disables the out direction + * USB_IN_ENABLED enables the in direction + * USB_IN_DISABLED disables the in direction + * USB_ALLOW_SETUP enables control transfers + * USB_DISALLOW_SETUP disables control transfers + * USB_STALL_ENDPOINT STALLs this endpoint + Return: + None + Remarks: + None + *****************************************************************************/ +void USBEnableEndpoint(uint8_t ep, uint8_t options) +{ + unsigned char* p; + + //Use USBConfigureEndpoint() to set up the pBDTEntryIn/Out[ep] pointer and + //starting DTS state in the BDT entry. + if(options & USB_OUT_ENABLED) + { + USBConfigureEndpoint(ep, OUT_FROM_HOST); + } + if(options & USB_IN_ENABLED) + { + USBConfigureEndpoint(ep, IN_TO_HOST); + } + + //Update the relevant UEPx register to actually enable the endpoint with + //the specified options (ex: handshaking enabled, control transfers allowed, + //etc.) + #if defined(__C32__) + p = (unsigned char*)(&U1EP0+(4*ep)); + #else + p = (unsigned char*)(&U1EP0+ep); + #endif + *p = options; +} + + +/************************************************************************* + Function: + USB_HANDLE USBTransferOnePacket(uint8_t ep, uint8_t dir, uint8_t* data, uint8_t len) + + Summary: + Transfers a single packet (one transaction) of data on the USB bus. + + Description: + The USBTransferOnePacket() function prepares a USB endpoint + so that it may send data to the host (an IN transaction), or + receive data from the host (an OUT transaction). The + USBTransferOnePacket() function can be used both to receive and + send data to the host. This function is the primary API function + provided by the USB stack firmware for sending or receiving application + data over the USB port. + + The USBTransferOnePacket() is intended for use with all application + endpoints. It is not used for sending or receiving application data + through endpoint 0 by using control transfers. Separate API + functions, such as USBEP0Receive(), USBEP0SendRAMPtr(), and + USBEP0SendROMPtr() are provided for this purpose. + + The USBTransferOnePacket() writes to the Buffer Descriptor Table (BDT) + entry associated with an endpoint buffer, and sets the UOWN bit, which + prepares the USB hardware to allow the transaction to complete. The + application firmware can use the USBHandleBusy() macro to check the + status of the transaction, to see if the data has been successfully + transmitted yet. + + + Typical Usage + + //make sure that the we are in the configured state + if(USBGetDeviceState() == CONFIGURED_STATE) + { + //make sure that the last transaction isn't busy by checking the handle + if(!USBHandleBusy(USBInHandle)) + { + //Write the new data that we wish to send to the host to the INPacket[] array + INPacket[0] = USEFUL_APPLICATION_VALUE1; + INPacket[1] = USEFUL_APPLICATION_VALUE2; + //INPacket[2] = ... (fill in the rest of the packet data) + + //Send the data contained in the INPacket[] array through endpoint "EP_NUM" + USBInHandle = USBTransferOnePacket(EP_NUM,IN_TO_HOST,(uint8_t*)&INPacket[0],sizeof(INPacket)); + } + } + + + Conditions: + Before calling USBTransferOnePacket(), the following should be true. + 1. The USB stack has already been initialized (USBDeviceInit() was called). + 2. A transaction is not already pending on the specified endpoint. This + is done by checking the previous request using the USBHandleBusy() + macro (see the typical usage example). + 3. The host has already sent a set configuration request and the + enumeration process is complete. + This can be checked by verifying that the USBGetDeviceState() + macro returns "CONFIGURED_STATE", prior to calling + USBTransferOnePacket(). + + Input: + uint8_t ep - The endpoint number that the data will be transmitted or + received on + uint8_t dir - The direction of the transfer + This value is either OUT_FROM_HOST or IN_TO_HOST + uint8_t* data - For IN transactions: pointer to the RAM buffer containing + the data to be sent to the host. For OUT transactions: pointer + to the RAM buffer that the received data should get written to. + uint8_t len - Length of the data needing to be sent (for IN transactions). + For OUT transactions, the len parameter should normally be set + to the endpoint size specified in the endpoint descriptor. + + Return Values: + USB_HANDLE - handle to the transfer. The handle is a pointer to + the BDT entry associated with this transaction. The + status of the transaction (ex: if it is complete or still + pending) can be checked using the USBHandleBusy() macro + and supplying the USB_HANDLE provided by + USBTransferOnePacket(). + + Remarks: + If calling the USBTransferOnePacket() function from within the USBCBInitEP() + callback function, the set configuration is still being processed and the + USBDeviceState may not be == CONFIGURED_STATE yet. In this special case, + the USBTransferOnePacket() may still be called, but make sure that the + endpoint has been enabled and initialized by the USBEnableEndpoint() + function first. + + *************************************************************************/ +USB_HANDLE USBTransferOnePacket(uint8_t ep,uint8_t dir,uint8_t* data,uint8_t len) +{ + volatile BDT_ENTRY* handle; + + //If the direction is IN + if(dir != 0) + { + //point to the IN BDT of the specified endpoint + handle = pBDTEntryIn[ep]; + } + else + { + //else point to the OUT BDT of the specified endpoint + handle = pBDTEntryOut[ep]; + } + + //Error checking code. Make sure the handle (pBDTEntryIn[ep] or + //pBDTEntryOut[ep]) is initialized before using it. + if(handle == 0) + { + return 0; + } + + //Toggle the DTS bit if required + #if (USB_PING_PONG_MODE == USB_PING_PONG__NO_PING_PONG) + handle->STAT.Val ^= _DTSMASK; + #elif (USB_PING_PONG_MODE == USB_PING_PONG__EP0_OUT_ONLY) + if(ep != 0) + { + handle->STAT.Val ^= _DTSMASK; + } + #endif + + //Set the data pointer, data length, and enable the endpoint + handle->ADR = ConvertToPhysicalAddress(data); + handle->CNT = len; + handle->STAT.Val &= _DTSMASK; + handle->STAT.Val |= (_DTSEN & _DTS_CHECKING_ENABLED); + handle->STAT.Val |= _USIE; + + //Point to the next buffer for ping pong purposes. + if(dir != OUT_FROM_HOST) + { + //toggle over the to the next buffer for an IN endpoint + pBDTEntryIn[ep] = (BDT_ENTRY*)(((uintptr_t)pBDTEntryIn[ep]) ^ USB_NEXT_PING_PONG); + } + else + { + //toggle over the to the next buffer for an OUT endpoint + pBDTEntryOut[ep] = (BDT_ENTRY*)(((uintptr_t)pBDTEntryOut[ep]) ^ USB_NEXT_PING_PONG); + } + return (USB_HANDLE)handle; +} + + +/******************************************************************** + Function: + void USBStallEndpoint(uint8_t ep, uint8_t dir) + + Summary: + Configures the specified endpoint to send STALL to the host, the next + time the host tries to access the endpoint. + + PreCondition: + None + + Parameters: + uint8_t ep - The endpoint number that should be configured to send STALL. + uint8_t dir - The direction of the endpoint to STALL, either + IN_TO_HOST or OUT_FROM_HOST. + + Return Values: + None + + Remarks: + None + + *******************************************************************/ +void USBStallEndpoint(uint8_t ep, uint8_t dir) +{ + BDT_ENTRY *p; + + if(ep == 0) + { + //For control endpoints (ex: EP0), we need to STALL both IN and OUT + //endpoints. EP0 OUT must also be prepared to receive the next SETUP + //packet that will arrive. + pBDTEntryEP0OutNext->CNT = USB_EP0_BUFF_SIZE; + pBDTEntryEP0OutNext->ADR = ConvertToPhysicalAddress(&SetupPkt); + pBDTEntryEP0OutNext->STAT.Val = _DAT0|(_DTSEN & _DTS_CHECKING_ENABLED)|_BSTALL; + pBDTEntryEP0OutNext->STAT.Val |= _USIE; + pBDTEntryIn[0]->STAT.Val = _BSTALL; + pBDTEntryIn[0]->STAT.Val |= _USIE; + + } + else + { + p = (BDT_ENTRY*)(&BDT[EP(ep,dir,0)]); + p->STAT.Val |= _BSTALL; + p->STAT.Val |= _USIE; + + //If the device is in FULL or ALL_BUT_EP0 ping pong modes + //then stall that entry as well + #if (USB_PING_PONG_MODE == USB_PING_PONG__FULL_PING_PONG) || (USB_PING_PONG_MODE == USB_PING_PONG__ALL_BUT_EP0) + p = (BDT_ENTRY*)(&BDT[EP(ep,dir,1)]); + p->STAT.Val |= _BSTALL; + p->STAT.Val |= _USIE; + #endif + } +} + +/************************************************************************** + Function: + void USBCancelIO(uint8_t endpoint) + + Description: + This function cancels the transfers pending on the specified endpoint. + This function can only be used after a SETUP packet is received and + before that setup packet is handled. This is the time period in which + the EVENT_EP0_REQUEST is thrown, before the event handler function + returns to the stack. + + Precondition: + + Parameters: + uint8_t endpoint - the endpoint number you wish to cancel the transfers for + + Return Values: + None + + Remarks: + None + + **************************************************************************/ +void USBCancelIO(uint8_t endpoint) +{ + if(USBPacketDisable == 1) + { + //The PKTDIS bit is currently set right now. It is therefore "safe" + //to mess with the BDT right now. + pBDTEntryIn[endpoint]->Val &= _DTSMASK; //Makes UOWN = 0 (_UCPU mode). Deactivates endpoint. Only sends NAKs. + pBDTEntryIn[endpoint]->Val ^= _DTSMASK; //Toggle the DTS bit. This packet didn't get sent yet, and the next call to USBTransferOnePacket() will re-toggle the DTS bit back to the original (correct) value. + + //Need to do additional handling if ping-pong buffering is being used + #if ((USB_PING_PONG_MODE == USB_PING_PONG__FULL_PING_PONG) || (USB_PING_PONG_MODE == USB_PING_PONG__ALL_BUT_EP0)) + //Point to the next buffer for ping pong purposes. UOWN getting cleared + //(either due to SIE clearing it after a transaction, or the firmware + //clearing it) makes hardware ping pong pointer advance. + pBDTEntryIn[endpoint] = (BDT_ENTRY*)(((uintptr_t)pBDTEntryIn[endpoint]) ^ USB_NEXT_PING_PONG); + + pBDTEntryIn[endpoint]->STAT.Val &= _DTSMASK; + pBDTEntryIn[endpoint]->STAT.Val ^= _DTSMASK; + #endif + } +} + +/************************************************************************** + Function: + void USBDeviceDetach(void) + + Summary: + This function configures the USB module to "soft detach" itself from + the USB host. + + Description: + This function configures the USB module to perform a "soft detach" + operation, by disabling the D+ (or D-) ~1.5k pull up resistor, which + lets the host know the device is present and attached. This will make + the host think that the device has been unplugged. This is potentially + useful, as it allows the USB device to force the host to re-enumerate + the device (on the firmware has re-enabled the USB module/pull up, by + calling USBDeviceAttach(), to "soft re-attach" to the host). + + Precondition: + Should only be called when USB_INTERRUPT is defined. See remarks + section if USB_POLLING mode option is being used (usb_config.h option). + + Additionally, this function should only be called from the main() loop + context. Do not call this function from within an interrupt handler, as + this function may modify global interrupt enable bits and settings. + + Parameters: + None + + Return Values: + None + + Remarks: + If the application firmware calls USBDeviceDetach(), it is strongly + recommended that the firmware wait at least >= 80ms before calling + USBDeviceAttach(). If the firmware performs a soft detach, and then + re-attaches too soon (ex: after a few micro seconds for instance), some + hosts may interpret this as an unexpected "glitch" rather than as a + physical removal/re-attachment of the USB device. In this case the host + may simply ignore the event without re-enumerating the device. To + ensure that the host properly detects and processes the device soft + detach/re-attach, it is recommended to make sure the device remains + detached long enough to mimic a real human controlled USB + unplug/re-attach event (ex: after calling USBDeviceDetach(), do not + call USBDeviceAttach() for at least 80+ms, preferably longer. + + Neither the USBDeviceDetach() or USBDeviceAttach() functions are blocking + or take long to execute. It is the application firmwares + responsibility for adding the 80+ms delay, when using these API + functions. + + Note: The Windows plug and play event handler processing is fairly + slow, especially in certain versions of Windows, and for certain USB + device classes. It has been observed that some device classes need to + provide even more USB detach dwell interval (before calling + USBDeviceAttach()), in order to work correctly after re-enumeration. + If the USB device is a CDC class device, it is recommended to wait + at least 1.5 seconds or longer, before soft re-attaching to the host, + to provide the plug and play event handler enough time to finish + processing the removal event, before the re-attach occurs. + + If the application is using the USB_POLLING mode option, then the + USBDeviceDetach() and USBDeviceAttach() functions are not available. + In this mode, the USB stack relies on the "#define USE_USB_BUS_SENSE_IO" + and "#define USB_BUS_SENSE" options in the + HardwareProfile – [platform name].h file. + + When using the USB_POLLING mode option, and the + "#define USE_USB_BUS_SENSE_IO" definition has been commented out, then + the USB stack assumes that it should always enable the USB module at + pretty much all times. Basically, anytime the application firmware + calls USBDeviceTasks(), the firmware will automatically enable the USB + module. This mode would typically be selected if the application was + designed to be a purely bus powered device. In this case, the + application is powered from the +5V VBUS supply from the USB port, so + it is correct and sensible in this type of application to power up and + turn on the USB module, at anytime that the microcontroller is + powered (which implies the USB cable is attached and the host is also + powered). + + In a self powered application, the USB stack is designed with the + intention that the user will enable the "#define USE_USB_BUS_SENSE_IO" + option in the HardwareProfile – [platform name].h file. When this + option is defined, then the USBDeviceTasks() function will automatically + check the I/O pin port value of the designated pin (based on the + #define USB_BUS_SENSE option in the HardwareProfile – [platform name].h + file), every time the application calls USBDeviceTasks(). If the + USBDeviceTasks() function is executed and finds that the pin defined by + the #define USB_BUS_SENSE is in a logic low state, then it will + automatically disable the USB module and tri-state the D+ and D- pins. + If however the USBDeviceTasks() function is executed and finds the pin + defined by the #define USB_BUS_SENSE is in a logic high state, then it + will automatically enable the USB module, if it has not already been + enabled. + + **************************************************************************/ +#if defined(USB_INTERRUPT) +void USBDeviceDetach(void) +{ + //If the interrupt option is selected then the customer is required + // to notify the stack when the device is attached or removed from the + // bus by calling the USBDeviceAttach() and USBDeviceDetach() functions. +#ifdef USB_SUPPORT_OTG + if (USB_BUS_SENSE != 1) +#endif + { + // Disable module & detach from bus + U1CON = 0; + + // Mask all USB interrupts + U1IE = 0; + + //Move to the detached state + USBDeviceState = DETACHED_STATE; + + #ifdef USB_SUPPORT_OTG + //Disable D+ Pull-up + U1OTGCONbits.DPPULUP = 0; + + //Disable HNP + USBOTGDisableHnp(); + + //Deactivate HNP + USBOTGDeactivateHnp(); + + //If ID Pin Changed State + if (USBIDIF && USBIDIE) + { + //Re-detect & Initialize + USBOTGInitialize(); + + //Clear ID Interrupt Flag + USBClearInterruptFlag(USBIDIFReg,USBIDIFBitNum); + } + #endif + + #if defined __C30__ || defined __XC16__ + //USBClearInterruptFlag(U1OTGIR, 3); + #endif + //return so that we don't go through the rest of + //the state machine + return; + } + +#ifdef USB_SUPPORT_OTG + //If Session Is Started Then + else + { + //If SRP Is Ready + if (USBOTGSRPIsReady()) + { + //Clear SRPReady + USBOTGClearSRPReady(); + + //Clear SRP Timeout Flag + USBOTGClearSRPTimeOutFlag(); + + //Indicate Session Started + UART2PrintString( "\r\n***** USB OTG B Event - Session Started *****\r\n" ); + } + } +#endif +} +#endif //#if defined(USB_INTERRUPT) +/************************************************************************** + Function: + void USBDeviceAttach(void) + + Summary: + Checks if VBUS is present, and that the USB module is not already + initialized, and if so, enables the USB module so as to signal device + attachment to the USB host. + + Description: + This function indicates to the USB host that the USB device has been + attached to the bus. This function needs to be called in order for the + device to start to enumerate on the bus. + + Precondition: + Should only be called when USB_INTERRUPT is defined. Also, should only + be called from the main() loop context. Do not call USBDeviceAttach() + from within an interrupt handler, as the USBDeviceAttach() function + may modify global interrupt enable bits and settings. + + For normal USB devices: + Make sure that if the module was previously on, that it has been turned off + for a long time (ex: 100ms+) before calling this function to re-enable the module. + If the device turns off the D+ (for full speed) or D- (for low speed) ~1.5k ohm + pull up resistor, and then turns it back on very quickly, common hosts will sometimes + reject this event, since no human could ever unplug and re-attach a USB device in a + microseconds (or nanoseconds) timescale. The host could simply treat this as some kind + of glitch and ignore the event altogether. + Parameters: + None + + Return Values: + None + + Remarks: + See also the USBDeviceDetach() API function documentation. +****************************************************************************/ +#if defined(USB_INTERRUPT) +void USBDeviceAttach(void) +{ + //if we are in the detached state + if(USBDeviceState == DETACHED_STATE) + { + if(USB_BUS_SENSE == 1) + { + //Initialize registers to known states. + U1CON = 0; + + // Mask all USB interrupts + U1IE = 0; + + //Configure things like: pull ups, full/low-speed mode, + //set the ping pong mode, and set internal transceiver + SetConfigurationOptions(); + + USBEnableInterrupts(); //Modifies global interrupt settings + + // Enable module & attach to bus + while(!U1CONbits.USBEN){U1CONbits.USBEN = 1;} + + //moved to the attached state + USBDeviceState = ATTACHED_STATE; + + #ifdef USB_SUPPORT_OTG + U1OTGCON = USB_OTG_DPLUS_ENABLE | USB_OTG_ENABLE; + #endif + } + } +} +#endif //#if defined(USB_INTERRUPT) + + +/******************************************************************************* + Function: void USBCtrlEPAllowStatusStage(void); + + Summary: This function prepares the proper endpoint 0 IN or endpoint 0 OUT + (based on the controlTransferState) to allow the status stage packet + of a control transfer to complete. This function gets used + internally by the USB stack itself, but it may also be called from + the application firmware, IF the application firmware called + the USBDeferStatusStage() function during the initial processing + of the control transfer request. In this case, the application + must call the USBCtrlEPAllowStatusStage() once, after it has fully + completed processing and handling the data stage portion of the + request. + + If the application firmware has no need for delaying control + transfers, and therefore never calls USBDeferStatusStage(), then the + application firmware should not call USBCtrlEPAllowStatusStage(). + + Description: + + Conditions: + None + + Input: + + Return: + + Remarks: + None + *****************************************************************************/ +void USBCtrlEPAllowStatusStage(void) +{ + //Check and set two flags, prior to actually modifying any BDT entries. + //This double checking is necessary to make certain that + //USBCtrlEPAllowStatusStage() can be called twice simultaneously (ex: once + //in main loop context, while simultaneously getting an interrupt which + //tries to call USBCtrlEPAllowStatusStage() again, at the same time). + if(USBStatusStageEnabledFlag1 == false) + { + USBStatusStageEnabledFlag1 = true; + if(USBStatusStageEnabledFlag2 == false) + { + USBStatusStageEnabledFlag2 = true; + + //Determine which endpoints (EP0 IN or OUT needs arming for the status + //stage), based on the type of control transfer currently pending. + if(controlTransferState == CTRL_TRF_RX) + { + pBDTEntryIn[0]->CNT = 0; + pBDTEntryIn[0]->STAT.Val = _DAT1|(_DTSEN & _DTS_CHECKING_ENABLED); + pBDTEntryIn[0]->STAT.Val |= _USIE; + } + else if(controlTransferState == CTRL_TRF_TX) + { + BothEP0OutUOWNsSet = false; //Indicator flag used in USBCtrlTrfOutHandler() + + //This buffer (when ping pong buffering is enabled on EP0 OUT) receives the + //next SETUP packet. + #if((USB_PING_PONG_MODE == USB_PING_PONG__EP0_OUT_ONLY) || (USB_PING_PONG_MODE == USB_PING_PONG__FULL_PING_PONG)) + pBDTEntryEP0OutCurrent->CNT = USB_EP0_BUFF_SIZE; + pBDTEntryEP0OutCurrent->ADR = ConvertToPhysicalAddress(&SetupPkt); + pBDTEntryEP0OutCurrent->STAT.Val = _BSTALL; //Prepare endpoint to accept a SETUP transaction + pBDTEntryEP0OutCurrent->STAT.Val |= _USIE; + BothEP0OutUOWNsSet = true; //Indicator flag used in USBCtrlTrfOutHandler() + #endif + + //This EP0 OUT buffer receives the 0-byte OUT status stage packet. + pBDTEntryEP0OutNext->CNT = USB_EP0_BUFF_SIZE; + pBDTEntryEP0OutNext->ADR = ConvertToPhysicalAddress(&SetupPkt); + pBDTEntryEP0OutNext->STAT.Val = _USIE; // Note: DTSEN is 0 + } + } + } +} + + +/******************************************************************************* + Function: void USBCtrlEPAllowDataStage(void); + + Summary: This function allows the data stage of either a host-to-device or + device-to-host control transfer (with data stage) to complete. + This function is meant to be used in conjunction with either the + USBDeferOUTDataStage() or USBDeferINDataStage(). If the firmware + does not call either USBDeferOUTDataStage() or USBDeferINDataStage(), + then the firmware does not need to manually call + USBCtrlEPAllowDataStage(), as the USB stack will call this function + instead. + + Description: + + Conditions: A control transfer (with data stage) should already be pending, + if the firmware calls this function. Additionally, the firmware + should have called either USBDeferOUTDataStage() or + USBDeferINDataStage() at the start of the control transfer, if + the firmware will be calling this function manually. + + Input: + + Return: + + Remarks: + *****************************************************************************/ +void USBCtrlEPAllowDataStage(void) +{ + USBDeferINDataStagePackets = false; + USBDeferOUTDataStagePackets = false; + + if(controlTransferState == CTRL_TRF_RX) //(...) + { + //Prepare EP0 OUT to receive the first OUT data packet in the data stage sequence. + pBDTEntryEP0OutNext->CNT = USB_EP0_BUFF_SIZE; + pBDTEntryEP0OutNext->ADR = ConvertToPhysicalAddress(&CtrlTrfData); + pBDTEntryEP0OutNext->STAT.Val = _DAT1|(_DTSEN & _DTS_CHECKING_ENABLED); + pBDTEntryEP0OutNext->STAT.Val |= _USIE; + } + else //else must be controlTransferState == CTRL_TRF_TX (...) + { + //Error check the data stage byte count. Make sure the user specified + //value was no greater than the number of bytes the host requested. + if(SetupPkt.wLength < inPipes[0].wCount.Val) + { + inPipes[0].wCount.Val = SetupPkt.wLength; + } + USBCtrlTrfTxService(); //Copies one IN data packet worth of data from application buffer + //to CtrlTrfData buffer. Also keeps track of how many bytes remaining. + + //Cnt should have been initialized by responsible request owner (ex: by + //using the USBEP0SendRAMPtr() or USBEP0SendROMPtr() API function). + pBDTEntryIn[0]->ADR = ConvertToPhysicalAddress(&CtrlTrfData); + pBDTEntryIn[0]->STAT.Val = _DAT1|(_DTSEN & _DTS_CHECKING_ENABLED); + pBDTEntryIn[0]->STAT.Val |= _USIE; + } +} + + +/******************************************************************************/ +/** Internal Functions *********************************************************/ +/******************************************************************************/ + +/******************************************************************** + * Function: void USBConfigureEndpoint(uint8_t EPNum, uint8_t direction) + * + * PreCondition: None + * + * Input: uint8_t EPNum - the endpoint to be configured + * uint8_t direction - the direction to be configured + * (either OUT_FROM_HOST or IN_TO_HOST) + * + * Output: None + * + * Side Effects: None + * + * Overview: This function will configure the specified + * endpoint + * + * Note: None + *******************************************************************/ +static void USBConfigureEndpoint(uint8_t EPNum, uint8_t direction) +{ + volatile BDT_ENTRY* handle; + + //Compute a pointer to the even BDT entry corresponding to the + //EPNum and direction values passed to this function. + handle = (volatile BDT_ENTRY*)&BDT[EP0_OUT_EVEN]; //Get address of start of BDT + handle += EP(EPNum,direction,0u); //Add in offset to the BDT of interest + + handle->STAT.UOWN = 0; //mostly redundant, since USBStdSetCfgHandler() + //already cleared the entire BDT table + + //Make sure our pBDTEntryIn/Out[] pointer is initialized. Needed later + //for USBTransferOnePacket() API calls. + if(direction == OUT_FROM_HOST) + { + pBDTEntryOut[EPNum] = handle; + } + else + { + pBDTEntryIn[EPNum] = handle; + } + + #if (USB_PING_PONG_MODE == USB_PING_PONG__FULL_PING_PONG) + handle->STAT.DTS = 0; + (handle+1)->STAT.DTS = 1; + #elif (USB_PING_PONG_MODE == USB_PING_PONG__NO_PING_PONG) + //Set DTS to one because the first thing we will do + //when transmitting is toggle the bit + handle->STAT.DTS = 1; + #elif (USB_PING_PONG_MODE == USB_PING_PONG__EP0_OUT_ONLY) + if(EPNum != 0) + { + handle->STAT.DTS = 1; + } + #elif (USB_PING_PONG_MODE == USB_PING_PONG__ALL_BUT_EP0) + if(EPNum != 0) + { + handle->STAT.DTS = 0; + (handle+1)->STAT.DTS = 1; + } + #endif +} + + +/****************************************************************************** + * Function: void USBCtrlEPServiceComplete(void) + * + * PreCondition: None + * + * Input: None + * + * Output: None + * + * Side Effects: None + * + * Overview: This routine wrap up the remaining tasks in servicing + * a Setup Request. Its main task is to set the endpoint + * controls appropriately for a given situation. See code + * below. + * There are three main scenarios: + * a) There was no handler for the Request, in this case + * a STALL should be sent out. + * b) The host has requested a read control transfer, + * endpoints are required to be setup in a specific way. + * c) The host has requested a write control transfer, or + * a control data stage is not required, endpoints are + * required to be setup in a specific way. + * + * Packet processing is resumed by clearing PKTDIS bit. + * + * Note: None + *****************************************************************************/ +static void USBCtrlEPServiceComplete(void) +{ + /* + * PKTDIS bit is set when a Setup Transaction is received. + * Clear to resume packet processing. + */ + USBPacketDisable = 0; + + //Check the busy bits and the SetupPtk.DataDir variables to determine what type of + //control transfer is currently in progress. We need to know the type of control + //transfer that is currently pending, in order to know how to properly arm the + //EP0 IN and EP0 OUT endpoints. + if(inPipes[0].info.bits.busy == 0) + { + if(outPipes[0].info.bits.busy == 1) + { + controlTransferState = CTRL_TRF_RX; + /* + * Control Write: + * ... | + */ + + //1. Prepare OUT EP to receive data, unless a USB class request handler + // function decided to defer the data stage (ex: because the intended + // RAM buffer wasn't available yet) by calling USBDeferDataStage(). + // If it did so, it is then responsible for calling USBCtrlEPAllowDataStage(), + // once it is ready to begin receiving the data. + if(USBDeferOUTDataStagePackets == false) + { + USBCtrlEPAllowDataStage(); + } + + //2. IN endpoint 0 status stage will be armed by USBCtrlEPAllowStatusStage() + //after all of the OUT data has been received and consumed, or if a timeout occurs. + USBStatusStageEnabledFlag2 = false; + USBStatusStageEnabledFlag1 = false; + } + else + { + /* + * If no one knows how to service this request then stall. + * Must also prepare EP0 to receive the next SETUP transaction. + */ + pBDTEntryEP0OutNext->CNT = USB_EP0_BUFF_SIZE; + pBDTEntryEP0OutNext->ADR = ConvertToPhysicalAddress(&SetupPkt); + pBDTEntryEP0OutNext->STAT.Val = _DAT0|(_DTSEN & _DTS_CHECKING_ENABLED)|_BSTALL; + pBDTEntryEP0OutNext->STAT.Val |= _USIE; + pBDTEntryIn[0]->STAT.Val = _BSTALL; + pBDTEntryIn[0]->STAT.Val |= _USIE; + } + } + else // A module has claimed ownership of the control transfer session. + { + if(SetupPkt.DataDir == USB_SETUP_DEVICE_TO_HOST_BITFIELD) + { + controlTransferState = CTRL_TRF_TX; + /* + * Control Read: + * ... | + * + * 1. Prepare IN EP to transfer data to the host. If however the data + * wasn't ready yet (ex: because the firmware needs to go and read it from + * some slow/currently unavailable resource, such as an external I2C EEPconst), + * Then the class request handler responsible should call the USBDeferDataStage() + * macro. In this case, the firmware may wait up to 500ms, before it is required + * to transmit the first IN data packet. Once the data is ready, and the firmware + * is ready to begin sending the data, it should then call the + * USBCtrlEPAllowDataStage() function to start the data stage. + */ + if(USBDeferINDataStagePackets == false) + { + USBCtrlEPAllowDataStage(); + } + + // 2. (Optionally) allow the status stage now, to prepare for early termination. + // Note: If a class request handler decided to set USBDeferStatusStagePacket == true, + // then it is responsible for eventually calling USBCtrlEPAllowStatusStage() once it + // is ready. If the class request handler does this, it needs to be careful to + // be written so that it can handle the early termination scenario. + // Ex: It should call USBCtrlEPAllowStatusStage() when any of the following occurs: + // 1. The desired total number of bytes were sent to the host. + // 2. The number of bytes that the host originally requested (in the SETUP packet that + // started the control transfer) has been reached. + // 3. Or, if a timeout occurs (ex: <50ms since the last successful EP0 IN transaction), regardless + // of how many bytes have actually been sent. This is necessary to prevent a deadlock situation + // (where the control transfer can't complete, due to continuous NAK on status stage) if the + // host performs early termination. If enabled, the USB_ENABLE_STATUS_STAGE_TIMEOUTS usb_config.h + // option can take care of this for you. + // Note: For this type of control transfer, there is normally no harm in simply arming the + // status stage packet right now, even if the IN data is not ready yet. This allows for + // immediate early termination, without adding unnecessary delay. Therefore, it is generally not + // recommended for the USB class handler firmware to call USBDeferStatusStage(), for this + // type of control transfer. If the USB class handler firmware needs more time to fetch the IN + // data that needs to be sent to the host, it should instead use the USBDeferDataStage() function. + USBStatusStageEnabledFlag2 = false; + USBStatusStageEnabledFlag1 = false; + if(USBDeferStatusStagePacket == false) + { + USBCtrlEPAllowStatusStage(); + } + } + else // (SetupPkt.DataDir == USB_SETUP_DIRECTION_HOST_TO_DEVICE) + { + //This situation occurs for special types of control transfers, + //such as that which occurs when the host sends a SET_ADDRESS + //control transfer. Ex: + // + // | + + //Although the data direction is HOST_TO_DEVICE, there is no data stage + //(hence: outPipes[0].info.bits.busy == 0). There is however still + //an IN status stage. + + controlTransferState = CTRL_TRF_RX; //Since this is a HOST_TO_DEVICE control transfer + + //1. Prepare OUT EP to receive the next SETUP packet. + pBDTEntryEP0OutNext->CNT = USB_EP0_BUFF_SIZE; + pBDTEntryEP0OutNext->ADR = ConvertToPhysicalAddress(&SetupPkt); + pBDTEntryEP0OutNext->STAT.Val = _BSTALL; + pBDTEntryEP0OutNext->STAT.Val |= _USIE; + + //2. Prepare for IN status stage of the control transfer + USBStatusStageEnabledFlag2 = false; + USBStatusStageEnabledFlag1 = false; + if(USBDeferStatusStagePacket == false) + { + USBCtrlEPAllowStatusStage(); + } + } + + }//end if(ctrl_trf_session_owner == MUID_NULL) + +}//end USBCtrlEPServiceComplete + + +/****************************************************************************** + * Function: void USBCtrlTrfTxService(void) + * + * PreCondition: pSrc, wCount, and usb_stat.ctrl_trf_mem are setup properly. + * + * Input: None + * + * Output: None + * + * Side Effects: None + * + * Overview: This routine is used for device to host control transfers + * (IN transactions). This function takes care of managing a + * transfer over multiple USB transactions. + * This routine should be called from only two places. + * One from USBCtrlEPServiceComplete() and one from + * USBCtrlTrfInHandler(). + * + * Note: + *****************************************************************************/ +static void USBCtrlTrfTxService(void) +{ + uint8_t byteToSend; + + //Figure out how many bytes of data to send in the next IN transaction. + //Assume a full size packet, unless otherwise determined below. + byteToSend = USB_EP0_BUFF_SIZE; + if(inPipes[0].wCount.Val < (uint8_t)USB_EP0_BUFF_SIZE) + { + byteToSend = inPipes[0].wCount.Val; + + //Keep track of whether or not we have sent a "short packet" yet. + //This is useful so that later on, we can configure EP0 IN to STALL, + //after we have sent all of the intended data. This makes sure the + //hardware STALLs if the host erroneously tries to send more IN token + //packets, requesting more data than intended in the control transfer. + if(shortPacketStatus == SHORT_PKT_NOT_USED) + { + shortPacketStatus = SHORT_PKT_PENDING; + } + else if(shortPacketStatus == SHORT_PKT_PENDING) + { + shortPacketStatus = SHORT_PKT_SENT; + } + } + + //Keep track of how many bytes remain to be sent in the transfer, by + //subtracting the number of bytes about to be sent from the total. + inPipes[0].wCount.Val -= byteToSend; + + //Next, load the number of bytes to send to BC7..0 in buffer descriptor. + //Note: Control endpoints may never have a max packet size of > 64 bytes. + //Therefore, the BC8 and BC9 bits should always be maintained clear. + pBDTEntryIn[0]->CNT = byteToSend; + + //Now copy the data from the source location, to the CtrlTrfData[] buffer, + //which we will send to the host. + pDst = (USB_VOLATILE uint8_t*)CtrlTrfData; // Set destination pointer + if(inPipes[0].info.bits.ctrl_trf_mem == USB_EP0_ROM) // Determine type of memory source + { + while(byteToSend) + { + *pDst++ = *inPipes[0].pSrc.bRom++; + byteToSend--; + }//end while(byte_to_send.Val) + } + else // RAM + { + while(byteToSend) + { + *pDst++ = *inPipes[0].pSrc.bRam++; + byteToSend--; + }//end while(byte_to_send.Val) + }//end if(usb_stat.ctrl_trf_mem == _const) +}//end USBCtrlTrfTxService + +/****************************************************************************** + * Function: void USBCtrlTrfRxService(void) + * + * PreCondition: pDst and wCount are setup properly. + * pSrc is always &CtrlTrfData + * usb_stat.ctrl_trf_mem is always USB_EP0_RAM. + * wCount should be set to 0 at the start of each control + * transfer. + * + * Input: None + * + * Output: None + * + * Side Effects: None + * + * Overview: This routine is used for host to device control transfers + * (uses OUT transactions). This function receives the data that arrives + * on EP0 OUT, and copies it into the appropriate outPipes[0].pDst.bRam + * buffer. Once the host has sent all the data it was intending + * to send, this function will call the appropriate outPipes[0].pFunc() + * handler (unless it is NULL), so that it can be used by the + * intended target firmware. + * + * Note: None + *****************************************************************************/ +static void USBCtrlTrfRxService(void) +{ + uint8_t byteToRead; + uint8_t i; + + //Load byteToRead with the number of bytes the host just sent us in the + //last OUT transaction. + byteToRead = pBDTEntryEP0OutCurrent->CNT; + + //Update the "outPipes[0].wCount.Val", which keeps track of the total number + //of remaining bytes expected to be received from the host, in the control + //transfer. First check to see if the host sent us more bytes than the + //application firmware was expecting to receive. + if(byteToRead > outPipes[0].wCount.Val) + { + byteToRead = outPipes[0].wCount.Val; + } + //Reduce the number of remaining bytes by the number we just received. + outPipes[0].wCount.Val -= byteToRead; + + //Copy the OUT DATAx packet bytes that we just received from the host, + //into the user application buffer space. + for(i=0;i 0) + { + pBDTEntryEP0OutNext->CNT = USB_EP0_BUFF_SIZE; + pBDTEntryEP0OutNext->ADR = ConvertToPhysicalAddress(&CtrlTrfData); + if(pBDTEntryEP0OutCurrent->STAT.DTS == 0) + { + pBDTEntryEP0OutNext->STAT.Val = _DAT1|(_DTSEN & _DTS_CHECKING_ENABLED); + pBDTEntryEP0OutNext->STAT.Val |= _USIE; + } + else + { + pBDTEntryEP0OutNext->STAT.Val = _DAT0|(_DTSEN & _DTS_CHECKING_ENABLED); + pBDTEntryEP0OutNext->STAT.Val |= _USIE; + } + } + else + { + //We have received all OUT packets that we were expecting to + //receive for the control transfer. Prepare EP0 OUT to receive + //the next SETUP transaction that may arrive. + pBDTEntryEP0OutNext->CNT = USB_EP0_BUFF_SIZE; + pBDTEntryEP0OutNext->ADR = ConvertToPhysicalAddress(&SetupPkt); + //Configure EP0 OUT to receive the next SETUP transaction for any future + //control transfers. However, set BSTALL in case the host tries to send + //more data than it claims it was going to send. + pBDTEntryEP0OutNext->STAT.Val = _BSTALL; + pBDTEntryEP0OutNext->STAT.Val |= _USIE; + + //All data bytes for the host to device control write (OUT) have now been + //received successfully. + //Go ahead and call the user specified callback function, to use/consume + //the control transfer data (ex: if the "void (*function)" parameter + //was non-NULL when USBEP0Receive() was called). + if(outPipes[0].pFunc != NULL) + { + #if defined(__XC8) + //Special pragmas to suppress an expected/harmless warning + //message when building with the XC8 compiler + #pragma warning push + #pragma warning disable 1088 + outPipes[0].pFunc(); //Call the user's callback function + #pragma warning pop + #else + outPipes[0].pFunc(); //Call the user's callback function + #endif + } + outPipes[0].info.bits.busy = 0; + + //Ready to arm status stage IN transaction now, if the application + //firmware has completed processing the request. If it is still busy + //and needs more time to finish handling the request, then the user + //callback (the one called by the outPipes[0].pFunc();) should set the + //USBDeferStatusStagePacket to true (by calling USBDeferStatusStage()). In + //this case, it is the application's firmware responsibility to call + //the USBCtrlEPAllowStatusStage() function, once it is fully done handling the request. + //Note: The application firmware must process the request and call + //USBCtrlEPAllowStatusStage() in a semi-timely fashion. "Semi-timely" + //means either 50ms, 500ms, or 5 seconds, depending on the type of + //control transfer. See the USB 2.0 specification section 9.2.6 for + //more details. + if(USBDeferStatusStagePacket == false) + { + USBCtrlEPAllowStatusStage(); + } + } + +}//end USBCtrlTrfRxService + + +/******************************************************************** + * Function: void USBStdSetCfgHandler(void) + * + * PreCondition: None + * + * Input: None + * + * Output: None + * + * Side Effects: None + * + * Overview: This routine first disables all endpoints by + * clearing UEP registers. It then configures + * (initializes) endpoints by calling the callback + * function USBCBInitEP(). + * + * Note: None + *******************************************************************/ +static void USBStdSetCfgHandler(void) +{ + uint8_t i; + + // This will generate a zero length packet + inPipes[0].info.bits.busy = 1; + + //Clear all of the endpoint control registers + DisableNonZeroEndpoints(USB_MAX_EP_NUMBER); + + //Clear all of the BDT entries + memset((void*)&BDT[0], 0x00, sizeof(BDT)); + + // Assert reset request to all of the Ping Pong buffer pointers + USBPingPongBufferReset = 1; + + //Re-Initialize all ping pong software state bits to 0 (which corresponds to + //the EVEN buffer being the next one that will be used), since we are also + //doing a hardware ping pong pointer reset above. + for(i = 0; i < (uint8_t)(USB_MAX_EP_NUMBER+1u); i++) + { + ep_data_in[i].Val = 0u; + ep_data_out[i].Val = 0u; + } + + //clear the alternate interface settings + memset((void*)&USBAlternateInterface,0x00,USB_MAX_NUM_INT); + + //Stop trying to reset ping pong buffer pointers + USBPingPongBufferReset = 0; + + pBDTEntryIn[0] = (volatile BDT_ENTRY*)&BDT[EP0_IN_EVEN]; + + //Set the next out to the current out packet + pBDTEntryEP0OutCurrent = (volatile BDT_ENTRY*)&BDT[EP0_OUT_EVEN]; + pBDTEntryEP0OutNext = pBDTEntryEP0OutCurrent; + + //set the current configuration + USBActiveConfiguration = SetupPkt.bConfigurationValue; + + //if the configuration value == 0 + if(USBActiveConfiguration == 0) + { + //Go back to the addressed state + USBDeviceState = ADDRESS_STATE; + } + else + { + //initialize the required endpoints + USB_SET_CONFIGURATION_HANDLER(EVENT_CONFIGURED,(void*)&USBActiveConfiguration,1); + + //Otherwise go to the configured state. Update the state variable last, + //after performing all of the set configuration related initialization + //tasks. + USBDeviceState = CONFIGURED_STATE; + }//end if(SetupPkt.bConfigurationValue == 0) +}//end USBStdSetCfgHandler + + +/******************************************************************** + * Function: void USBStdGetDscHandler(void) + * + * PreCondition: None + * + * Input: None + * + * Output: None + * + * Side Effects: None + * + * Overview: This routine handles the standard GET_DESCRIPTOR + * request. + * + * Note: None + *******************************************************************/ +static void USBStdGetDscHandler(void) +{ + if(SetupPkt.bmRequestType == 0x80) + { + inPipes[0].info.Val = USB_EP0_ROM | USB_EP0_BUSY | USB_EP0_INCLUDE_ZERO; + + switch(SetupPkt.bDescriptorType) + { + case USB_DESCRIPTOR_DEVICE: + #if !defined(USB_USER_DEVICE_DESCRIPTOR) + inPipes[0].pSrc.bRom = (const uint8_t*)&device_dsc; + #else + inPipes[0].pSrc.bRom = (const uint8_t*)USB_USER_DEVICE_DESCRIPTOR; + #endif + inPipes[0].wCount.Val = sizeof(device_dsc); + break; + case USB_DESCRIPTOR_CONFIGURATION: + //First perform error case check, to make sure the host is requesting a + //legal descriptor index. If the request index is illegal, don't do + //anything (so that the default STALL response will be sent). + if(SetupPkt.bDscIndex < USB_MAX_NUM_CONFIG_DSC) + { + #if !defined(USB_USER_CONFIG_DESCRIPTOR) + inPipes[0].pSrc.bRom = *(USB_CD_Ptr+SetupPkt.bDscIndex); + #else + inPipes[0].pSrc.bRom = *(USB_USER_CONFIG_DESCRIPTOR+SetupPkt.bDscIndex); + #endif + + //This must be loaded using byte addressing. The source pointer + // may not be word aligned for the 16 or 32 bit machines resulting + // in an address error on the dereference. + inPipes[0].wCount.byte.LB = *(inPipes[0].pSrc.bRom+2); + inPipes[0].wCount.byte.HB = *(inPipes[0].pSrc.bRom+3); + } + else + { + inPipes[0].info.Val = 0; + } + break; + case USB_DESCRIPTOR_STRING: + //USB_NUM_STRING_DESCRIPTORS was introduced as optional in release v2.3. In v2.4 and + // later it is now mandatory. This should be defined in usb_config.h and should + // indicate the number of string descriptors. + if(SetupPkt.bDscIndexSTAT.UOWN == 1) && (p->STAT.BSTALL == 1)) + CtrlTrfData[0]=0x01; // Set bit0 + break; + } + }//end switch + + if(inPipes[0].info.bits.busy == 1) + { + inPipes[0].pSrc.bRam = (uint8_t*)&CtrlTrfData; // Set Source + inPipes[0].info.bits.ctrl_trf_mem = USB_EP0_RAM; // Set memory type + inPipes[0].wCount.v[0] = 2; // Set data count + }//end if(...) +}//end USBStdGetStatusHandler + +/******************************************************************** + * Function: void USBStallHandler(void) + * + * PreCondition: None + * + * Input: None + * + * Output: None + * + * Side Effects: + * + * Overview: This function handles the event of a STALL + * occurring on the bus + * + * Note: None + *******************************************************************/ +static void USBStallHandler(void) +{ + /* + * Does not really have to do anything here, + * even for the control endpoint. + * All BDs of Endpoint 0 are owned by SIE right now, + * but once a Setup Transaction is received, the ownership + * for EP0_OUT will be returned to CPU. + * When the Setup Transaction is serviced, the ownership + * for EP0_IN will then be forced back to CPU by firmware. + */ + + if(U1EP0bits.EPSTALL == 1) + { + // UOWN - if 0, owned by CPU, if 1, owned by SIE + if((pBDTEntryEP0OutCurrent->STAT.Val == _USIE) && (pBDTEntryIn[0]->STAT.Val == (_USIE|_BSTALL))) + { + // Set ep0Bo to stall also + pBDTEntryEP0OutCurrent->STAT.Val = _DAT0|(_DTSEN & _DTS_CHECKING_ENABLED)|_BSTALL; + pBDTEntryEP0OutCurrent->STAT.Val |= _USIE; + }//end if + U1EP0bits.EPSTALL = 0; // Clear stall status + }//end if + + USBClearInterruptFlag(USBStallIFReg,USBStallIFBitNum); +} + +/******************************************************************** + * Function: void USBSuspend(void) + * + * PreCondition: None + * + * Input: None + * + * Output: None + * + * Side Effects: + * + * Overview: This function handles if the host tries to + * suspend the device + * + * Note: None + *******************************************************************/ +static void USBSuspend(void) +{ + /* + * NOTE: Do not clear UIRbits.ACTVIF here! + * Reason: + * ACTVIF is only generated once an IDLEIF has been generated. + * This is a 1:1 ratio interrupt generation. + * For every IDLEIF, there will be only one ACTVIF regardless of + * the number of subsequent bus transitions. + * + * If the ACTIF is cleared here, a problem could occur when: + * [ IDLE ][bus activity -> + * <--- 3 ms -----> ^ + * ^ ACTVIF=1 + * IDLEIF=1 + * # # # # (#=Program polling flags) + * ^ + * This polling loop will see both + * IDLEIF=1 and ACTVIF=1. + * However, the program services IDLEIF first + * because ACTIVIE=0. + * If this routine clears the only ACTIVIF, + * then it can never get out of the suspend + * mode. + */ + USBActivityIE = 1; // Enable bus activity interrupt + USBClearInterruptFlag(USBIdleIFReg,USBIdleIFBitNum); + + #if defined(__18CXX) || defined(_PIC14E) || defined(__XC8) + U1CONbits.SUSPND = 1; // Put USB module in power conserve + // mode, SIE clock inactive + #endif + USBBusIsSuspended = true; + USBTicksSinceSuspendEnd = 0; + + /* + * At this point the PIC can go into sleep,idle, or + * switch to a slower clock, etc. This should be done in the + * USBCBSuspend() if necessary. + */ + USB_SUSPEND_HANDLER(EVENT_SUSPEND,0,0); +} + +/******************************************************************** + * Function: void USBWakeFromSuspend(void) + * + * PreCondition: None + * + * Input: None + * + * Output: None + * + * Side Effects: None + * + * Overview: + * + * Note: None + *******************************************************************/ +static void USBWakeFromSuspend(void) +{ + USBBusIsSuspended = false; + + /* + * If using clock switching, the place to restore the original + * microcontroller core clock frequency is in the USBCBWakeFromSuspend() callback + */ + USB_WAKEUP_FROM_SUSPEND_HANDLER(EVENT_RESUME,0,0); + + #if defined(__18CXX) || defined(_PIC14E) || defined(__XC8) + //To avoid improperly clocking the USB module, make sure the oscillator + //settings are consistent with USB operation before clearing the SUSPND bit. + //Make sure the correct oscillator settings are selected in the + //"USB_WAKEUP_FROM_SUSPEND_HANDLER(EVENT_RESUME,0,0)" handler. + U1CONbits.SUSPND = 0; // Bring USB module out of power conserve + // mode. + #endif + + + USBActivityIE = 0; + + /******************************************************************** + Bug Fix: Feb 26, 2007 v2.1 + ********************************************************************* + The ACTVIF bit cannot be cleared immediately after the USB module wakes + up from Suspend or while the USB module is suspended. A few clock cycles + are required to synchronize the internal hardware state machine before + the ACTIVIF bit can be cleared by firmware. Clearing the ACTVIF bit + before the internal hardware is synchronized may not have an effect on + the value of ACTVIF. Additionally, if the USB module uses the clock from + the 96 MHz PLL source, then after clearing the SUSPND bit, the USB + module may not be immediately operational while waiting for the 96 MHz + PLL to lock. + ********************************************************************/ + + // UIRbits.ACTVIF = 0; // Removed + #if defined(__18CXX) || defined(__XC8) + while(USBActivityIF) + #endif + { + USBClearInterruptFlag(USBActivityIFReg,USBActivityIFBitNum); + } // Added + + USBTicksSinceSuspendEnd = 0; + +}//end USBWakeFromSuspend + +/******************************************************************** + * Function: void USBCtrlEPService(void) + * + * PreCondition: USTAT is loaded with a valid endpoint address. + * + * Input: None + * + * Output: None + * + * Side Effects: None + * + * Overview: USBCtrlEPService checks for three transaction + * types that it knows how to service and services + * them: + * 1. EP0 SETUP + * 2. EP0 OUT + * 3. EP0 IN + * It ignores all other types (i.e. EP1, EP2, etc.) + * + * Note: None + *******************************************************************/ +static void USBCtrlEPService(void) +{ + //If we get to here, that means a successful transaction has just occurred + //on EP0. This means "progress" has occurred in the currently pending + //control transfer, so we should re-initialize our timeout counter. + #if defined(USB_ENABLE_STATUS_STAGE_TIMEOUTS) + USBStatusStageTimeoutCounter = USB_STATUS_STAGE_TIMEOUT; + #endif + + //Check if the last transaction was on EP0 OUT endpoint (of any kind, to either the even or odd buffer if ping pong buffers used) + if((USTATcopy.Val & USTAT_EP0_PP_MASK) == USTAT_EP0_OUT_EVEN) + { + //Point to the EP0 OUT buffer of the buffer that arrived + #if defined (_PIC14E) || defined(__18CXX) || defined(__XC8) + pBDTEntryEP0OutCurrent = (volatile BDT_ENTRY*)&BDT[(USTATcopy.Val & USTAT_EP_MASK)>>1]; + #elif defined(__C30__) || defined(__C32__) || defined __XC16__ + pBDTEntryEP0OutCurrent = (volatile BDT_ENTRY*)&BDT[(USTATcopy.Val & USTAT_EP_MASK)>>2]; + #else + #error "unimplemented" + #endif + + //Set the next out to the current out packet + pBDTEntryEP0OutNext = pBDTEntryEP0OutCurrent; + //Toggle it to the next ping pong buffer (if applicable) + pBDTEntryEP0OutNext = (volatile BDT_ENTRY*)(((uintptr_t)pBDTEntryEP0OutNext) ^ USB_NEXT_EP0_OUT_PING_PONG); + + //If the current EP0 OUT buffer has a SETUP packet + if(pBDTEntryEP0OutCurrent->STAT.PID == PID_SETUP) + { + //The SETUP transaction data may have gone into the the CtrlTrfData + //buffer, or elsewhere, depending upon how the BDT was prepared + //before the transaction. Therefore, we should copy the data to the + //SetupPkt buffer so it can be processed correctly by USBCtrlTrfSetupHandler(). + memcpy((uint8_t*)&SetupPkt, (uint8_t*)ConvertToVirtualAddress(pBDTEntryEP0OutCurrent->ADR), 8); + + //Handle the control transfer (parse the 8-byte SETUP command and figure out what to do) + USBCtrlTrfSetupHandler(); + } + else + { + //Handle the DATA transfer + USBCtrlTrfOutHandler(); + } + } + else if((USTATcopy.Val & USTAT_EP0_PP_MASK) == USTAT_EP0_IN) + { + //Otherwise the transmission was and EP0 IN + // so take care of the IN transfer + USBCtrlTrfInHandler(); + } + +}//end USBCtrlEPService + +/******************************************************************** + * Function: void USBCtrlTrfSetupHandler(void) + * + * PreCondition: SetupPkt buffer is loaded with valid USB Setup Data + * + * Input: None + * + * Output: None + * + * Side Effects: None + * + * Overview: This routine is a task dispatcher and has 3 stages. + * 1. It initializes the control transfer state machine. + * 2. It calls on each of the module that may know how to + * service the Setup Request from the host. + * Module Example: USBD, HID, CDC, MSD, ... + * A callback function, USBCBCheckOtherReq(), + * is required to call other module handlers. + * 3. Once each of the modules has had a chance to check if + * it is responsible for servicing the request, stage 3 + * then checks direction of the transfer to determine how + * to prepare EP0 for the control transfer. + * Refer to USBCtrlEPServiceComplete() for more details. + * + * Note: Microchip USB Firmware has three different states for + * the control transfer state machine: + * 1. WAIT_SETUP + * 2. CTRL_TRF_TX (device sends data to host through IN transactions) + * 3. CTRL_TRF_RX (device receives data from host through OUT transactions) + * Refer to firmware manual to find out how one state + * is transitioned to another. + * + * A Control Transfer is composed of many USB transactions. + * When transferring data over multiple transactions, + * it is important to keep track of data source, data + * destination, and data count. These three parameters are + * stored in pSrc,pDst, and wCount. A flag is used to + * note if the data source is from const or RAM. + * + *******************************************************************/ +static void USBCtrlTrfSetupHandler(void) +{ + //-------------------------------------------------------------------------- + //1. Re-initialize state tracking variables related to control transfers. + //-------------------------------------------------------------------------- + shortPacketStatus = SHORT_PKT_NOT_USED; + USBDeferStatusStagePacket = false; + USBDeferINDataStagePackets = false; + USBDeferOUTDataStagePackets = false; + BothEP0OutUOWNsSet = false; + controlTransferState = WAIT_SETUP; + + //Abandon any previous control transfers that might have been using EP0. + //Ordinarily, nothing actually needs abandoning, since the previous control + //transfer would have completed successfully prior to the host sending the next + //SETUP packet. However, in a timeout error case, or after an EP0 STALL event, + //one or more UOWN bits might still be set. If so, we should clear the UOWN bits, + //so the EP0 IN/OUT endpoints are in a known inactive state, ready for re-arming + //by the class request handler that will be called next. + pBDTEntryIn[0]->STAT.Val &= ~(_USIE); + + pBDTEntryIn[0] = (volatile BDT_ENTRY*)(((uintptr_t)pBDTEntryIn[0]) ^ USB_NEXT_EP0_IN_PING_PONG); + pBDTEntryIn[0]->STAT.Val &= ~(_USIE); + pBDTEntryIn[0] = (volatile BDT_ENTRY*)(((uintptr_t)pBDTEntryIn[0]) ^ USB_NEXT_EP0_IN_PING_PONG); + pBDTEntryEP0OutNext->STAT.Val &= ~(_USIE); + + inPipes[0].info.Val = 0; + inPipes[0].wCount.Val = 0; + outPipes[0].info.Val = 0; + outPipes[0].wCount.Val = 0; + + + //-------------------------------------------------------------------------- + //2. Now find out what was in the SETUP packet, and begin handling the request. + //-------------------------------------------------------------------------- + USBCheckStdRequest(); //Check for standard USB "Chapter 9" requests. + USB_NONSTANDARD_EP0_REQUEST_HANDLER(EVENT_EP0_REQUEST,0,0); //Check for USB device class specific requests + + + //-------------------------------------------------------------------------- + //3. Re-arm EP0 IN and EP0 OUT endpoints, based on the control transfer in + // progress. If one of the above handlers (in step 2) knew how to process + // the request, it will have set one of the inPipes[0].info.bits.busy or + // outPipes[0].info.bits.busy flags = 1. This lets the + // USBCtrlEPServiceComplete() function know how and which endpoints to + // arm. If both info.bits.busy flags are = 0, then no one knew how to + // process the request. In this case, the default behavior will be to + // perform protocol STALL on EP0. + //-------------------------------------------------------------------------- + USBCtrlEPServiceComplete(); +}//end USBCtrlTrfSetupHandler + + +/****************************************************************************** + * Function: void USBCtrlTrfOutHandler(void) + * + * PreCondition: None + * + * Input: None + * + * Output: None + * + * Side Effects: None + * + * Overview: This routine handles an OUT transaction according to + * which control transfer state is currently active. + * + * Note: Note that if the the control transfer was from + * host to device, the session owner should be notified + * at the end of each OUT transaction to service the + * received data. + * + *****************************************************************************/ +static void USBCtrlTrfOutHandler(void) +{ + if(controlTransferState == CTRL_TRF_RX) + { + USBCtrlTrfRxService(); //Copies the newly received data into the appropriate buffer and configures EP0 OUT for next transaction. + } + else //In this case the last OUT transaction must have been a status stage of a CTRL_TRF_TX (... <-- this last OUT just occurred as the status stage) + { + //If the status stage is complete, this means we are done with the + //control transfer. Go back to the idle "WAIT_SETUP" state. + controlTransferState = WAIT_SETUP; + + //Prepare EP0 OUT for the next SETUP transaction, however, it may have + //already been prepared if ping-pong buffering was enabled on EP0 OUT, + //and the last control transfer was of direction: device to host, see + //USBCtrlEPServiceComplete(). If it was already prepared, do not want + //to do anything to the BDT. + if(BothEP0OutUOWNsSet == false) + { + pBDTEntryEP0OutNext->CNT = USB_EP0_BUFF_SIZE; + pBDTEntryEP0OutNext->ADR = ConvertToPhysicalAddress(&SetupPkt); + pBDTEntryEP0OutNext->STAT.Val = _DAT0|(_DTSEN & _DTS_CHECKING_ENABLED)|_BSTALL; + pBDTEntryEP0OutNext->STAT.Val |= _USIE; + } + else + { + BothEP0OutUOWNsSet = false; + } + } +} + +/****************************************************************************** + * Function: void USBCtrlTrfInHandler(void) + * + * PreCondition: None + * + * Input: None + * + * Output: None + * + * Side Effects: None + * + * Overview: This routine handles an IN transaction according to + * which control transfer state is currently active. + * + * Note: A Set Address Request must not change the actual address + * of the device until the completion of the control + * transfer. The end of the control transfer for Set Address + * Request is an IN transaction. Therefore it is necessary + * to service this unique situation when the condition is + * right. Macro mUSBCheckAdrPendingState is defined in + * usb9.h and its function is to specifically service this + * event. + *****************************************************************************/ +static void USBCtrlTrfInHandler(void) +{ + uint8_t lastDTS; + + lastDTS = pBDTEntryIn[0]->STAT.DTS; + + //switch to the next ping pong buffer + pBDTEntryIn[0] = (volatile BDT_ENTRY*)(((uintptr_t)pBDTEntryIn[0]) ^ USB_NEXT_EP0_IN_PING_PONG); + + //Must check if in ADR_PENDING_STATE. If so, we need to update the address + //now, since the IN status stage of the (set address) control transfer has + //evidently completed successfully. + if(USBDeviceState == ADR_PENDING_STATE) + { + U1ADDR = (SetupPkt.bDevADR & 0x7F); + if(U1ADDR != 0u) + { + USBDeviceState=ADDRESS_STATE; + } + else + { + USBDeviceState=DEFAULT_STATE; + } + }//end if + + + if(controlTransferState == CTRL_TRF_TX) + { + pBDTEntryIn[0]->ADR = ConvertToPhysicalAddress(CtrlTrfData); + USBCtrlTrfTxService(); + + //Check if we have already sent a short packet. If so, configure + //the endpoint to STALL in response to any further IN tokens (in the + //case that the host erroneously tries to receive more data than it + //should). + if(shortPacketStatus == SHORT_PKT_SENT) + { + // If a short packet has been sent, don't want to send any more, + // stall next time if host is still trying to read. + pBDTEntryIn[0]->STAT.Val = _BSTALL; + pBDTEntryIn[0]->STAT.Val |= _USIE; + } + else + { + if(lastDTS == 0) + { + pBDTEntryIn[0]->STAT.Val = _DAT1|(_DTSEN & _DTS_CHECKING_ENABLED); + pBDTEntryIn[0]->STAT.Val |= _USIE; + } + else + { + pBDTEntryIn[0]->STAT.Val = _DAT0|(_DTSEN & _DTS_CHECKING_ENABLED); + pBDTEntryIn[0]->STAT.Val |= _USIE; + } + }//end if(...)else + } + else // must have been a CTRL_TRF_RX status stage IN packet (... <-- this last IN just occurred as the status stage) + { + //if someone is still expecting data from the control transfer + // then make sure to terminate that request and let them know that + // they are done + if(outPipes[0].info.bits.busy == 1) + { + if(outPipes[0].pFunc != NULL) + { + outPipes[0].pFunc(); + } + outPipes[0].info.bits.busy = 0; + } + + controlTransferState = WAIT_SETUP; + //Don't need to arm EP0 OUT here. It was already armed by the last that + //got processed by the USBCtrlTrfRxService() handler. + } + +} + + +/******************************************************************** + * Function: void USBCheckStdRequest(void) + * + * PreCondition: None + * + * Input: None + * + * Output: None + * + * Side Effects: None + * + * Overview: This routine checks the setup data packet to see + * if it knows how to handle it + * + * Note: None + *******************************************************************/ +static void USBCheckStdRequest(void) +{ + if(SetupPkt.RequestType != USB_SETUP_TYPE_STANDARD_BITFIELD) return; + + switch(SetupPkt.bRequest) + { + case USB_REQUEST_SET_ADDRESS: + inPipes[0].info.bits.busy = 1; // This will generate a zero length packet + USBDeviceState = ADR_PENDING_STATE; // Update state only + /* See USBCtrlTrfInHandler() for the next step */ + break; + case USB_REQUEST_GET_DESCRIPTOR: + USBStdGetDscHandler(); + break; + case USB_REQUEST_SET_CONFIGURATION: + USBStdSetCfgHandler(); + break; + case USB_REQUEST_GET_CONFIGURATION: + inPipes[0].pSrc.bRam = (uint8_t*)&USBActiveConfiguration; // Set Source + inPipes[0].info.bits.ctrl_trf_mem = USB_EP0_RAM; // Set memory type + inPipes[0].wCount.v[0] = 1; // Set data count + inPipes[0].info.bits.busy = 1; + break; + case USB_REQUEST_GET_STATUS: + USBStdGetStatusHandler(); + break; + case USB_REQUEST_CLEAR_FEATURE: + case USB_REQUEST_SET_FEATURE: + USBStdFeatureReqHandler(); + break; + case USB_REQUEST_GET_INTERFACE: + inPipes[0].pSrc.bRam = (uint8_t*)&USBAlternateInterface[SetupPkt.bIntfID]; // Set source + inPipes[0].info.bits.ctrl_trf_mem = USB_EP0_RAM; // Set memory type + inPipes[0].wCount.v[0] = 1; // Set data count + inPipes[0].info.bits.busy = 1; + break; + case USB_REQUEST_SET_INTERFACE: + inPipes[0].info.bits.busy = 1; + USBAlternateInterface[SetupPkt.bIntfID] = SetupPkt.bAltID; + break; + case USB_REQUEST_SET_DESCRIPTOR: + USB_SET_DESCRIPTOR_HANDLER(EVENT_SET_DESCRIPTOR,0,0); + break; + case USB_REQUEST_SYNCH_FRAME: + default: + break; + }//end switch +}//end USBCheckStdRequest + +/******************************************************************** + * Function: void USBStdFeatureReqHandler(void) + * + * PreCondition: None + * + * Input: None + * + * Output: Can alter BDT entries. Can also modify USB stack + * Maintained variables. + * + * Side Effects: None + * + * Overview: This routine handles the standard SET & CLEAR + * FEATURES requests + * + * Note: This is a private function, intended for internal + * use by the USB stack, when processing SET/CLEAR + * feature requests. + *******************************************************************/ +static void USBStdFeatureReqHandler(void) +{ + BDT_ENTRY *p; + EP_STATUS current_ep_data; + #if defined(__C32__) + uint32_t* pUEP; + #else + unsigned char* pUEP; + #endif + + + #ifdef USB_SUPPORT_OTG + //Check for USB On-The-Go (OTG) specific requests + if ((SetupPkt.bFeature == OTG_FEATURE_B_HNP_ENABLE)&& + (SetupPkt.Recipient == USB_SETUP_RECIPIENT_DEVICE_BITFIELD)) + { + inPipes[0].info.bits.busy = 1; + if(SetupPkt.bRequest == USB_REQUEST_SET_FEATURE) + USBOTGEnableHnp(); + else + USBOTGDisableHnp(); + } + + if ((SetupPkt.bFeature == OTG_FEATURE_A_HNP_SUPPORT)&& + (SetupPkt.Recipient == USB_SETUP_RECIPIENT_DEVICE_BITFIELD)) + { + inPipes[0].info.bits.busy = 1; + if(SetupPkt.bRequest == USB_REQUEST_SET_FEATURE) + USBOTGEnableSupportHnp(); + else + USBOTGDisableSupportHnp(); + } + + if ((SetupPkt.bFeature == OTG_FEATURE_A_ALT_HNP_SUPPORT)&& + (SetupPkt.Recipient == USB_SETUP_RECIPIENT_DEVICE_BITFIELD)) + { + inPipes[0].info.bits.busy = 1; + if(SetupPkt.bRequest == USB_REQUEST_SET_FEATURE) + USBOTGEnableAltHnp(); + else + USBOTGDisableAltHnp(); + } + #endif //#ifdef USB_SUPPORT_OTG + + //Check if the host sent a valid SET or CLEAR feature (remote wakeup) request. + if((SetupPkt.bFeature == USB_FEATURE_DEVICE_REMOTE_WAKEUP)&& + (SetupPkt.Recipient == USB_SETUP_RECIPIENT_DEVICE_BITFIELD)) + { + inPipes[0].info.bits.busy = 1; + if(SetupPkt.bRequest == USB_REQUEST_SET_FEATURE) + RemoteWakeup = true; + else + RemoteWakeup = false; + }//end if + + //Check if the host sent a valid SET or CLEAR endpoint halt request. + if((SetupPkt.bFeature == USB_FEATURE_ENDPOINT_HALT)&& + (SetupPkt.Recipient == USB_SETUP_RECIPIENT_ENDPOINT_BITFIELD)&& + (SetupPkt.EPNum != 0) && (SetupPkt.EPNum <= USB_MAX_EP_NUMBER)&& + (USBDeviceState == CONFIGURED_STATE)) + { + //The request was valid. Take control of the control transfer and + //perform the host requested action. + inPipes[0].info.bits.busy = 1; + + //Fetch a pointer to the BDT that the host wants to SET/CLEAR halt on. + if(SetupPkt.EPDir == OUT_FROM_HOST) + { + p = (BDT_ENTRY*)pBDTEntryOut[SetupPkt.EPNum]; + current_ep_data.Val = ep_data_out[SetupPkt.EPNum].Val; + } + else + { + p = (BDT_ENTRY*)pBDTEntryIn[SetupPkt.EPNum]; + current_ep_data.Val = ep_data_in[SetupPkt.EPNum].Val; + } + + //If ping pong buffering is enabled on the requested endpoint, need + //to point to the one that is the active BDT entry which the SIE will + //use for the next attempted transaction on that EP number. + #if (USB_PING_PONG_MODE == USB_PING_PONG__ALL_BUT_EP0) || (USB_PING_PONG_MODE == USB_PING_PONG__FULL_PING_PONG) + if(current_ep_data.bits.ping_pong_state == 0) //Check if even + { + p = (BDT_ENTRY*)(((uintptr_t)p) & (~USB_NEXT_PING_PONG)); + } + else //else must have been odd + { + p = (BDT_ENTRY*)(((uintptr_t)p) | USB_NEXT_PING_PONG); + } + #endif + + //Update the BDT pointers with the new, next entry based on the feature + // request + if(SetupPkt.EPDir == OUT_FROM_HOST) + { + pBDTEntryOut[SetupPkt.EPNum] = (volatile BDT_ENTRY *)p; + } + else + { + pBDTEntryIn[SetupPkt.EPNum] = (volatile BDT_ENTRY *)p; + } + + //Check if it was a SET_FEATURE endpoint halt request + if(SetupPkt.bRequest == USB_REQUEST_SET_FEATURE) + { + if(p->STAT.UOWN == 1) + { + //Mark that we are terminating this transfer and that the user + // needs to be notified later + if(SetupPkt.EPDir == OUT_FROM_HOST) + { + ep_data_out[SetupPkt.EPNum].bits.transfer_terminated = 1; + } + else + { + ep_data_in[SetupPkt.EPNum].bits.transfer_terminated = 1; + } + } + + //Then STALL the endpoint + p->STAT.Val |= _BSTALL; + p->STAT.Val |= _USIE; + }//if(SetupPkt.bRequest == USB_REQUEST_SET_FEATURE) + else + { + //Else the request must have been a CLEAR_FEATURE endpoint halt. + #if (USB_PING_PONG_MODE == USB_PING_PONG__ALL_BUT_EP0) || (USB_PING_PONG_MODE == USB_PING_PONG__FULL_PING_PONG) + //toggle over the to the non-active BDT + p = (BDT_ENTRY*)(((uintptr_t)p) ^ USB_NEXT_PING_PONG); + + if(p->STAT.UOWN == 1) + { + //Clear UOWN and set DTS state so it will be correct the next time + //the application firmware uses USBTransferOnePacket() on the EP. + p->STAT.Val &= (~_USIE); //Clear UOWN bit + p->STAT.Val |= _DAT1; //Set DTS to DATA1 + USB_TRANSFER_TERMINATED_HANDLER(EVENT_TRANSFER_TERMINATED,p,sizeof(p)); + } + else + { + //UOWN already clear, but still need to set DTS to DATA1 + p->STAT.Val |= _DAT1; + } + + //toggle back to the active BDT (the one the SIE is currently looking at + //and will use for the next successful transaction to take place on the EP + p = (BDT_ENTRY*)(((uintptr_t)p) ^ USB_NEXT_PING_PONG); + + //Check if we are currently terminating, or have previously terminated + //a transaction on the given endpoint. If so, need to clear UOWN, + //set DTS to the proper state, and call the application callback + //function. + if((current_ep_data.bits.transfer_terminated != 0) || (p->STAT.UOWN == 1)) + { + if(SetupPkt.EPDir == OUT_FROM_HOST) + { + ep_data_out[SetupPkt.EPNum].bits.transfer_terminated = 0; + } + else + { + ep_data_in[SetupPkt.EPNum].bits.transfer_terminated = 0; + } + //clear UOWN, clear DTS to DATA0, and finally remove the STALL condition + p->STAT.Val &= ~(_USIE | _DAT1 | _BSTALL); + //Call the application event handler callback function, so it can + //decide if the endpoint should get re-armed again or not. + USB_TRANSFER_TERMINATED_HANDLER(EVENT_TRANSFER_TERMINATED,p,sizeof(p)); + } + else + { + //clear UOWN, clear DTS to DATA0, and finally remove the STALL condition + p->STAT.Val &= ~(_USIE | _DAT1 | _BSTALL); + } + #else //else we must not be using ping-pong buffering on the requested endpoint + //Check if we need to call the user transfer terminated event callback function. + //We should call the callback, if the endpoint was previously terminated, + //or the endpoint is currently armed, and the host is performing clear + //endpoint halt, even though the endpoint wasn't stalled. + if((current_ep_data.bits.transfer_terminated != 0) || (p->STAT.UOWN == 1)) + { + //We are going to call the user transfer terminated callback. + //Clear the flag so we know we took care of it and don't need + //to call it again later. + if(SetupPkt.EPDir == OUT_FROM_HOST) + { + ep_data_out[SetupPkt.EPNum].bits.transfer_terminated = 0; + } + else + { + ep_data_in[SetupPkt.EPNum].bits.transfer_terminated = 0; + } + + //Clear UOWN and remove the STALL condition. + // In this case we also need to set the DTS bit to 1 so that + // it toggles to DATA0 the next time the application firmware + // calls USBTransferOnePacket() (or equivalent macro). + p->STAT.Val &= ~(_USIE | _BSTALL); + p->STAT.Val |= _DAT1; + //Let the application firmware know a transaction just + //got terminated by the host, and that it is now free to + //re-arm the endpoint or do other tasks if desired. + USB_TRANSFER_TERMINATED_HANDLER(EVENT_TRANSFER_TERMINATED,p,sizeof(p)); + } + else + { + //Clear UOWN and remove the STALL condition. + // In this case we also need to set the DTS bit to 1 so that + // it toggles to DATA0 the next time the application firmware + // calls USBTransferOnePacket() (or equivalent macro). + p->STAT.Val &= ~(_USIE | _BSTALL); + p->STAT.Val |= _DAT1; + } + #endif //end of #if (USB_PING_PONG_MODE == USB_PING_PONG__ALL_BUT_EP0) || (USB_PING_PONG_MODE == USB_PING_PONG__FULL_PING_PONG) + + //Get a pointer to the appropriate UEPn register + #if defined(__C32__) + pUEP = (uint32_t*)(&U1EP0); + pUEP += (SetupPkt.EPNum*4); + #else + pUEP = (unsigned char*)(&U1EP0+SetupPkt.EPNum); + #endif + + //Clear the STALL bit in the UEP register + *pUEP &= ~UEP_STALL; + }//end if(SetupPkt.bRequest == USB_REQUEST_SET_FEATURE) + }//end if (lots of checks for set/clear endpoint halt) +}//end USBStdFeatureReqHandler + + + + +/************************************************************************** + Function: + void USBIncrement1msInternalTimers(void) + + Description: + This function increments internal 1ms time base counters, which are + useful for application code (that can use a 1ms time base/counter), and + for certain USB event timing specific purposes. + + In USB full speed applications, the application code does not need to (and should + not) explicitly call this function, as the USBDeviceTasks() function will + automatically call this function whenever a 1ms time interval has elapsed + (assuming the code is calling USBDeviceTasks() frequently enough in USB_POLLING + mode, or that USB interrupts aren't being masked for more than 1ms at a time + in USB_INTERRUPT mode). + + In USB low speed applications, the application firmware is responsible for + periodically calling this function at a ~1ms rate. This can be done using + a general purpose microcontroller timer set to interrupt every 1ms for example. + If the low speed application code does not call this function, the internal timers + will not increment, and the USBGet1msTickCount() API function will not be available. + Additionally, certain USB stack operations (like control transfer timeouts) + may be unavailable. + + Precondition: + This function should be called only after USBDeviceInit() has been + called (at least once at the start of the application). Ordinarily, + application code should never call this function, unless it is a low speed + USB device. + + Parameters: + None + + Return Values: + None + + Remarks: + This function does not need to be called during USB suspend conditions, when + the USB module/stack is disabled, or when the USB cable is detached from the host. + ***************************************************************************/ +void USBIncrement1msInternalTimers(void) +{ + #if(USB_SPEED_OPTION == USB_LOW_SPEED) + #warning "For low speed USB applications, read the function comments for the USBIncrement1msInternalTimers() function, and implement code to call this function periodically." + #endif + + //Increment timekeeping 1ms tick counters. Useful for other APIs/code + //that needs a 1ms time base that is active during USB non-suspended operation. + USB1msTickCount++; + if(USBIsBusSuspended() == false) + { + USBTicksSinceSuspendEnd++; + //Check for 8-bit wraparound. If so, force it to saturate at 255. + if(USBTicksSinceSuspendEnd == 0) + { + USBTicksSinceSuspendEnd = 255; + } + } +} + + + + +/************************************************************************** + Function: + uint32_t USBGet1msTickCount(void) + + Description: + This function retrieves a 32-bit unsigned integer that normally increments by + one every one millisecond. The count value starts from zero when the + USBDeviceInit() function is first called. See the remarks section for + details on special circumstances where the tick count will not increment. + + Precondition: + This function should be called only after USBDeviceInit() has been + called (at least once at the start of the application). + + Parameters: + None + + Return Values: + uint32_t representing the approximate millisecond count, since the time the + USBDeviceInit() function was first called. + + Remarks: + On 8-bit USB full speed devices, the internal counter is incremented on + every SOF packet detected. Therefore, it will not increment during suspend + or when the USB cable is detached. However, on 16-bit devices, the T1MSECIF + hardware interrupt source is used to increment the internal counter. Therefore, + on 16-bit devices, the count continue to increment during USB suspend or + detach events, so long as the application code has not put the microcontroller + to sleep during these events, and the application firmware is regularly + calling the USBDeviceTasks() function (or allowing it to execute, if using + USB_INTERRUPT mode operation). + + In USB low speed applications, the host does not broadcast SOF packets to + the device, so the application firmware becomes responsible for calling + USBIncrement1msInternalTimers() periodically (ex: from a general purpose + timer interrupt handler), or else the returned value from this function will + not increment. + + Prior to calling USBDeviceInit() for the first time the returned value will + be unpredictable. + + This function is USB_INTERRUPT mode safe and may be called from main loop + code without risk of retrieving a partially updated 32-bit number. + + However, this value only increments when the USBDeviceTasks() function is allowed + to execute. If USB_INTERRUPT mode is used, it is allowable to block on this + function. If however USB_POLLING mode is used, one must not block on this + function without also calling USBDeviceTasks() continuously for the blocking + duration (since the USB stack must still be allowed to execute, and the USB + stack is also responsible for updating the tick counter internally). + + If the application is operating in USB_POLLING mode, this function should + only be called from the main loop context, and not from an interrupt handler, + as the returned value could be incorrect, if the main loop context code was in + the process of updating the internal count at the moment of the interrupt event. + ***************************************************************************/ +uint32_t USBGet1msTickCount(void) +{ + #if defined (USB_INTERRUPT) + uint32_t localContextValue; + + //Repeatedly read the interrupt context variable, until we get a stable/unchanging + //value. This ensures that the complete 32-bit value got read without + //getting interrupted in between bytes. + do + { + localContextValue = USB1msTickCount; + }while(localContextValue != USB1msTickCount); + + return localContextValue; + + #else + return USB1msTickCount; + #endif +} + + + + + + +/** EOF USBDevice.c *****************************************************/ diff --git a/usb/src/usb_device_cdc.c b/usb/src/usb_device_cdc.c new file mode 100644 index 0000000..88cdbac --- /dev/null +++ b/usb/src/usb_device_cdc.c @@ -0,0 +1,935 @@ +// 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 + +/******************************************************************** + Change History: + Rev Description + ---- ----------- + 2.3 Deprecated the mUSBUSARTIsTxTrfReady() macro. It is + replaced by the USBUSARTIsTxTrfReady() function. + + 2.6 Minor definition changes + + 2.6a No Changes + + 2.7 Fixed error in the part support list of the variables section + where the address of the CDC variables are defined. The + PIC18F2553 was incorrectly named PIC18F2453 and the PIC18F4558 + was incorrectly named PIC18F4458. + + http://www.microchip.com/forums/fb.aspx?m=487397 + + 2.8 Minor change to CDCInitEP() to enhance ruggedness in + multi0-threaded usage scenarios. + + 2.9b Updated to implement optional support for DTS reporting. + +********************************************************************/ + +/** I N C L U D E S **********************************************************/ +#include "usb.h" +#include "usb_device_cdc.h" + +#ifdef USB_USE_CDC + +#ifndef FIXED_ADDRESS_MEMORY + #define IN_DATA_BUFFER_ADDRESS_TAG + #define OUT_DATA_BUFFER_ADDRESS_TAG + #define CONTROL_BUFFER_ADDRESS_TAG +#endif + +#if !defined(IN_DATA_BUFFER_ADDRESS_TAG) || !defined(OUT_DATA_BUFFER_ADDRESS_TAG) || !defined(CONTROL_BUFFER_ADDRESS_TAG) + #error "One of the fixed memory address definitions is not defined. Please define the required address tags for the required buffers." +#endif + +/** V A R I A B L E S ********************************************************/ +volatile unsigned char cdc_data_tx[CDC_DATA_IN_EP_SIZE] IN_DATA_BUFFER_ADDRESS_TAG; +volatile unsigned char cdc_data_rx[CDC_DATA_OUT_EP_SIZE] OUT_DATA_BUFFER_ADDRESS_TAG; + +typedef union +{ + LINE_CODING lineCoding; + CDC_NOTICE cdcNotice; +} CONTROL_BUFFER; + +//static CONTROL_BUFFER controlBuffer CONTROL_BUFFER_ADDRESS_TAG; + +LINE_CODING line_coding; // Buffer to store line coding information +CDC_NOTICE cdc_notice; + +#if defined(USB_CDC_SUPPORT_DSR_REPORTING) + SERIAL_STATE_NOTIFICATION SerialStatePacket; +#endif + +uint8_t cdc_rx_len; // total rx length +uint8_t cdc_trf_state; // States are defined cdc.h +POINTER pCDCSrc; // Dedicated source pointer +POINTER pCDCDst; // Dedicated destination pointer +uint8_t cdc_tx_len; // total tx length +uint8_t cdc_mem_type; // _ROM, _RAM + +USB_HANDLE CDCDataOutHandle; +USB_HANDLE CDCDataInHandle; + + +CONTROL_SIGNAL_BITMAP control_signal_bitmap; +uint32_t BaudRateGen; // BRG value calculated from baud rate + +#if defined(USB_CDC_SUPPORT_DSR_REPORTING) + BM_SERIAL_STATE SerialStateBitmap; + BM_SERIAL_STATE OldSerialStateBitmap; + USB_HANDLE CDCNotificationInHandle; +#endif + +/************************************************************************** + SEND_ENCAPSULATED_COMMAND and GET_ENCAPSULATED_RESPONSE are required + requests according to the CDC specification. + However, it is not really being used here, therefore a dummy buffer is + used for conformance. + **************************************************************************/ +#define dummy_length 0x08 +uint8_t dummy_encapsulated_cmd_response[dummy_length]; + +#if defined(USB_CDC_SET_LINE_CODING_HANDLER) +CTRL_TRF_RETURN USB_CDC_SET_LINE_CODING_HANDLER(CTRL_TRF_PARAMS); +#endif + +/** P R I V A T E P R O T O T Y P E S ***************************************/ +void USBCDCSetLineCoding(void); + +/** D E C L A R A T I O N S **************************************************/ +//#pragma code + +/** C L A S S S P E C I F I C R E Q ****************************************/ +/****************************************************************************** + Function: + void USBCheckCDCRequest(void) + + Description: + This routine checks the most recently received SETUP data packet to + see if the request is specific to the CDC class. If the request was + a CDC specific request, this function will take care of handling the + request and responding appropriately. + + PreCondition: + This function should only be called after a control transfer SETUP + packet has arrived from the host. + + Parameters: + None + + Return Values: + None + + Remarks: + This function does not change status or do anything if the SETUP packet + did not contain a CDC class specific request. + *****************************************************************************/ +void USBCheckCDCRequest(void) +{ + /* + * If request recipient is not an interface then return + */ + if(SetupPkt.Recipient != USB_SETUP_RECIPIENT_INTERFACE_BITFIELD) return; + + /* + * If request type is not class-specific then return + */ + if(SetupPkt.RequestType != USB_SETUP_TYPE_CLASS_BITFIELD) return; + + /* + * Interface ID must match interface numbers associated with + * CDC class, else return + */ + if((SetupPkt.bIntfID != CDC_COMM_INTF_ID)&& + (SetupPkt.bIntfID != CDC_DATA_INTF_ID)) return; + + switch(SetupPkt.bRequest) + { + //****** These commands are required ******// + case SEND_ENCAPSULATED_COMMAND: + //send the packet + inPipes[0].pSrc.bRam = (uint8_t*)&dummy_encapsulated_cmd_response; + inPipes[0].wCount.Val = dummy_length; + inPipes[0].info.bits.ctrl_trf_mem = USB_EP0_RAM; + inPipes[0].info.bits.busy = 1; + break; + case GET_ENCAPSULATED_RESPONSE: + // Populate dummy_encapsulated_cmd_response first. + inPipes[0].pSrc.bRam = (uint8_t*)&dummy_encapsulated_cmd_response; + inPipes[0].info.bits.busy = 1; + break; + //****** End of required commands ******// + + #if defined(USB_CDC_SUPPORT_ABSTRACT_CONTROL_MANAGEMENT_CAPABILITIES_D1) + case SET_LINE_CODING: + outPipes[0].wCount.Val = SetupPkt.wLength; + outPipes[0].pDst.bRam = (uint8_t*)LINE_CODING_TARGET; + outPipes[0].pFunc = LINE_CODING_PFUNC; + outPipes[0].info.bits.busy = 1; + break; + + case GET_LINE_CODING: + USBEP0SendRAMPtr( + (uint8_t*)&line_coding, + LINE_CODING_LENGTH, + USB_EP0_INCLUDE_ZERO); + break; + + case SET_CONTROL_LINE_STATE: + control_signal_bitmap._byte = (uint8_t)SetupPkt.wValue; + //------------------------------------------------------------------ + //One way to control the RTS pin is to allow the USB host to decide the value + //that should be output on the RTS pin. Although RTS and CTS pin functions + //are technically intended for UART hardware based flow control, some legacy + //UART devices use the RTS pin like a "general purpose" output pin + //from the PC host. In this usage model, the RTS pin is not related + //to flow control for RX/TX. + //In this scenario, the USB host would want to be able to control the RTS + //pin, and the below line of code should be uncommented. + //However, if the intention is to implement true RTS/CTS flow control + //for the RX/TX pair, then this application firmware should override + //the USB host's setting for RTS, and instead generate a real RTS signal, + //based on the amount of remaining buffer space available for the + //actual hardware UART of this microcontroller. In this case, the + //below code should be left commented out, but instead RTS should be + //controlled in the application firmware responsible for operating the + //hardware UART of this microcontroller. + //--------- + //CONFIGURE_RTS(control_signal_bitmap.CARRIER_CONTROL); + //------------------------------------------------------------------ + + #if defined(USB_CDC_SUPPORT_DTR_SIGNALING) + if(control_signal_bitmap.DTE_PRESENT == 1) + { + UART_DTR = USB_CDC_DTR_ACTIVE_LEVEL; + } + else + { + UART_DTR = (USB_CDC_DTR_ACTIVE_LEVEL ^ 1); + } + #endif + inPipes[0].info.bits.busy = 1; + break; + #endif + + #if defined(USB_CDC_SUPPORT_ABSTRACT_CONTROL_MANAGEMENT_CAPABILITIES_D2) + case SEND_BREAK: // Optional + inPipes[0].info.bits.busy = 1; + if (SetupPkt.wValue == 0xFFFF) //0xFFFF means send break indefinitely until a new SEND_BREAK command is received + { + UART_Tx = 0; // Prepare to drive TX low (for break signaling) + UART_TRISTx = 0; // Make sure TX pin configured as an output + UART_ENABLE = 0; // Turn off USART (to relinquish TX pin control) + } + else if (SetupPkt.wValue == 0x0000) //0x0000 means stop sending indefinite break + { + UART_ENABLE = 1; // turn on USART + UART_TRISTx = 1; // Make TX pin an input + } + else + { + //Send break signaling on the pin for (SetupPkt.wValue) milliseconds + UART_SEND_BREAK(); + } + break; + #endif + default: + break; + }//end switch(SetupPkt.bRequest) + +}//end USBCheckCDCRequest + +/** U S E R A P I ***********************************************************/ + +/************************************************************************** + Function: + void CDCInitEP(void) + + Summary: + This function initializes the CDC function driver. This function should + be called after the SET_CONFIGURATION command (ex: within the context of + the USBCBInitEP() function). + Description: + This function initializes the CDC function driver. This function sets + the default line coding (baud rate, bit parity, number of data bits, + and format). This function also enables the endpoints and prepares for + the first transfer from the host. + + This function should be called after the SET_CONFIGURATION command. + This is most simply done by calling this function from the + USBCBInitEP() function. + + Typical Usage: + + void USBCBInitEP(void) + { + CDCInitEP(); + } + + Conditions: + None + Remarks: + None + **************************************************************************/ +void CDCInitEP(void) +{ + //Abstract line coding information + line_coding.dwDTERate = 19200; // baud rate + line_coding.bCharFormat = 0x00; // 1 stop bit + line_coding.bParityType = 0x00; // None + line_coding.bDataBits = 0x08; // 5,6,7,8, or 16 + + cdc_rx_len = 0; + + /* + * Do not have to init Cnt of IN pipes here. + * Reason: Number of BYTEs to send to the host + * varies from one transaction to + * another. Cnt should equal the exact + * number of BYTEs to transmit for + * a given IN transaction. + * This number of BYTEs will only + * be known right before the data is + * sent. + */ + USBEnableEndpoint(CDC_COMM_EP,USB_IN_ENABLED|USB_HANDSHAKE_ENABLED|USB_DISALLOW_SETUP); + USBEnableEndpoint(CDC_DATA_EP,USB_IN_ENABLED|USB_OUT_ENABLED|USB_HANDSHAKE_ENABLED|USB_DISALLOW_SETUP); + + CDCDataOutHandle = USBRxOnePacket(CDC_DATA_EP,(uint8_t*)&cdc_data_rx,sizeof(cdc_data_rx)); + CDCDataInHandle = NULL; + + #if defined(USB_CDC_SUPPORT_DSR_REPORTING) + CDCNotificationInHandle = NULL; + mInitDTSPin(); //Configure DTS as a digital input + SerialStateBitmap.byte = 0x00; + OldSerialStateBitmap.byte = !SerialStateBitmap.byte; //To force firmware to send an initial serial state packet to the host. + //Prepare a SerialState notification element packet (contains info like DSR state) + SerialStatePacket.bmRequestType = 0xA1; //Always 0xA1 for this type of packet. + SerialStatePacket.bNotification = SERIAL_STATE; + SerialStatePacket.wValue = 0x0000; //Always 0x0000 for this type of packet + SerialStatePacket.wIndex = CDC_COMM_INTF_ID; //Interface number + SerialStatePacket.SerialState.byte = 0x00; + SerialStatePacket.Reserved = 0x00; + SerialStatePacket.wLength = 0x02; //Always 2 bytes for this type of packet + CDCNotificationHandler(); + #endif + + #if defined(USB_CDC_SUPPORT_DTR_SIGNALING) + mInitDTRPin(); + #endif + + #if defined(USB_CDC_SUPPORT_HARDWARE_FLOW_CONTROL) + mInitRTSPin(); + mInitCTSPin(); + #endif + + cdc_trf_state = CDC_TX_READY; +}//end CDCInitEP + + +/************************************************************************** + Function: void CDCNotificationHandler(void) + Summary: Checks for changes in DSR status and reports them to the USB host. + Description: Checks for changes in DSR pin state and reports any changes + to the USB host. + Conditions: CDCInitEP() must have been called previously, prior to calling + CDCNotificationHandler() for the first time. + Remarks: + This function is only implemented and needed when the + USB_CDC_SUPPORT_DSR_REPORTING option has been enabled. If the function is + enabled, it should be called periodically to sample the DSR pin and feed + the information to the USB host. This can be done by calling + CDCNotificationHandler() by itself, or, by calling CDCTxService() which + also calls CDCNotificationHandler() internally, when appropriate. + **************************************************************************/ +#if defined(USB_CDC_SUPPORT_DSR_REPORTING) +void CDCNotificationHandler(void) +{ + //Check the DTS I/O pin and if a state change is detected, notify the + //USB host by sending a serial state notification element packet. + if(UART_DTS == USB_CDC_DSR_ACTIVE_LEVEL) //UART_DTS must be defined to be an I/O pin in the hardware profile to use the DTS feature (ex: "PORTXbits.RXY") + { + SerialStateBitmap.bits.DSR = 1; + } + else + { + SerialStateBitmap.bits.DSR = 0; + } + + //If the state has changed, and the endpoint is available, send a packet to + //notify the hUSB host of the change. + if((SerialStateBitmap.byte != OldSerialStateBitmap.byte) && (!USBHandleBusy(CDCNotificationInHandle))) + { + //Copy the updated value into the USB packet buffer to send. + SerialStatePacket.SerialState.byte = SerialStateBitmap.byte; + //We don't need to write to the other bytes in the SerialStatePacket USB + //buffer, since they don't change and will always be the same as our + //initialized value. + + //Send the packet over USB to the host. + CDCNotificationInHandle = USBTransferOnePacket(CDC_COMM_EP, IN_TO_HOST, (uint8_t*)&SerialStatePacket, sizeof(SERIAL_STATE_NOTIFICATION)); + + //Save the old value, so we can detect changes later. + OldSerialStateBitmap.byte = SerialStateBitmap.byte; + } +}//void CDCNotificationHandler(void) +#else + #define CDCNotificationHandler() {} +#endif + + +/********************************************************************************** + Function: + bool USBCDCEventHandler(USB_EVENT event, void *pdata, uint16_t size) + + Summary: + Handles events from the USB stack, which may have an effect on the CDC + endpoint(s). + + Description: + Handles events from the USB stack. This function should be called when + there is a USB event that needs to be processed by the CDC driver. + + Conditions: + Value of input argument 'len' should be smaller than the maximum + endpoint size responsible for receiving bulk data from USB host for CDC + class. Input argument 'buffer' should point to a buffer area that is + bigger or equal to the size specified by 'len'. + Input: + event - the type of event that occurred + pdata - pointer to the data that caused the event + size - the size of the data that is pointed to by pdata + + **********************************************************************************/ +bool USBCDCEventHandler(USB_EVENT event, void *pdata, uint16_t size) +{ + switch( (uint16_t)event ) + { + case EVENT_TRANSFER_TERMINATED: + if(pdata == CDCDataOutHandle) + { + CDCDataOutHandle = USBRxOnePacket(CDC_DATA_EP,(uint8_t*)&cdc_data_rx,sizeof(cdc_data_rx)); + } + if(pdata == CDCDataInHandle) + { + //flush all of the data in the CDC buffer + cdc_trf_state = CDC_TX_READY; + cdc_tx_len = 0; + } + break; + default: + return false; + } + return true; +} + +/********************************************************************************** + Function: + uint8_t getsUSBUSART(char *buffer, uint8_t len) + + Summary: + getsUSBUSART copies a string of BYTEs received through USB CDC Bulk OUT + endpoint to a user's specified location. It is a non-blocking function. + It does not wait for data if there is no data available. Instead it + returns '0' to notify the caller that there is no data available. + + Description: + getsUSBUSART copies a string of BYTEs received through USB CDC Bulk OUT + endpoint to a user's specified location. It is a non-blocking function. + It does not wait for data if there is no data available. Instead it + returns '0' to notify the caller that there is no data available. + + Typical Usage: + + uint8_t numBytes; + uint8_t buffer[64] + + numBytes = getsUSBUSART(buffer,sizeof(buffer)); //until the buffer is free. + if(numBytes \> 0) + { + //we received numBytes bytes of data and they are copied into + // the "buffer" variable. We can do something with the data + // here. + } + + Conditions: + Value of input argument 'len' should be smaller than the maximum + endpoint size responsible for receiving bulk data from USB host for CDC + class. Input argument 'buffer' should point to a buffer area that is + bigger or equal to the size specified by 'len'. + Input: + buffer - Pointer to where received BYTEs are to be stored + len - The number of BYTEs expected. + + **********************************************************************************/ +uint8_t getsUSBUSART(uint8_t *buffer, uint8_t len) +{ + cdc_rx_len = 0; + + if(!USBHandleBusy(CDCDataOutHandle)) + { + /* + * Adjust the expected number of BYTEs to equal + * the actual number of BYTEs received. + */ + if(len > USBHandleGetLength(CDCDataOutHandle)) + len = USBHandleGetLength(CDCDataOutHandle); + + /* + * Copy data from dual-ram buffer to user's buffer + */ + for(cdc_rx_len = 0; cdc_rx_len < len; cdc_rx_len++) + buffer[cdc_rx_len] = cdc_data_rx[cdc_rx_len]; + + /* + * Prepare dual-ram buffer for next OUT transaction + */ + + CDCDataOutHandle = USBRxOnePacket(CDC_DATA_EP,(uint8_t*)&cdc_data_rx,sizeof(cdc_data_rx)); + + }//end if + + return cdc_rx_len; + +}//end getsUSBUSART + +/****************************************************************************** + Function: + void putUSBUSART(char *data, uint8_t length) + + Summary: + putUSBUSART writes an array of data to the USB. Use this version, is + capable of transferring 0x00 (what is typically a NULL character in any of + the string transfer functions). + + Description: + putUSBUSART writes an array of data to the USB. Use this version, is + capable of transferring 0x00 (what is typically a NULL character in any of + the string transfer functions). + + Typical Usage: + + if(USBUSARTIsTxTrfReady()) + { + char data[] = {0x00, 0x01, 0x02, 0x03, 0x04}; + putUSBUSART(data,5); + } + + + The transfer mechanism for device-to-host(put) is more flexible than + host-to-device(get). It can handle a string of data larger than the + maximum size of bulk IN endpoint. A state machine is used to transfer a + \long string of data over multiple USB transactions. CDCTxService() + must be called periodically to keep sending blocks of data to the host. + + Conditions: + USBUSARTIsTxTrfReady() must return true. This indicates that the last + transfer is complete and is ready to receive a new block of data. The + string of characters pointed to by 'data' must equal to or smaller than + 255 BYTEs. + + Input: + char *data - pointer to a RAM array of data to be transfered to the host + uint8_t length - the number of bytes to be transfered (must be less than 255). + + *****************************************************************************/ +void putUSBUSART(uint8_t *data, uint8_t length) +{ + /* + * User should have checked that cdc_trf_state is in CDC_TX_READY state + * before calling this function. + * As a safety precaution, this function checks the state one more time + * to make sure it does not override any pending transactions. + * + * Currently it just quits the routine without reporting any errors back + * to the user. + * + * Bottom line: User MUST make sure that USBUSARTIsTxTrfReady()==1 + * before calling this function! + * Example: + * if(USBUSARTIsTxTrfReady()) + * putUSBUSART(pData, Length); + * + * IMPORTANT: Never use the following blocking while loop to wait: + * while(!USBUSARTIsTxTrfReady()) + * putUSBUSART(pData, Length); + * + * The whole firmware framework is written based on cooperative + * multi-tasking and a blocking code is not acceptable. + * Use a state machine instead. + */ + USBMaskInterrupts(); + if(cdc_trf_state == CDC_TX_READY) + { + mUSBUSARTTxRam((uint8_t*)data, length); // See cdc.h + } + USBUnmaskInterrupts(); +}//end putUSBUSART + +/****************************************************************************** + Function: + void putsUSBUSART(char *data) + + Summary: + putsUSBUSART writes a string of data to the USB including the null + character. Use this version, 'puts', to transfer data from a RAM buffer. + + Description: + putsUSBUSART writes a string of data to the USB including the null + character. Use this version, 'puts', to transfer data from a RAM buffer. + + Typical Usage: + + if(USBUSARTIsTxTrfReady()) + { + char data[] = "Hello World"; + putsUSBUSART(data); + } + + + The transfer mechanism for device-to-host(put) is more flexible than + host-to-device(get). It can handle a string of data larger than the + maximum size of bulk IN endpoint. A state machine is used to transfer a + \long string of data over multiple USB transactions. CDCTxService() + must be called periodically to keep sending blocks of data to the host. + + Conditions: + USBUSARTIsTxTrfReady() must return true. This indicates that the last + transfer is complete and is ready to receive a new block of data. The + string of characters pointed to by 'data' must equal to or smaller than + 255 BYTEs. + + Input: + char *data - null\-terminated string of constant data. If a + null character is not found, 255 BYTEs of data + will be transferred to the host. + + *****************************************************************************/ + +void putsUSBUSART(char *data) +{ + uint8_t len; + char *pData; + + /* + * User should have checked that cdc_trf_state is in CDC_TX_READY state + * before calling this function. + * As a safety precaution, this function checks the state one more time + * to make sure it does not override any pending transactions. + * + * Currently it just quits the routine without reporting any errors back + * to the user. + * + * Bottom line: User MUST make sure that USBUSARTIsTxTrfReady()==1 + * before calling this function! + * Example: + * if(USBUSARTIsTxTrfReady()) + * putsUSBUSART(pData, Length); + * + * IMPORTANT: Never use the following blocking while loop to wait: + * while(!USBUSARTIsTxTrfReady()) + * putsUSBUSART(pData); + * + * The whole firmware framework is written based on cooperative + * multi-tasking and a blocking code is not acceptable. + * Use a state machine instead. + */ + USBMaskInterrupts(); + if(cdc_trf_state != CDC_TX_READY) + { + USBUnmaskInterrupts(); + return; + } + + /* + * While loop counts the number of BYTEs to send including the + * null character. + */ + len = 0; + pData = data; + do + { + len++; + if(len == 255) break; // Break loop once max len is reached. + }while(*pData++); + + /* + * Second piece of information (length of data to send) is ready. + * Call mUSBUSARTTxRam to setup the transfer. + * The actual transfer process will be handled by CDCTxService(), + * which should be called once per Main Program loop. + */ + mUSBUSARTTxRam((uint8_t*)data, len); // See cdc.h + USBUnmaskInterrupts(); +}//end putsUSBUSART + +/************************************************************************** + Function: + void putrsUSBUSART(const const char *data) + + Summary: + putrsUSBUSART writes a string of data to the USB including the null + character. Use this version, 'putrs', to transfer data literals and + data located in program memory. + + Description: + putrsUSBUSART writes a string of data to the USB including the null + character. Use this version, 'putrs', to transfer data literals and + data located in program memory. + + Typical Usage: + + if(USBUSARTIsTxTrfReady()) + { + putrsUSBUSART("Hello World"); + } + + + The transfer mechanism for device-to-host(put) is more flexible than + host-to-device(get). It can handle a string of data larger than the + maximum size of bulk IN endpoint. A state machine is used to transfer a + \long string of data over multiple USB transactions. CDCTxService() + must be called periodically to keep sending blocks of data to the host. + + Conditions: + USBUSARTIsTxTrfReady() must return true. This indicates that the last + transfer is complete and is ready to receive a new block of data. The + string of characters pointed to by 'data' must equal to or smaller than + 255 BYTEs. + + Input: + const const char *data - null\-terminated string of constant data. If a + null character is not found, 255 uint8_ts of data + will be transferred to the host. + + **************************************************************************/ +void putrsUSBUSART(const const char *data) +{ + uint8_t len; + const const char *pData; + + /* + * User should have checked that cdc_trf_state is in CDC_TX_READY state + * before calling this function. + * As a safety precaution, this function checks the state one more time + * to make sure it does not override any pending transactions. + * + * Currently it just quits the routine without reporting any errors back + * to the user. + * + * Bottom line: User MUST make sure that USBUSARTIsTxTrfReady() + * before calling this function! + * Example: + * if(USBUSARTIsTxTrfReady()) + * putsUSBUSART(pData); + * + * IMPORTANT: Never use the following blocking while loop to wait: + * while(cdc_trf_state != CDC_TX_READY) + * putsUSBUSART(pData); + * + * The whole firmware framework is written based on cooperative + * multi-tasking and a blocking code is not acceptable. + * Use a state machine instead. + */ + USBMaskInterrupts(); + if(cdc_trf_state != CDC_TX_READY) + { + USBUnmaskInterrupts(); + return; + } + + /* + * While loop counts the number of BYTEs to send including the + * null character. + */ + len = 0; + pData = data; + do + { + len++; + if(len == 255) break; // Break loop once max len is reached. + }while(*pData++); + + /* + * Second piece of information (length of data to send) is ready. + * Call mUSBUSARTTxRom to setup the transfer. + * The actual transfer process will be handled by CDCTxService(), + * which should be called once per Main Program loop. + */ + + mUSBUSARTTxRom((const uint8_t*)data,len); // See cdc.h + USBUnmaskInterrupts(); + +}//end putrsUSBUSART + +/************************************************************************ + Function: + void CDCTxService(void) + + Summary: + CDCTxService handles device-to-host transaction(s). This function + should be called once per Main Program loop after the device reaches + the configured state. + Description: + CDCTxService handles device-to-host transaction(s). This function + should be called once per Main Program loop after the device reaches + the configured state (after the CDCIniEP() function has already executed). + This function is needed, in order to advance the internal software state + machine that takes care of sending multiple transactions worth of IN USB + data to the host, associated with CDC serial data. Failure to call + CDCTxService() periodically will prevent data from being sent to the + USB host, over the CDC serial data interface. + + Typical Usage: + + void main(void) + { + USBDeviceInit(); + while(1) + { + USBDeviceTasks(); + if((USBGetDeviceState() \< CONFIGURED_STATE) || + (USBIsDeviceSuspended() == true)) + { + //Either the device is not configured or we are suspended + // so we don't want to do execute any application code + continue; //go back to the top of the while loop + } + else + { + //Keep trying to send data to the PC as required + CDCTxService(); + + //Run application code. + UserApplication(); + } + } + } + + Conditions: + CDCIniEP() function should have already executed/the device should be + in the CONFIGURED_STATE. + Remarks: + None + ************************************************************************/ + +void CDCTxService(void) +{ + uint8_t byte_to_send; + uint8_t i; + + USBMaskInterrupts(); + + CDCNotificationHandler(); + + if(USBHandleBusy(CDCDataInHandle)) + { + USBUnmaskInterrupts(); + return; + } + + /* + * Completing stage is necessary while [ mCDCUSartTxIsBusy()==1 ]. + * By having this stage, user can always check cdc_trf_state, + * and not having to call mCDCUsartTxIsBusy() directly. + */ + if(cdc_trf_state == CDC_TX_COMPLETING) + cdc_trf_state = CDC_TX_READY; + + /* + * If CDC_TX_READY state, nothing to do, just return. + */ + if(cdc_trf_state == CDC_TX_READY) + { + USBUnmaskInterrupts(); + return; + } + + /* + * If CDC_TX_BUSY_ZLP state, send zero length packet + */ + if(cdc_trf_state == CDC_TX_BUSY_ZLP) + { + CDCDataInHandle = USBTxOnePacket(CDC_DATA_EP,NULL,0); + //CDC_DATA_BD_IN.CNT = 0; + cdc_trf_state = CDC_TX_COMPLETING; + } + else if(cdc_trf_state == CDC_TX_BUSY) + { + /* + * First, have to figure out how many byte of data to send. + */ + if(cdc_tx_len > sizeof(cdc_data_tx)) + byte_to_send = sizeof(cdc_data_tx); + else + byte_to_send = cdc_tx_len; + + /* + * Subtract the number of bytes just about to be sent from the total. + */ + cdc_tx_len = cdc_tx_len - byte_to_send; + + pCDCDst.bRam = (uint8_t*)&cdc_data_tx; // Set destination pointer + + i = byte_to_send; + if(cdc_mem_type == USB_EP0_ROM) // Determine type of memory source + { + while(i) + { + *pCDCDst.bRam = *pCDCSrc.bRom; + pCDCDst.bRam++; + pCDCSrc.bRom++; + i--; + }//end while(byte_to_send) + } + else + { + while(i) + { + *pCDCDst.bRam = *pCDCSrc.bRam; + pCDCDst.bRam++; + pCDCSrc.bRam++; + i--; + } + } + + /* + * Lastly, determine if a zero length packet state is necessary. + * See explanation in USB Specification 2.0: Section 5.8.3 + */ + if(cdc_tx_len == 0) + { + if(byte_to_send == CDC_DATA_IN_EP_SIZE) + cdc_trf_state = CDC_TX_BUSY_ZLP; + else + cdc_trf_state = CDC_TX_COMPLETING; + }//end if(cdc_tx_len...) + CDCDataInHandle = USBTxOnePacket(CDC_DATA_EP,(uint8_t*)&cdc_data_tx,byte_to_send); + + }//end if(cdc_tx_sate == CDC_TX_BUSY) + + USBUnmaskInterrupts(); +}//end CDCTxService + +#endif //USB_USE_CDC + +/** EOF cdc.c ****************************************************************/ diff --git a/usb/src/usb_device_generic.c b/usb/src/usb_device_generic.c new file mode 100644 index 0000000..1547daf --- /dev/null +++ b/usb/src/usb_device_generic.c @@ -0,0 +1,240 @@ +// 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 + +/******************************************************************** + Change History: + Rev Description + ---- ----------- + 2.6 Minor changes in include file structure. + 2.9h Implemented USBCheckVendorRequest() function, in order to + support MS OS Feature Descriptor handling. +******************************************************************** + +******************************************************************************/ + +/** I N C L U D E S **********************************************************/ +#include "usb.h" +#include "usb_device_generic.h" + +#if defined(USB_USE_GEN) + +/** V A R I A B L E S ********************************************************/ +extern volatile CTRL_TRF_SETUP SetupPkt; //Common buffer that receives the + //8-byte SETUP packet data from the + //host during control transfer + //requests. + +/** P R I V A T E P R O T O T Y P E S ***************************************/ + +/** D E C L A R A T I O N S **************************************************/ + +/** U S E R A P I ***********************************************************/ + +/******************************************************************** + Function: + USB_HANDLE USBGenWrite(uint8_t ep, uint8_t* data, uint16_t len) + + Summary: + Sends the specified data out the specified endpoint + + Description: + This function sends the specified data out the specified + endpoint and returns a handle to the transfer information. + + Typical Usage: + + //make sure that the last transfer isn't busy by checking the handle + if(!USBHandleBusy(USBGenericInHandle)) + { + //Send the data contained in the INPacket[] array out on + // endpoint USBGEN_EP_NUM + USBGenericInHandle = USBGenWrite(USBGEN_EP_NUM,(uint8_t*)&INPacket[0],sizeof(INPacket)); + } + + + PreCondition: + None + + Parameters: + uint8_t ep - the endpoint you want to send the data out of + uint8_t* data - pointer to the data that you wish to send + uint16_t len - the length of the data that you wish to send + + Return Values: + USB_HANDLE - a handle for the transfer. This information + should be kept to track the status of the transfer + + Remarks: + None + + *******************************************************************/ + // Implemented as a macro. See usb_function_generic.h + +/******************************************************************** + Function: + USB_HANDLE USBGenRead(uint8_t ep, uint8_t* data, uint16_t len) + + Summary: + Receives the specified data out the specified endpoint + + Description: + Receives the specified data out the specified endpoint. + + Typical Usage: + + //Read 64-bytes from endpoint USBGEN_EP_NUM, into the OUTPacket array. + // Make sure to save the return handle so that we can check it later + // to determine when the transfer is complete. + if(!USBHandleBusy(USBOutHandle)) + { + USBOutHandle = USBGenRead(USBGEN_EP_NUM,(uint8_t*)&OUTPacket,64); + } + + + PreCondition: + None + + Parameters: + uint8_t ep - the endpoint you want to receive the data into + uint8_t* data - pointer to where the data will go when it arrives + uint16_t len - the length of the data that you wish to receive + + Return Values: + USB_HANDLE - a handle for the transfer. This information + should be kept to track the status of the transfer + + Remarks: + None + + *******************************************************************/ + // Implemented as a macro. See usb_function_generic.h + + +/******************************************************************** + Function: + void USBCheckVendorRequest(void) + + Summary: + This routine handles vendor class specific requests that happen on EP0. + This function should be called from the USBCBCheckOtherReq() call back + function whenever implementing a custom/vendor class device. + + Description: + This routine handles vendor specific requests that may arrive on EP0 as + a control transfer. These can include, but are not necessarily + limited to, requests for Microsft specific OS feature descriptor(s). + This function should be called from the USBCBCheckOtherReq() call back + function whenever using a vendor class device. + + Typical Usage: + + void USBCBCheckOtherReq(void) + { + //Since the stack didn't handle the request I need to check + // my class drivers to see if it is for them + USBCheckVendorRequest(); + } + + + PreCondition: + None + + Parameters: + Although this function has a void input, this handler function will + typically need to look at the 8-byte SETUP packet contents that the + host just sent, which may contain the vendor class specific request. + + Therefore, the statically allocated SetupPkt structure may be looked + at while in the context of this function, and it will contain the most + recently received 8-byte SETUP packet data. + + Return Values: + None + + Remarks: + This function normally gets called within the same context as the + USBDeviceTasks() function, just after a new control transfer request + from the host has arrived. If the USB stack is operated in + USB_INTERRUPT mode (a usb_config.h option), then this function + will be executed in the interrupt context. If however the USB stack + is operated in the USB_POLLING mode, then this function executes in the + main loop context. + + In order to respond to class specific control transfer request(s) in + this handler function, it is suggested to use one or more of the + USBEP0SendRAMPtr(), USBEP0SendROMPtr(), or USBEP0Receive() API + functions. + + *******************************************************************/ +void USBCheckVendorRequest(void) +{ + #if defined(IMPLEMENT_MICROSOFT_OS_DESCRIPTOR) + uint16_t Length; + + //Check if the most recent SETUP request is class specific + if(SetupPkt.bmRequestType == 0b11000000) //Class specific, device to host, device level target + { + //Check if the host is requesting an MS feature descriptor + if(SetupPkt.bRequest == GET_MS_DESCRIPTOR) + { + //Figure out which descriptor is being requested + if(SetupPkt.wIndex == EXTENDED_COMPAT_ID) + { + //Determine number of bytes to send to host + //Lesser of: requested amount, or total size of the descriptor + Length = CompatIDFeatureDescriptor.dwLength; + if(SetupPkt.wLength < Length) + { + Length = SetupPkt.wLength; + } + + //Prepare to send the requested descriptor to the host + USBEP0SendROMPtr((const uint8_t*)&CompatIDFeatureDescriptor, Length, USB_EP0_ROM | USB_EP0_INCLUDE_ZERO); + } + } + }//if(SetupPkt.bmRequestType == 0b11000000) + else if(SetupPkt.bmRequestType == 0b11000001) //Class specific, device to host, interface target + { + //Check if the host is requesting an MS feature descriptor + if(SetupPkt.bRequest == GET_MS_DESCRIPTOR) + { + //Figure out which descriptor is being requested + if(SetupPkt.wIndex == EXTENDED_PROPERTIES) + { + //Determine number of bytes to send to host + //Lesser of: requested amount, or total size of the descriptor + Length = ExtPropertyFeatureDescriptor.dwLength; + if(SetupPkt.wLength < Length) + { + Length = SetupPkt.wLength; + } + + //Prepare to send the requested descriptor to the host + USBEP0SendROMPtr((const uint8_t*)&ExtPropertyFeatureDescriptor, Length, USB_EP0_ROM | USB_EP0_INCLUDE_ZERO); + } + } + }//else if(SetupPkt.bmRequestType == 0b11000001) + #endif //#if defined(IMPLEMENT_MICROSOFT_OS_DESCRIPTOR) +}//void USBCheckVendorRequest(void) + + +#endif //def USB_USE_GEN +/** EOF usbgen.c *************************************************************/ diff --git a/usb/src/usb_device_hid.c b/usb/src/usb_device_hid.c new file mode 100644 index 0000000..cb5a7ef --- /dev/null +++ b/usb/src/usb_device_hid.c @@ -0,0 +1,321 @@ +// 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 + +/******************************************************************************* + USB Device Human Interface Device (HID) Layer + + Company: + Microchip Technology Inc. + + File Name: + usb_device_hid.c + + Summary: + USB Device Human Interface Device (HID) Layer interface API. + + Description: + USB Device Human Interface Device (HID) Layer interface API. +*******************************************************************************/ + + +// ***************************************************************************** +// ***************************************************************************** +// Section: Included Files +// ***************************************************************************** +// ***************************************************************************** +#include "usb_config.h" +#include "usb.h" +#include "usb_device_hid.h" + +// ***************************************************************************** +// ***************************************************************************** +// Section: File Scope or Global Constants +// ***************************************************************************** +// ***************************************************************************** + +// ***************************************************************************** +// ***************************************************************************** +// Section: File Scope Data Types +// ***************************************************************************** +// ***************************************************************************** +typedef struct __attribute__((packed)) +{ + unsigned :8; + unsigned :8; + uint8_t reportId; + uint8_t duration; +} USB_SETUP_SET_IDLE_RATE; + +typedef struct __attribute__((packed)) +{ + unsigned :8; + unsigned :8; + uint8_t protocol; +} USB_SETUP_SET_PROTOCOL; + +// ***************************************************************************** +// ***************************************************************************** +// Section: Variables +// ***************************************************************************** +// ***************************************************************************** +static uint8_t idle_rate; +static uint8_t active_protocol; // [0] Boot Protocol [1] Report Protocol + +extern const struct{uint8_t report[HID_RPT01_SIZE];}hid_rpt01; + +// ***************************************************************************** +// ***************************************************************************** +// Section: Prototypes +// ***************************************************************************** +// ***************************************************************************** +#if defined USER_GET_REPORT_HANDLER + void USER_GET_REPORT_HANDLER(void); +#endif + +#if defined USER_SET_REPORT_HANDLER + extern void USER_SET_REPORT_HANDLER(void); +#endif + +// ***************************************************************************** +// ***************************************************************************** +// Section: Macros or Functions +// ***************************************************************************** +// ***************************************************************************** + +//To implement a set idle rate callback function in the application, +//Make sure "#define USB_DEVICE_HID_IDLE_RATE_CALLBACK(reportID, newIdleRate) USBHIDCBSetIdleRateHandler(reportID, newIdleRate)" +//is placed in your usb_config.h file, and then in your application .c file, +//add the void USBHIDCBSetIdleRateHandler(reportID, newIdleRate) function +//implementation that saves the new idle rate and report ID info, so that it +//gets used later when sending subsequent HID input report packets to the host. +#ifndef USB_DEVICE_HID_IDLE_RATE_CALLBACK + #define USB_DEVICE_HID_IDLE_RATE_CALLBACK(reportId, idleRate) +#else + extern void USB_DEVICE_HID_IDLE_RATE_CALLBACK(uint8_t reportId, uint8_t idleRate); +#endif + +/******************************************************************** + Function: + void USBCheckHIDRequest(void) + + Summary: + This routine handles HID specific request that happen on EP0. + This function should be called from the USBCBCheckOtherReq() call back + function whenever implementing a HID device. + + Description: + This routine handles HID specific request that happen on EP0. These + include, but are not limited to, requests for the HID report + descriptors. This function should be called from the + USBCBCheckOtherReq() call back function whenever using an HID device. + + Typical Usage: + + void USBCBCheckOtherReq(void) + { + //Since the stack didn't handle the request I need to check + // my class drivers to see if it is for them + USBCheckHIDRequest(); + } + + + PreCondition: + None + + Parameters: + None + + Return Values: + None + + Remarks: + None + + *******************************************************************/ +void USBCheckHIDRequest(void) +{ + if(SetupPkt.Recipient != USB_SETUP_RECIPIENT_INTERFACE_BITFIELD) return; + if(SetupPkt.bIntfID != HID_INTF_ID) return; + + /* + * There are two standard requests that hid.c may support. + * 1. GET_DSC(DSC_HID,DSC_RPT,DSC_PHY); + * 2. SET_DSC(DSC_HID,DSC_RPT,DSC_PHY); + */ + if(SetupPkt.bRequest == USB_REQUEST_GET_DESCRIPTOR) + { + switch(SetupPkt.bDescriptorType) + { + case DSC_HID: //HID Descriptor + if(USBActiveConfiguration == 1) + { + USBEP0SendROMPtr( + (const uint8_t*)&configDescriptor1 + 18, //18 is a magic number. It is the offset from start of the configuration descriptor to the start of the HID descriptor. + sizeof(USB_HID_DSC)+3, + USB_EP0_INCLUDE_ZERO); + } + break; + case DSC_RPT: //Report Descriptor + //if(USBActiveConfiguration == 1) + { + USBEP0SendROMPtr( + (const uint8_t*)&hid_rpt01, + HID_RPT01_SIZE, //See usbcfg.h + USB_EP0_INCLUDE_ZERO); + } + break; + case DSC_PHY: //Physical Descriptor + //Note: The below placeholder code is commented out. HID Physical Descriptors are optional and are not used + //in many types of HID applications. If an application does not have a physical descriptor, + //then the device should return STALL in response to this request (stack will do this automatically + //if no-one claims ownership of the control transfer). + //If an application does implement a physical descriptor, then make sure to declare + //hid_phy01 (rom structure containing the descriptor data), and hid_phy01 (the size of the descriptors in uint8_ts), + //and then uncomment the below code. + //if(USBActiveConfiguration == 1) + //{ + // USBEP0SendROMPtr((const uint8_t*)&hid_phy01, sizeof(hid_phy01), USB_EP0_INCLUDE_ZERO); + //} + break; + }//end switch(SetupPkt.bDescriptorType) + }//end if(SetupPkt.bRequest == GET_DSC) + + if(SetupPkt.RequestType != USB_SETUP_TYPE_CLASS_BITFIELD) + { + return; + } + + switch(SetupPkt.bRequest) + { + case GET_REPORT: + #if defined USER_GET_REPORT_HANDLER + USER_GET_REPORT_HANDLER(); + #endif + break; + case SET_REPORT: + #if defined USER_SET_REPORT_HANDLER + USER_SET_REPORT_HANDLER(); + #endif + break; + case GET_IDLE: + USBEP0SendRAMPtr( + (uint8_t*)&idle_rate, + 1, + USB_EP0_INCLUDE_ZERO); + break; + case SET_IDLE: + USBEP0Transmit(USB_EP0_NO_DATA); + idle_rate = SetupPkt.W_Value.byte.HB; + USB_DEVICE_HID_IDLE_RATE_CALLBACK(SetupPkt.W_Value.byte.LB, idle_rate); + break; + case GET_PROTOCOL: + USBEP0SendRAMPtr( + (uint8_t*)&active_protocol, + 1, + USB_EP0_NO_OPTIONS); + break; + case SET_PROTOCOL: + USBEP0Transmit(USB_EP0_NO_DATA); + active_protocol = SetupPkt.W_Value.byte.LB; + break; + }//end switch(SetupPkt.bRequest) + +}//end USBCheckHIDRequest + +/******************************************************************** + Function: + USB_HANDLE HIDTxPacket(uint8_t ep, uint8_t* data, uint16_t len) + + Summary: + Sends the specified data out the specified endpoint + + Description: + This function sends the specified data out the specified + endpoint and returns a handle to the transfer information. + + Typical Usage: + + //make sure that the last transfer isn't busy by checking the handle + if(!HIDTxHandleBusy(USBInHandle)) + { + //Send the data contained in the ToSendDataBuffer[] array out on + // endpoint HID_EP + USBInHandle = HIDTxPacket(HID_EP,(uint8_t*)&ToSendDataBuffer[0],sizeof(ToSendDataBuffer)); + } + + + PreCondition: + None + + Parameters: + uint8_t ep - the endpoint you want to send the data out of + uint8_t* data - pointer to the data that you wish to send + uint16_t len - the length of the data that you wish to send + + Return Values: + USB_HANDLE - a handle for the transfer. This information + should be kept to track the status of the transfer + + Remarks: + None + + *******************************************************************/ + // Implemented as a macro. See usb_function_hid.h + +/******************************************************************** + Function: + USB_HANDLE HIDRxPacket(uint8_t ep, uint8_t* data, uint16_t len) + + Summary: + Receives the specified data out the specified endpoint + + Description: + Receives the specified data out the specified endpoint. + + Typical Usage: + + //Read 64-uint8_ts from endpoint HID_EP, into the ReceivedDataBuffer array. + // Make sure to save the return handle so that we can check it later + // to determine when the transfer is complete. + USBOutHandle = HIDRxPacket(HID_EP,(uint8_t*)&ReceivedDataBuffer,64); + + + PreCondition: + None + + Parameters: + uint8_t ep - the endpoint you want to receive the data into + uint8_t* data - pointer to where the data will go when it arrives + uint16_t len - the length of the data that you wish to receive + + Return Values: + USB_HANDLE - a handle for the transfer. This information + should be kept to track the status of the transfer + + Remarks: + None + + *******************************************************************/ + // Implemented as a macro. See usb_function_hid.h + +/******************************************************************************* + End of File +*/