summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.cproject241
-rw-r--r--.gitignore2
-rw-r--r--.settings/language.settings.xml4
-rw-r--r--CMSIS/MK20D10_features.h2
-rw-r--r--MK20DN512xxx10_flash.ld10
-rw-r--r--board/board.c5
-rw-r--r--board/board.h13
-rw-r--r--board/clock_config.c56
-rw-r--r--board/clock_config.h2
-rw-r--r--board/pin_mux.c128
-rw-r--r--board/usb_host_config.h204
-rw-r--r--drivers/fsl_adc16.c2
-rw-r--r--k20_tester_Debug_Segger.launch42
-rw-r--r--source/adc_task.c343
-rw-r--r--source/adc_task.h19
-rw-r--r--source/com_task.c205
-rw-r--r--source/com_task.h130
-rw-r--r--source/gpio_ext.c141
-rw-r--r--source/gpio_ext.h73
-rw-r--r--source/main.c83
-rw-r--r--usb_1.1.0/device/usb_device.h508
-rw-r--r--usb_1.1.0/device/usb_device_dci.c1109
-rw-r--r--usb_1.1.0/device/usb_device_dci.h150
-rw-r--r--usb_1.1.0/device/usb_device_khci.c1355
-rw-r--r--usb_1.1.0/device/usb_device_khci.h243
-rw-r--r--usb_1.1.0/host/class/usb_host_audio.c1051
-rw-r--r--usb_1.1.0/host/class/usb_host_audio.h549
-rw-r--r--usb_1.1.0/host/class/usb_host_cdc.c1200
-rw-r--r--usb_1.1.0/host/class/usb_host_cdc.h518
-rw-r--r--usb_1.1.0/host/class/usb_host_hid.c804
-rw-r--r--usb_1.1.0/host/class/usb_host_hid.h411
-rw-r--r--usb_1.1.0/host/class/usb_host_hub.c612
-rw-r--r--usb_1.1.0/host/class/usb_host_hub.h390
-rw-r--r--usb_1.1.0/host/class/usb_host_hub_app.c1106
-rw-r--r--usb_1.1.0/host/class/usb_host_hub_app.h103
-rw-r--r--usb_1.1.0/host/class/usb_host_msd.c1155
-rw-r--r--usb_1.1.0/host/class/usb_host_msd.h872
-rw-r--r--usb_1.1.0/host/class/usb_host_msd_ufi.c473
-rw-r--r--usb_1.1.0/host/class/usb_host_phdc.c1272
-rw-r--r--usb_1.1.0/host/class/usb_host_phdc.h329
-rw-r--r--usb_1.1.0/host/class/usb_host_printer.c775
-rw-r--r--usb_1.1.0/host/class/usb_host_printer.h301
-rw-r--r--usb_1.1.0/host/usb_host.h569
-rw-r--r--usb_1.1.0/host/usb_host_devices.c1345
-rw-r--r--usb_1.1.0/host/usb_host_devices.h178
-rw-r--r--usb_1.1.0/host/usb_host_framework.c377
-rw-r--r--usb_1.1.0/host/usb_host_framework.h107
-rw-r--r--usb_1.1.0/host/usb_host_hci.c754
-rw-r--r--usb_1.1.0/host/usb_host_hci.h118
-rw-r--r--usb_1.1.0/host/usb_host_khci.c1886
-rw-r--r--usb_1.1.0/host/usb_host_khci.h328
-rw-r--r--usb_1.1.0/include/usb.h119
-rw-r--r--usb_1.1.0/include/usb_khci.h62
-rw-r--r--usb_1.1.0/include/usb_misc.h238
-rw-r--r--usb_1.1.0/include/usb_spec.h254
-rw-r--r--usb_1.1.0/osa/usb_osa.h578
-rw-r--r--usb_1.1.0/osa/usb_osa_bm.c538
-rw-r--r--usb_1.1.0/osa/usb_osa_bm.h57
-rw-r--r--usb_1.1.0/osa/usb_osa_freertos.c490
-rw-r--r--usb_1.1.0/osa/usb_osa_freertos.h111
60 files changed, 24907 insertions, 193 deletions
diff --git a/.cproject b/.cproject
index 769adc3..cb96519 100644
--- a/.cproject
+++ b/.cproject
@@ -17,41 +17,48 @@
<configuration artifactName="${ProjName}" buildArtefactType="org.eclipse.cdt.build.core.buildArtefactType.exe" buildProperties="org.eclipse.cdt.build.core.buildType=org.eclipse.cdt.build.core.buildType.debug,org.eclipse.cdt.build.core.buildArtefactType=org.eclipse.cdt.build.core.buildArtefactType.exe" cleanCommand="${cross_rm} -rf" description="" id="ilg.gnuarmeclipse.managedbuild.cross.config.elf.debug.475762548" name="Debug" parent="ilg.gnuarmeclipse.managedbuild.cross.config.elf.debug">
<folderInfo id="ilg.gnuarmeclipse.managedbuild.cross.config.elf.debug.475762548." name="/" resourcePath="">
<toolChain id="ilg.gnuarmeclipse.managedbuild.cross.toolchain.elf.debug.1690074070" name="Cross ARM GCC" superClass="ilg.gnuarmeclipse.managedbuild.cross.toolchain.elf.debug">
- <option id="ilg.gnuarmeclipse.managedbuild.cross.option.optimization.level.1531534215" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.optimization.level" value="ilg.gnuarmeclipse.managedbuild.cross.option.optimization.level.none" valueType="enumerated"/>
- <option id="ilg.gnuarmeclipse.managedbuild.cross.option.optimization.messagelength.1376026763" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.optimization.messagelength" value="true" valueType="boolean"/>
- <option id="ilg.gnuarmeclipse.managedbuild.cross.option.optimization.signedchar.322137639" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.optimization.signedchar" value="true" valueType="boolean"/>
- <option id="ilg.gnuarmeclipse.managedbuild.cross.option.optimization.functionsections.85374014" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.optimization.functionsections" value="true" valueType="boolean"/>
- <option id="ilg.gnuarmeclipse.managedbuild.cross.option.optimization.datasections.1295381849" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.optimization.datasections" value="true" valueType="boolean"/>
- <option id="ilg.gnuarmeclipse.managedbuild.cross.option.debugging.level.1293539573" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.debugging.level" value="ilg.gnuarmeclipse.managedbuild.cross.option.debugging.level.max" valueType="enumerated"/>
- <option id="ilg.gnuarmeclipse.managedbuild.cross.option.debugging.format.1380103813" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.debugging.format"/>
+ <option id="ilg.gnuarmeclipse.managedbuild.cross.option.optimization.level.1531534215" name="Optimization Level" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.optimization.level" value="ilg.gnuarmeclipse.managedbuild.cross.option.optimization.level.more" valueType="enumerated"/>
+ <option id="ilg.gnuarmeclipse.managedbuild.cross.option.optimization.messagelength.1376026763" name="Message length (-fmessage-length=0)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.optimization.messagelength" value="true" valueType="boolean"/>
+ <option id="ilg.gnuarmeclipse.managedbuild.cross.option.optimization.signedchar.322137639" name="'char' is signed (-fsigned-char)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.optimization.signedchar" value="true" valueType="boolean"/>
+ <option id="ilg.gnuarmeclipse.managedbuild.cross.option.optimization.functionsections.85374014" name="Function sections (-ffunction-sections)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.optimization.functionsections" value="true" valueType="boolean"/>
+ <option id="ilg.gnuarmeclipse.managedbuild.cross.option.optimization.datasections.1295381849" name="Data sections (-fdata-sections)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.optimization.datasections" value="true" valueType="boolean"/>
+ <option id="ilg.gnuarmeclipse.managedbuild.cross.option.debugging.level.1293539573" name="Debug level" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.debugging.level" value="ilg.gnuarmeclipse.managedbuild.cross.option.debugging.level.max" valueType="enumerated"/>
+ <option id="ilg.gnuarmeclipse.managedbuild.cross.option.debugging.format.1380103813" name="Debug format" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.debugging.format"/>
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.toolchain.name.782758310" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.toolchain.name" value="GNU Tools for ARM Embedded Processors" valueType="string"/>
- <option id="ilg.gnuarmeclipse.managedbuild.cross.option.architecture.1149841387" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.architecture" value="ilg.gnuarmeclipse.managedbuild.cross.option.architecture.arm" valueType="enumerated"/>
- <option id="ilg.gnuarmeclipse.managedbuild.cross.option.arm.target.family.267595661" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.arm.target.family" value="ilg.gnuarmeclipse.managedbuild.cross.option.arm.target.mcpu.cortex-m4" valueType="enumerated"/>
- <option id="ilg.gnuarmeclipse.managedbuild.cross.option.arm.target.instructionset.1361490329" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.arm.target.instructionset" value="ilg.gnuarmeclipse.managedbuild.cross.option.arm.target.instructionset.thumb" valueType="enumerated"/>
- <option id="ilg.gnuarmeclipse.managedbuild.cross.option.command.prefix.1064133248" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.command.prefix" value="arm-none-eabi-" valueType="string"/>
- <option id="ilg.gnuarmeclipse.managedbuild.cross.option.command.c.485268380" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.command.c" value="gcc" valueType="string"/>
- <option id="ilg.gnuarmeclipse.managedbuild.cross.option.command.cpp.712355467" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.command.cpp" value="g++" valueType="string"/>
- <option id="ilg.gnuarmeclipse.managedbuild.cross.option.command.ar.1786745360" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.command.ar" value="ar" valueType="string"/>
- <option id="ilg.gnuarmeclipse.managedbuild.cross.option.command.objcopy.114197144" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.command.objcopy" value="objcopy" valueType="string"/>
- <option id="ilg.gnuarmeclipse.managedbuild.cross.option.command.objdump.489938533" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.command.objdump" value="objdump" valueType="string"/>
- <option id="ilg.gnuarmeclipse.managedbuild.cross.option.command.size.1683169955" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.command.size" value="size" valueType="string"/>
- <option id="ilg.gnuarmeclipse.managedbuild.cross.option.command.make.1444304584" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.command.make" value="make" valueType="string"/>
- <option id="ilg.gnuarmeclipse.managedbuild.cross.option.command.rm.210870127" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.command.rm" value="rm" valueType="string"/>
- <option id="ilg.gnuarmeclipse.managedbuild.cross.option.addtools.createflash.416739129" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.addtools.createflash" value="true" valueType="boolean"/>
- <option id="ilg.gnuarmeclipse.managedbuild.cross.option.addtools.printsize.2071799907" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.addtools.printsize" value="true" valueType="boolean"/>
- <option id="ilg.gnuarmeclipse.managedbuild.cross.option.warnings.allwarn.998714097" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.warnings.allwarn" value="true" valueType="boolean"/>
+ <option id="ilg.gnuarmeclipse.managedbuild.cross.option.architecture.1149841387" name="Architecture" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.architecture" value="ilg.gnuarmeclipse.managedbuild.cross.option.architecture.arm" valueType="enumerated"/>
+ <option id="ilg.gnuarmeclipse.managedbuild.cross.option.arm.target.family.267595661" name="ARM family" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.arm.target.family" value="ilg.gnuarmeclipse.managedbuild.cross.option.arm.target.mcpu.cortex-m4" valueType="enumerated"/>
+ <option id="ilg.gnuarmeclipse.managedbuild.cross.option.arm.target.instructionset.1361490329" name="Instruction set" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.arm.target.instructionset" value="ilg.gnuarmeclipse.managedbuild.cross.option.arm.target.instructionset.thumb" valueType="enumerated"/>
+ <option id="ilg.gnuarmeclipse.managedbuild.cross.option.command.prefix.1064133248" name="Prefix" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.command.prefix" value="arm-none-eabi-" valueType="string"/>
+ <option id="ilg.gnuarmeclipse.managedbuild.cross.option.command.c.485268380" name="C compiler" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.command.c" value="gcc" valueType="string"/>
+ <option id="ilg.gnuarmeclipse.managedbuild.cross.option.command.cpp.712355467" name="C++ compiler" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.command.cpp" value="g++" valueType="string"/>
+ <option id="ilg.gnuarmeclipse.managedbuild.cross.option.command.ar.1786745360" name="Archiver" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.command.ar" value="ar" valueType="string"/>
+ <option id="ilg.gnuarmeclipse.managedbuild.cross.option.command.objcopy.114197144" name="Hex/Bin converter" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.command.objcopy" value="objcopy" valueType="string"/>
+ <option id="ilg.gnuarmeclipse.managedbuild.cross.option.command.objdump.489938533" name="Listing generator" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.command.objdump" value="objdump" valueType="string"/>
+ <option id="ilg.gnuarmeclipse.managedbuild.cross.option.command.size.1683169955" name="Size command" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.command.size" value="size" valueType="string"/>
+ <option id="ilg.gnuarmeclipse.managedbuild.cross.option.command.make.1444304584" name="Build command" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.command.make" value="make" valueType="string"/>
+ <option id="ilg.gnuarmeclipse.managedbuild.cross.option.command.rm.210870127" name="Remove command" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.command.rm" value="rm" valueType="string"/>
+ <option id="ilg.gnuarmeclipse.managedbuild.cross.option.addtools.createflash.416739129" name="Create flash image" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.addtools.createflash" value="true" valueType="boolean"/>
+ <option id="ilg.gnuarmeclipse.managedbuild.cross.option.addtools.printsize.2071799907" name="Print size" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.addtools.printsize" value="true" valueType="boolean"/>
+ <option id="ilg.gnuarmeclipse.managedbuild.cross.option.warnings.allwarn.998714097" name="Enable all common warnings (-Wall)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.warnings.allwarn" value="true" valueType="boolean"/>
+ <option id="ilg.gnuarmeclipse.managedbuild.cross.option.warnings.pedantic.1394555272" name="Pedantic (-pedantic)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.warnings.pedantic" value="false" valueType="boolean"/>
+ <option id="ilg.gnuarmeclipse.managedbuild.cross.option.warnings.extrawarn.1645809733" name="Enable extra warnings (-Wextra)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.warnings.extrawarn" value="true" valueType="boolean"/>
<targetPlatform archList="all" binaryParser="org.eclipse.cdt.core.ELF" id="ilg.gnuarmeclipse.managedbuild.cross.targetPlatform.1444192880" isAbstract="false" osList="all" superClass="ilg.gnuarmeclipse.managedbuild.cross.targetPlatform"/>
- <builder buildPath="${workspace_loc:/k20_tester}/Debug" id="ilg.gnuarmeclipse.managedbuild.cross.builder.1236922579" managedBuildOn="true" name="Gnu Make Builder.Debug" parallelBuildOn="true" parallelizationNumber="optimal" superClass="ilg.gnuarmeclipse.managedbuild.cross.builder"/>
+ <builder buildPath="${workspace_loc:/k20_tester}/Debug" id="ilg.gnuarmeclipse.managedbuild.cross.builder.1236922579" keepEnvironmentInBuildfile="false" managedBuildOn="true" name="Gnu Make Builder" parallelBuildOn="true" parallelizationNumber="optimal" superClass="ilg.gnuarmeclipse.managedbuild.cross.builder"/>
<tool id="ilg.gnuarmeclipse.managedbuild.cross.tool.assembler.959743626" name="Cross ARM GNU Assembler" superClass="ilg.gnuarmeclipse.managedbuild.cross.tool.assembler">
- <option id="ilg.gnuarmeclipse.managedbuild.cross.option.assembler.usepreprocessor.1302594668" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.assembler.usepreprocessor" value="true" valueType="boolean"/>
+ <option id="ilg.gnuarmeclipse.managedbuild.cross.option.assembler.usepreprocessor.1302594668" name="Use preprocessor" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.assembler.usepreprocessor" value="true" valueType="boolean"/>
+ <option id="ilg.gnuarmeclipse.managedbuild.cross.option.assembler.include.paths.340556141" name="Include paths (-I)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.assembler.include.paths" valueType="includePath">
+ <listOptionValue builtIn="false" value="&quot;${workspace_loc:/k20_main/usb_1.1.0/host}&quot;"/>
+ <listOptionValue builtIn="false" value="&quot;${workspace_loc:/k20_main/usb_1.1.0/osa}&quot;"/>
+ <listOptionValue builtIn="false" value="&quot;${workspace_loc:/k20_main/usb_1.1.0/include}&quot;"/>
+ </option>
<inputType id="ilg.gnuarmeclipse.managedbuild.cross.tool.assembler.input.852998941" superClass="ilg.gnuarmeclipse.managedbuild.cross.tool.assembler.input"/>
</tool>
<tool id="ilg.gnuarmeclipse.managedbuild.cross.tool.c.compiler.195326104" name="Cross ARM C Compiler" superClass="ilg.gnuarmeclipse.managedbuild.cross.tool.c.compiler">
- <option id="ilg.gnuarmeclipse.managedbuild.cross.option.c.compiler.defs.2027427795" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.c.compiler.defs" valueType="definedSymbols">
+ <option id="ilg.gnuarmeclipse.managedbuild.cross.option.c.compiler.defs.2027427795" name="Defined symbols (-D)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.c.compiler.defs" useByScannerDiscovery="false" valueType="definedSymbols">
<listOptionValue builtIn="false" value="&quot;CPU_MK20DN512VLK10&quot;"/>
</option>
- <option id="ilg.gnuarmeclipse.managedbuild.cross.option.c.compiler.std.1026465758" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.c.compiler.std" value="ilg.gnuarmeclipse.managedbuild.cross.option.c.compiler.std.gnu99" valueType="enumerated"/>
- <option id="ilg.gnuarmeclipse.managedbuild.cross.option.c.compiler.include.paths.59602908" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.c.compiler.include.paths" valueType="includePath">
+ <option id="ilg.gnuarmeclipse.managedbuild.cross.option.c.compiler.std.1026465758" name="Language standard" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.c.compiler.std" useByScannerDiscovery="true" value="ilg.gnuarmeclipse.managedbuild.cross.option.c.compiler.std.gnu99" valueType="enumerated"/>
+ <option id="ilg.gnuarmeclipse.managedbuild.cross.option.c.compiler.include.paths.59602908" name="Include paths (-I)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.c.compiler.include.paths" useByScannerDiscovery="false" valueType="includePath">
<listOptionValue builtIn="false" value="../freertos/Source/include"/>
<listOptionValue builtIn="false" value="../startup"/>
<listOptionValue builtIn="false" value="../board"/>
@@ -60,14 +67,17 @@
<listOptionValue builtIn="false" value="../source"/>
<listOptionValue builtIn="false" value="../CMSIS"/>
<listOptionValue builtIn="false" value="../drivers"/>
+ <listOptionValue builtIn="false" value="&quot;${workspace_loc:/k20_main/usb_1.1.0/include}&quot;"/>
+ <listOptionValue builtIn="false" value="&quot;${workspace_loc:/k20_main/usb_1.1.0/host}&quot;"/>
+ <listOptionValue builtIn="false" value="&quot;${workspace_loc:/k20_main/usb_1.1.0/osa}&quot;"/>
</option>
<inputType id="ilg.gnuarmeclipse.managedbuild.cross.tool.c.compiler.input.219491553" superClass="ilg.gnuarmeclipse.managedbuild.cross.tool.c.compiler.input"/>
</tool>
<tool id="ilg.gnuarmeclipse.managedbuild.cross.tool.cpp.compiler.476692042" name="Cross ARM C++ Compiler" superClass="ilg.gnuarmeclipse.managedbuild.cross.tool.cpp.compiler">
- <option id="ilg.gnuarmeclipse.managedbuild.cross.option.cpp.compiler.defs.406548015" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.cpp.compiler.defs" valueType="definedSymbols">
+ <option id="ilg.gnuarmeclipse.managedbuild.cross.option.cpp.compiler.defs.406548015" name="Defined symbols (-D)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.cpp.compiler.defs" useByScannerDiscovery="false" valueType="definedSymbols">
<listOptionValue builtIn="false" value="&quot;CPU_MK20DN512VLK10&quot;"/>
</option>
- <option id="ilg.gnuarmeclipse.managedbuild.cross.option.cpp.compiler.include.paths.506184444" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.cpp.compiler.include.paths" valueType="includePath">
+ <option id="ilg.gnuarmeclipse.managedbuild.cross.option.cpp.compiler.include.paths.506184444" name="Include paths (-I)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.cpp.compiler.include.paths" useByScannerDiscovery="false" valueType="includePath">
<listOptionValue builtIn="false" value="../freertos/Source/include"/>
<listOptionValue builtIn="false" value="../startup"/>
<listOptionValue builtIn="false" value="../board"/>
@@ -76,28 +86,31 @@
<listOptionValue builtIn="false" value="../source"/>
<listOptionValue builtIn="false" value="../CMSIS"/>
<listOptionValue builtIn="false" value="../drivers"/>
+ <listOptionValue builtIn="false" value="&quot;${workspace_loc:/k20_main/usb_1.1.0/host}&quot;"/>
+ <listOptionValue builtIn="false" value="&quot;${workspace_loc:/k20_main/usb_1.1.0/osa}&quot;"/>
+ <listOptionValue builtIn="false" value="&quot;${workspace_loc:/k20_main/usb_1.1.0/include}&quot;"/>
</option>
<inputType id="ilg.gnuarmeclipse.managedbuild.cross.tool.cpp.compiler.input.1983367536" superClass="ilg.gnuarmeclipse.managedbuild.cross.tool.cpp.compiler.input"/>
</tool>
<tool id="ilg.gnuarmeclipse.managedbuild.cross.tool.c.linker.582857652" name="Cross ARM C Linker" superClass="ilg.gnuarmeclipse.managedbuild.cross.tool.c.linker">
- <option id="ilg.gnuarmeclipse.managedbuild.cross.option.c.linker.gcsections.1973230905" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.c.linker.gcsections" value="true" valueType="boolean"/>
- <option id="ilg.gnuarmeclipse.managedbuild.cross.option.c.linker.usenewlibnano.192040549" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.c.linker.usenewlibnano" value="true" valueType="boolean"/>
- <option id="ilg.gnuarmeclipse.managedbuild.cross.option.c.linker.other.434660307" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.c.linker.other" value="-specs=nosys.specs -Xlinker -z -Xlinker muldefs" valueType="string"/>
- <option id="ilg.gnuarmeclipse.managedbuild.cross.option.c.linker.libs.495545513" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.c.linker.libs" valueType="libs">
+ <option id="ilg.gnuarmeclipse.managedbuild.cross.option.c.linker.gcsections.1973230905" name="Remove unused sections (-Xlinker --gc-sections)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.c.linker.gcsections" value="true" valueType="boolean"/>
+ <option id="ilg.gnuarmeclipse.managedbuild.cross.option.c.linker.usenewlibnano.192040549" name="Use newlib-nano (--specs=nano.specs)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.c.linker.usenewlibnano" value="true" valueType="boolean"/>
+ <option id="ilg.gnuarmeclipse.managedbuild.cross.option.c.linker.other.434660307" name="Other linker flags" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.c.linker.other" value="-specs=nosys.specs -Xlinker -z -Xlinker muldefs" valueType="string"/>
+ <option id="ilg.gnuarmeclipse.managedbuild.cross.option.c.linker.libs.495545513" name="Libraries (-l)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.c.linker.libs" valueType="libs">
<listOptionValue builtIn="false" value="m"/>
<listOptionValue builtIn="false" value="g"/>
<listOptionValue builtIn="false" value="gcc"/>
<listOptionValue builtIn="false" value="nosys"/>
</option>
- <option id="ilg.gnuarmeclipse.managedbuild.cross.option.c.linker.scriptfile.1440236707" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.c.linker.scriptfile" valueType="stringList">
+ <option id="ilg.gnuarmeclipse.managedbuild.cross.option.c.linker.scriptfile.1440236707" name="Script files (-T)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.c.linker.scriptfile" valueType="stringList">
<listOptionValue builtIn="false" value="&quot;../MK20DN512xxx10_flash.ld&quot;"/>
</option>
</tool>
<tool id="ilg.gnuarmeclipse.managedbuild.cross.tool.cpp.linker.279974294" name="Cross ARM C++ Linker" superClass="ilg.gnuarmeclipse.managedbuild.cross.tool.cpp.linker">
- <option id="ilg.gnuarmeclipse.managedbuild.cross.option.cpp.linker.gcsections.700834612" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.cpp.linker.gcsections" value="true" valueType="boolean"/>
- <option id="ilg.gnuarmeclipse.managedbuild.cross.option.cpp.linker.usenewlibnano.31880875" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.cpp.linker.usenewlibnano" value="true" valueType="boolean"/>
- <option id="ilg.gnuarmeclipse.managedbuild.cross.option.cpp.linker.other.1084061362" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.cpp.linker.other" value="-specs=nosys.specs -Xlinker -z -Xlinker muldefs" valueType="string"/>
- <option id="ilg.gnuarmeclipse.managedbuild.cross.option.cpp.linker.scriptfile.1842117803" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.cpp.linker.scriptfile" valueType="stringList">
+ <option id="ilg.gnuarmeclipse.managedbuild.cross.option.cpp.linker.gcsections.700834612" name="Remove unused sections (-Xlinker --gc-sections)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.cpp.linker.gcsections" value="true" valueType="boolean"/>
+ <option id="ilg.gnuarmeclipse.managedbuild.cross.option.cpp.linker.usenewlibnano.31880875" name="Use newlib-nano (--specs=nano.specs)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.cpp.linker.usenewlibnano" value="true" valueType="boolean"/>
+ <option id="ilg.gnuarmeclipse.managedbuild.cross.option.cpp.linker.other.1084061362" name="Other linker flags" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.cpp.linker.other" value="-specs=nosys.specs -Xlinker -z -Xlinker muldefs" valueType="string"/>
+ <option id="ilg.gnuarmeclipse.managedbuild.cross.option.cpp.linker.scriptfile.1842117803" name="Script files (-T)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.cpp.linker.scriptfile" valueType="stringList">
<listOptionValue builtIn="false" value="&quot;../MK20DN512xxx10_flash.ld&quot;"/>
</option>
<inputType id="ilg.gnuarmeclipse.managedbuild.cross.tool.cpp.linker.input.2139242385" superClass="ilg.gnuarmeclipse.managedbuild.cross.tool.cpp.linker.input">
@@ -106,37 +119,28 @@
</inputType>
</tool>
<tool id="ilg.gnuarmeclipse.managedbuild.cross.tool.archiver.1027019935" name="Cross ARM GNU Archiver" superClass="ilg.gnuarmeclipse.managedbuild.cross.tool.archiver"/>
- <tool id="ilg.gnuarmeclipse.managedbuild.cross.tool.createflash.765192573" name="Cross ARM GNU Create Flash Image" superClass="ilg.gnuarmeclipse.managedbuild.cross.tool.createflash"/>
+ <tool id="ilg.gnuarmeclipse.managedbuild.cross.tool.createflash.765192573" name="Cross ARM GNU Create Flash Image" superClass="ilg.gnuarmeclipse.managedbuild.cross.tool.createflash">
+ <option id="ilg.gnuarmeclipse.managedbuild.cross.option.createflash.choice.947331876" name="Output file format (-O)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.createflash.choice" value="ilg.gnuarmeclipse.managedbuild.cross.option.createflash.choice.binary" valueType="enumerated"/>
+ </tool>
<tool id="ilg.gnuarmeclipse.managedbuild.cross.tool.createlisting.1477096357" name="Cross ARM GNU Create Listing" superClass="ilg.gnuarmeclipse.managedbuild.cross.tool.createlisting">
- <option id="ilg.gnuarmeclipse.managedbuild.cross.option.createlisting.source.1301136094" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.createlisting.source" value="true" valueType="boolean"/>
- <option id="ilg.gnuarmeclipse.managedbuild.cross.option.createlisting.allheaders.225482937" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.createlisting.allheaders" value="true" valueType="boolean"/>
- <option id="ilg.gnuarmeclipse.managedbuild.cross.option.createlisting.demangle.325467794" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.createlisting.demangle" value="true" valueType="boolean"/>
- <option id="ilg.gnuarmeclipse.managedbuild.cross.option.createlisting.linenumbers.75698310" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.createlisting.linenumbers" value="true" valueType="boolean"/>
- <option id="ilg.gnuarmeclipse.managedbuild.cross.option.createlisting.wide.162004132" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.createlisting.wide" value="true" valueType="boolean"/>
+ <option id="ilg.gnuarmeclipse.managedbuild.cross.option.createlisting.source.1301136094" name="Display source (--source|-S)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.createlisting.source" value="true" valueType="boolean"/>
+ <option id="ilg.gnuarmeclipse.managedbuild.cross.option.createlisting.allheaders.225482937" name="Display all headers (--all-headers|-x)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.createlisting.allheaders" value="true" valueType="boolean"/>
+ <option id="ilg.gnuarmeclipse.managedbuild.cross.option.createlisting.demangle.325467794" name="Demangle names (--demangle|-C)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.createlisting.demangle" value="true" valueType="boolean"/>
+ <option id="ilg.gnuarmeclipse.managedbuild.cross.option.createlisting.linenumbers.75698310" name="Display line numbers (--line-numbers|-l)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.createlisting.linenumbers" value="true" valueType="boolean"/>
+ <option id="ilg.gnuarmeclipse.managedbuild.cross.option.createlisting.wide.162004132" name="Wide lines (--wide|-w)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.createlisting.wide" value="true" valueType="boolean"/>
</tool>
<tool id="ilg.gnuarmeclipse.managedbuild.cross.tool.printsize.905867099" name="Cross ARM GNU Print Size" superClass="ilg.gnuarmeclipse.managedbuild.cross.tool.printsize">
- <option id="ilg.gnuarmeclipse.managedbuild.cross.option.printsize.format.877762518" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.printsize.format"/>
+ <option id="ilg.gnuarmeclipse.managedbuild.cross.option.printsize.format.877762518" name="Size format" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.printsize.format"/>
</tool>
</toolChain>
</folderInfo>
- <fileInfo id="ilg.gnuarmeclipse.managedbuild.cross.config.elf.debug.475762548.freertos/Source/portable/MemMang/heap_2.c" name="heap_2.c" rcbsApplicability="disable" resourcePath="freertos/Source/portable/MemMang/heap_2.c" toolsToInvoke="ilg.gnuarmeclipse.managedbuild.cross.tool.c.compiler.195326104.1833320411">
- <tool id="ilg.gnuarmeclipse.managedbuild.cross.tool.c.compiler.195326104.1833320411" name="Cross ARM C Compiler" superClass="ilg.gnuarmeclipse.managedbuild.cross.tool.c.compiler.195326104"/>
- </fileInfo>
- <fileInfo id="ilg.gnuarmeclipse.managedbuild.cross.config.elf.debug.475762548.freertos/Source/portable/MemMang/heap_1.c" name="heap_1.c" rcbsApplicability="disable" resourcePath="freertos/Source/portable/MemMang/heap_1.c" toolsToInvoke="ilg.gnuarmeclipse.managedbuild.cross.tool.c.compiler.195326104.1716902986">
- <tool id="ilg.gnuarmeclipse.managedbuild.cross.tool.c.compiler.195326104.1716902986" name="Cross ARM C Compiler" superClass="ilg.gnuarmeclipse.managedbuild.cross.tool.c.compiler.195326104"/>
- </fileInfo>
- <fileInfo id="ilg.gnuarmeclipse.managedbuild.cross.config.elf.debug.475762548.freertos/Source/portable/MemMang/heap_5.c" name="heap_5.c" rcbsApplicability="disable" resourcePath="freertos/Source/portable/MemMang/heap_5.c" toolsToInvoke="ilg.gnuarmeclipse.managedbuild.cross.tool.c.compiler.195326104.1964988429">
- <tool id="ilg.gnuarmeclipse.managedbuild.cross.tool.c.compiler.195326104.1964988429" name="Cross ARM C Compiler" superClass="ilg.gnuarmeclipse.managedbuild.cross.tool.c.compiler.195326104"/>
- </fileInfo>
- <fileInfo id="ilg.gnuarmeclipse.managedbuild.cross.config.elf.debug.475762548.freertos/Source/portable/MemMang/heap_3.c" name="heap_3.c" rcbsApplicability="disable" resourcePath="freertos/Source/portable/MemMang/heap_3.c" toolsToInvoke="ilg.gnuarmeclipse.managedbuild.cross.tool.c.compiler.195326104.255822568">
- <tool id="ilg.gnuarmeclipse.managedbuild.cross.tool.c.compiler.195326104.255822568" name="Cross ARM C Compiler" superClass="ilg.gnuarmeclipse.managedbuild.cross.tool.c.compiler.195326104"/>
- </fileInfo>
<sourceEntries>
- <entry excluding="freertos/Source/portable/MemMang/heap_5.c|freertos/Source/portable/MemMang/heap_3.c|freertos/Source/portable/MemMang/heap_2.c|freertos/Source/portable/MemMang/heap_1.c" flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name=""/>
+ <entry excluding="usb_1.1.0/osa/usb_osa_bm.c|usb_1.1.0/device|freertos/Source/portable/MemMang/heap_5.c|freertos/Source/portable/MemMang/heap_3.c|freertos/Source/portable/MemMang/heap_2.c|freertos/Source/portable/MemMang/heap_1.c" flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name=""/>
</sourceEntries>
</configuration>
</storageModule>
<storageModule moduleId="org.eclipse.cdt.core.externalSettings"/>
+ <storageModule moduleId="ilg.gnuarmeclipse.managedbuild.packs"/>
</cconfiguration>
<cconfiguration id="ilg.gnuarmeclipse.managedbuild.cross.config.elf.release.1957441832">
<storageModule buildSystemId="org.eclipse.cdt.managedbuilder.core.configurationDataProvider" id="ilg.gnuarmeclipse.managedbuild.cross.config.elf.release.1957441832" moduleId="org.eclipse.cdt.core.settings" name="Release">
@@ -154,42 +158,48 @@
<configuration artifactName="${ProjName}" buildArtefactType="org.eclipse.cdt.build.core.buildArtefactType.exe" buildProperties="org.eclipse.cdt.build.core.buildType=org.eclipse.cdt.build.core.buildType.release,org.eclipse.cdt.build.core.buildArtefactType=org.eclipse.cdt.build.core.buildArtefactType.exe" cleanCommand="${cross_rm} -rf" description="" id="ilg.gnuarmeclipse.managedbuild.cross.config.elf.release.1957441832" name="Release" parent="ilg.gnuarmeclipse.managedbuild.cross.config.elf.release">
<folderInfo id="ilg.gnuarmeclipse.managedbuild.cross.config.elf.release.1957441832." name="/" resourcePath="">
<toolChain id="ilg.gnuarmeclipse.managedbuild.cross.toolchain.elf.release.1955683147" name="Cross ARM GCC" superClass="ilg.gnuarmeclipse.managedbuild.cross.toolchain.elf.release">
- <option id="ilg.gnuarmeclipse.managedbuild.cross.option.optimization.level.1503512935" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.optimization.level" value="ilg.gnuarmeclipse.managedbuild.cross.option.optimization.level.size" valueType="enumerated"/>
- <option id="ilg.gnuarmeclipse.managedbuild.cross.option.optimization.messagelength.749990463" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.optimization.messagelength" value="true" valueType="boolean"/>
- <option id="ilg.gnuarmeclipse.managedbuild.cross.option.optimization.signedchar.1398453889" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.optimization.signedchar" value="true" valueType="boolean"/>
- <option id="ilg.gnuarmeclipse.managedbuild.cross.option.optimization.functionsections.458714102" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.optimization.functionsections" value="true" valueType="boolean"/>
- <option id="ilg.gnuarmeclipse.managedbuild.cross.option.optimization.datasections.1713635727" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.optimization.datasections" value="true" valueType="boolean"/>
- <option id="ilg.gnuarmeclipse.managedbuild.cross.option.debugging.level.616331956" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.debugging.level"/>
- <option id="ilg.gnuarmeclipse.managedbuild.cross.option.debugging.format.1062923169" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.debugging.format"/>
+ <option id="ilg.gnuarmeclipse.managedbuild.cross.option.optimization.level.1503512935" name="Optimization Level" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.optimization.level" value="ilg.gnuarmeclipse.managedbuild.cross.option.optimization.level.more" valueType="enumerated"/>
+ <option id="ilg.gnuarmeclipse.managedbuild.cross.option.optimization.messagelength.749990463" name="Message length (-fmessage-length=0)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.optimization.messagelength" value="true" valueType="boolean"/>
+ <option id="ilg.gnuarmeclipse.managedbuild.cross.option.optimization.signedchar.1398453889" name="'char' is signed (-fsigned-char)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.optimization.signedchar" value="true" valueType="boolean"/>
+ <option id="ilg.gnuarmeclipse.managedbuild.cross.option.optimization.functionsections.458714102" name="Function sections (-ffunction-sections)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.optimization.functionsections" value="true" valueType="boolean"/>
+ <option id="ilg.gnuarmeclipse.managedbuild.cross.option.optimization.datasections.1713635727" name="Data sections (-fdata-sections)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.optimization.datasections" value="true" valueType="boolean"/>
+ <option id="ilg.gnuarmeclipse.managedbuild.cross.option.debugging.level.616331956" name="Debug level" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.debugging.level"/>
+ <option id="ilg.gnuarmeclipse.managedbuild.cross.option.debugging.format.1062923169" name="Debug format" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.debugging.format"/>
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.toolchain.name.2099258968" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.toolchain.name" value="GNU Tools for ARM Embedded Processors" valueType="string"/>
- <option id="ilg.gnuarmeclipse.managedbuild.cross.option.architecture.1414960201" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.architecture" value="ilg.gnuarmeclipse.managedbuild.cross.option.architecture.arm" valueType="enumerated"/>
- <option id="ilg.gnuarmeclipse.managedbuild.cross.option.arm.target.family.510906836" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.arm.target.family" value="ilg.gnuarmeclipse.managedbuild.cross.option.arm.target.mcpu.cortex-m4" valueType="enumerated"/>
- <option id="ilg.gnuarmeclipse.managedbuild.cross.option.arm.target.instructionset.280279268" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.arm.target.instructionset" value="ilg.gnuarmeclipse.managedbuild.cross.option.arm.target.instructionset.thumb" valueType="enumerated"/>
- <option id="ilg.gnuarmeclipse.managedbuild.cross.option.command.prefix.448665271" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.command.prefix" value="arm-none-eabi-" valueType="string"/>
- <option id="ilg.gnuarmeclipse.managedbuild.cross.option.command.c.2084483888" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.command.c" value="gcc" valueType="string"/>
- <option id="ilg.gnuarmeclipse.managedbuild.cross.option.command.cpp.69410033" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.command.cpp" value="g++" valueType="string"/>
- <option id="ilg.gnuarmeclipse.managedbuild.cross.option.command.ar.1633567946" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.command.ar" value="ar" valueType="string"/>
- <option id="ilg.gnuarmeclipse.managedbuild.cross.option.command.objcopy.1500379008" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.command.objcopy" value="objcopy" valueType="string"/>
- <option id="ilg.gnuarmeclipse.managedbuild.cross.option.command.objdump.1896055077" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.command.objdump" value="objdump" valueType="string"/>
- <option id="ilg.gnuarmeclipse.managedbuild.cross.option.command.size.874670059" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.command.size" value="size" valueType="string"/>
- <option id="ilg.gnuarmeclipse.managedbuild.cross.option.command.make.306940396" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.command.make" value="make" valueType="string"/>
- <option id="ilg.gnuarmeclipse.managedbuild.cross.option.command.rm.140768385" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.command.rm" value="rm" valueType="string"/>
- <option id="ilg.gnuarmeclipse.managedbuild.cross.option.addtools.createflash.1723171499" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.addtools.createflash" value="true" valueType="boolean"/>
- <option id="ilg.gnuarmeclipse.managedbuild.cross.option.addtools.printsize.293528197" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.addtools.printsize" value="true" valueType="boolean"/>
- <option id="ilg.gnuarmeclipse.managedbuild.cross.option.warnings.allwarn.1588021732" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.warnings.allwarn" value="true" valueType="boolean"/>
+ <option id="ilg.gnuarmeclipse.managedbuild.cross.option.architecture.1414960201" name="Architecture" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.architecture" value="ilg.gnuarmeclipse.managedbuild.cross.option.architecture.arm" valueType="enumerated"/>
+ <option id="ilg.gnuarmeclipse.managedbuild.cross.option.arm.target.family.510906836" name="ARM family" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.arm.target.family" value="ilg.gnuarmeclipse.managedbuild.cross.option.arm.target.mcpu.cortex-m4" valueType="enumerated"/>
+ <option id="ilg.gnuarmeclipse.managedbuild.cross.option.arm.target.instructionset.280279268" name="Instruction set" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.arm.target.instructionset" value="ilg.gnuarmeclipse.managedbuild.cross.option.arm.target.instructionset.thumb" valueType="enumerated"/>
+ <option id="ilg.gnuarmeclipse.managedbuild.cross.option.command.prefix.448665271" name="Prefix" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.command.prefix" value="arm-none-eabi-" valueType="string"/>
+ <option id="ilg.gnuarmeclipse.managedbuild.cross.option.command.c.2084483888" name="C compiler" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.command.c" value="gcc" valueType="string"/>
+ <option id="ilg.gnuarmeclipse.managedbuild.cross.option.command.cpp.69410033" name="C++ compiler" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.command.cpp" value="g++" valueType="string"/>
+ <option id="ilg.gnuarmeclipse.managedbuild.cross.option.command.ar.1633567946" name="Archiver" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.command.ar" value="ar" valueType="string"/>
+ <option id="ilg.gnuarmeclipse.managedbuild.cross.option.command.objcopy.1500379008" name="Hex/Bin converter" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.command.objcopy" value="objcopy" valueType="string"/>
+ <option id="ilg.gnuarmeclipse.managedbuild.cross.option.command.objdump.1896055077" name="Listing generator" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.command.objdump" value="objdump" valueType="string"/>
+ <option id="ilg.gnuarmeclipse.managedbuild.cross.option.command.size.874670059" name="Size command" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.command.size" value="size" valueType="string"/>
+ <option id="ilg.gnuarmeclipse.managedbuild.cross.option.command.make.306940396" name="Build command" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.command.make" value="make" valueType="string"/>
+ <option id="ilg.gnuarmeclipse.managedbuild.cross.option.command.rm.140768385" name="Remove command" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.command.rm" value="rm" valueType="string"/>
+ <option id="ilg.gnuarmeclipse.managedbuild.cross.option.addtools.createflash.1723171499" name="Create flash image" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.addtools.createflash" value="true" valueType="boolean"/>
+ <option id="ilg.gnuarmeclipse.managedbuild.cross.option.addtools.printsize.293528197" name="Print size" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.addtools.printsize" value="true" valueType="boolean"/>
+ <option id="ilg.gnuarmeclipse.managedbuild.cross.option.warnings.allwarn.1588021732" name="Enable all common warnings (-Wall)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.warnings.allwarn" value="true" valueType="boolean"/>
<targetPlatform archList="all" binaryParser="org.eclipse.cdt.core.ELF" id="ilg.gnuarmeclipse.managedbuild.cross.targetPlatform.883219432" isAbstract="false" osList="all" superClass="ilg.gnuarmeclipse.managedbuild.cross.targetPlatform"/>
- <builder buildPath="${workspace_loc:/k20_tester}/Release" id="ilg.gnuarmeclipse.managedbuild.cross.builder.1075071058" managedBuildOn="true" name="Gnu Make Builder.Release" parallelBuildOn="true" parallelizationNumber="optimal" superClass="ilg.gnuarmeclipse.managedbuild.cross.builder"/>
+ <builder buildPath="${workspace_loc:/k20_tester}/Release" id="ilg.gnuarmeclipse.managedbuild.cross.builder.1075071058" keepEnvironmentInBuildfile="false" managedBuildOn="true" name="Gnu Make Builder" parallelBuildOn="true" parallelizationNumber="optimal" superClass="ilg.gnuarmeclipse.managedbuild.cross.builder"/>
<tool id="ilg.gnuarmeclipse.managedbuild.cross.tool.assembler.1436178854" name="Cross ARM GNU Assembler" superClass="ilg.gnuarmeclipse.managedbuild.cross.tool.assembler">
- <option id="ilg.gnuarmeclipse.managedbuild.cross.option.assembler.usepreprocessor.174718932" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.assembler.usepreprocessor" value="true" valueType="boolean"/>
+ <option id="ilg.gnuarmeclipse.managedbuild.cross.option.assembler.usepreprocessor.174718932" name="Use preprocessor" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.assembler.usepreprocessor" value="true" valueType="boolean"/>
+ <option id="ilg.gnuarmeclipse.managedbuild.cross.option.assembler.include.paths.2136392768" name="Include paths (-I)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.assembler.include.paths" valueType="includePath">
+ <listOptionValue builtIn="false" value="&quot;${workspace_loc:/k20_tester/usb_1.1.0/host}&quot;"/>
+ <listOptionValue builtIn="false" value="&quot;${workspace_loc:/k20_main/usb_1.1.0/host}&quot;"/>
+ <listOptionValue builtIn="false" value="&quot;${workspace_loc:/k20_main/usb_1.1.0/osa}&quot;"/>
+ <listOptionValue builtIn="false" value="&quot;${workspace_loc:/k20_main/usb_1.1.0/include}&quot;"/>
+ </option>
<inputType id="ilg.gnuarmeclipse.managedbuild.cross.tool.assembler.input.982936805" superClass="ilg.gnuarmeclipse.managedbuild.cross.tool.assembler.input"/>
</tool>
<tool id="ilg.gnuarmeclipse.managedbuild.cross.tool.c.compiler.867386499" name="Cross ARM C Compiler" superClass="ilg.gnuarmeclipse.managedbuild.cross.tool.c.compiler">
- <option id="ilg.gnuarmeclipse.managedbuild.cross.option.c.compiler.defs.1292028075" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.c.compiler.defs" valueType="definedSymbols">
+ <option id="ilg.gnuarmeclipse.managedbuild.cross.option.c.compiler.defs.1292028075" name="Defined symbols (-D)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.c.compiler.defs" useByScannerDiscovery="false" valueType="definedSymbols">
<listOptionValue builtIn="false" value="NDEBUG"/>
<listOptionValue builtIn="false" value="&quot;CPU_MK20DN512VLK10&quot;"/>
</option>
- <option id="ilg.gnuarmeclipse.managedbuild.cross.option.c.compiler.std.1188085931" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.c.compiler.std" value="ilg.gnuarmeclipse.managedbuild.cross.option.c.compiler.std.gnu99" valueType="enumerated"/>
- <option id="ilg.gnuarmeclipse.managedbuild.cross.option.c.compiler.include.paths.1580315270" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.c.compiler.include.paths" valueType="includePath">
+ <option id="ilg.gnuarmeclipse.managedbuild.cross.option.c.compiler.std.1188085931" name="Language standard" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.c.compiler.std" useByScannerDiscovery="true" value="ilg.gnuarmeclipse.managedbuild.cross.option.c.compiler.std.gnu99" valueType="enumerated"/>
+ <option id="ilg.gnuarmeclipse.managedbuild.cross.option.c.compiler.include.paths.1580315270" name="Include paths (-I)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.c.compiler.include.paths" useByScannerDiscovery="false" valueType="includePath">
<listOptionValue builtIn="false" value="../freertos/Source/include"/>
<listOptionValue builtIn="false" value="../startup"/>
<listOptionValue builtIn="false" value="../board"/>
@@ -198,15 +208,18 @@
<listOptionValue builtIn="false" value="../source"/>
<listOptionValue builtIn="false" value="../CMSIS"/>
<listOptionValue builtIn="false" value="../drivers"/>
+ <listOptionValue builtIn="false" value="&quot;${workspace_loc:/k20_main/usb_1.1.0/host}&quot;"/>
+ <listOptionValue builtIn="false" value="&quot;${workspace_loc:/k20_main/usb_1.1.0/osa}&quot;"/>
+ <listOptionValue builtIn="false" value="&quot;${workspace_loc:/k20_main/usb_1.1.0/include}&quot;"/>
</option>
<inputType id="ilg.gnuarmeclipse.managedbuild.cross.tool.c.compiler.input.2019972668" superClass="ilg.gnuarmeclipse.managedbuild.cross.tool.c.compiler.input"/>
</tool>
<tool id="ilg.gnuarmeclipse.managedbuild.cross.tool.cpp.compiler.658547674" name="Cross ARM C++ Compiler" superClass="ilg.gnuarmeclipse.managedbuild.cross.tool.cpp.compiler">
- <option id="ilg.gnuarmeclipse.managedbuild.cross.option.cpp.compiler.defs.59523076" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.cpp.compiler.defs" valueType="definedSymbols">
+ <option id="ilg.gnuarmeclipse.managedbuild.cross.option.cpp.compiler.defs.59523076" name="Defined symbols (-D)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.cpp.compiler.defs" useByScannerDiscovery="false" valueType="definedSymbols">
<listOptionValue builtIn="false" value="NDEBUG"/>
<listOptionValue builtIn="false" value="&quot;CPU_MK20DN512VLK10&quot;"/>
</option>
- <option id="ilg.gnuarmeclipse.managedbuild.cross.option.cpp.compiler.include.paths.1916697474" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.cpp.compiler.include.paths" valueType="includePath">
+ <option id="ilg.gnuarmeclipse.managedbuild.cross.option.cpp.compiler.include.paths.1916697474" name="Include paths (-I)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.cpp.compiler.include.paths" useByScannerDiscovery="false" valueType="includePath">
<listOptionValue builtIn="false" value="../freertos/Source/include"/>
<listOptionValue builtIn="false" value="../startup"/>
<listOptionValue builtIn="false" value="../board"/>
@@ -215,28 +228,32 @@
<listOptionValue builtIn="false" value="../source"/>
<listOptionValue builtIn="false" value="../CMSIS"/>
<listOptionValue builtIn="false" value="../drivers"/>
+ <listOptionValue builtIn="false" value="&quot;${workspace_loc:/k20_tester/usb_1.1.0/host}&quot;"/>
+ <listOptionValue builtIn="false" value="&quot;${workspace_loc:/k20_main/usb_1.1.0/host}&quot;"/>
+ <listOptionValue builtIn="false" value="&quot;${workspace_loc:/k20_main/usb_1.1.0/osa}&quot;"/>
+ <listOptionValue builtIn="false" value="&quot;${workspace_loc:/k20_main/usb_1.1.0/include}&quot;"/>
</option>
<inputType id="ilg.gnuarmeclipse.managedbuild.cross.tool.cpp.compiler.input.501853267" superClass="ilg.gnuarmeclipse.managedbuild.cross.tool.cpp.compiler.input"/>
</tool>
<tool id="ilg.gnuarmeclipse.managedbuild.cross.tool.c.linker.2081594725" name="Cross ARM C Linker" superClass="ilg.gnuarmeclipse.managedbuild.cross.tool.c.linker">
- <option id="ilg.gnuarmeclipse.managedbuild.cross.option.c.linker.gcsections.574272050" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.c.linker.gcsections" value="true" valueType="boolean"/>
- <option id="ilg.gnuarmeclipse.managedbuild.cross.option.c.linker.usenewlibnano.1615086719" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.c.linker.usenewlibnano" value="true" valueType="boolean"/>
- <option id="ilg.gnuarmeclipse.managedbuild.cross.option.c.linker.other.1346892854" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.c.linker.other" value="-specs=nosys.specs -Xlinker -z -Xlinker muldefs" valueType="string"/>
- <option id="ilg.gnuarmeclipse.managedbuild.cross.option.c.linker.libs.1524186322" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.c.linker.libs" valueType="libs">
+ <option id="ilg.gnuarmeclipse.managedbuild.cross.option.c.linker.gcsections.574272050" name="Remove unused sections (-Xlinker --gc-sections)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.c.linker.gcsections" value="true" valueType="boolean"/>
+ <option id="ilg.gnuarmeclipse.managedbuild.cross.option.c.linker.usenewlibnano.1615086719" name="Use newlib-nano (--specs=nano.specs)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.c.linker.usenewlibnano" value="true" valueType="boolean"/>
+ <option id="ilg.gnuarmeclipse.managedbuild.cross.option.c.linker.other.1346892854" name="Other linker flags" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.c.linker.other" value="-specs=nosys.specs -Xlinker -z -Xlinker muldefs" valueType="string"/>
+ <option id="ilg.gnuarmeclipse.managedbuild.cross.option.c.linker.libs.1524186322" name="Libraries (-l)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.c.linker.libs" valueType="libs">
<listOptionValue builtIn="false" value="m"/>
<listOptionValue builtIn="false" value="g"/>
<listOptionValue builtIn="false" value="gcc"/>
<listOptionValue builtIn="false" value="nosys"/>
</option>
- <option id="ilg.gnuarmeclipse.managedbuild.cross.option.c.linker.scriptfile.2075351909" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.c.linker.scriptfile" valueType="stringList">
+ <option id="ilg.gnuarmeclipse.managedbuild.cross.option.c.linker.scriptfile.2075351909" name="Script files (-T)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.c.linker.scriptfile" valueType="stringList">
<listOptionValue builtIn="false" value="&quot;../MK20DN512xxx10_flash.ld&quot;"/>
</option>
</tool>
<tool id="ilg.gnuarmeclipse.managedbuild.cross.tool.cpp.linker.1018689855" name="Cross ARM C++ Linker" superClass="ilg.gnuarmeclipse.managedbuild.cross.tool.cpp.linker">
- <option id="ilg.gnuarmeclipse.managedbuild.cross.option.cpp.linker.gcsections.1431560932" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.cpp.linker.gcsections" value="true" valueType="boolean"/>
- <option id="ilg.gnuarmeclipse.managedbuild.cross.option.cpp.linker.usenewlibnano.1664026180" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.cpp.linker.usenewlibnano" value="true" valueType="boolean"/>
- <option id="ilg.gnuarmeclipse.managedbuild.cross.option.cpp.linker.other.51944173" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.cpp.linker.other" value="-specs=nosys.specs -Xlinker -z -Xlinker muldefs" valueType="string"/>
- <option id="ilg.gnuarmeclipse.managedbuild.cross.option.cpp.linker.scriptfile.858749115" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.cpp.linker.scriptfile" valueType="stringList">
+ <option id="ilg.gnuarmeclipse.managedbuild.cross.option.cpp.linker.gcsections.1431560932" name="Remove unused sections (-Xlinker --gc-sections)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.cpp.linker.gcsections" value="true" valueType="boolean"/>
+ <option id="ilg.gnuarmeclipse.managedbuild.cross.option.cpp.linker.usenewlibnano.1664026180" name="Use newlib-nano (--specs=nano.specs)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.cpp.linker.usenewlibnano" value="true" valueType="boolean"/>
+ <option id="ilg.gnuarmeclipse.managedbuild.cross.option.cpp.linker.other.51944173" name="Other linker flags" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.cpp.linker.other" value="-specs=nosys.specs -Xlinker -z -Xlinker muldefs" valueType="string"/>
+ <option id="ilg.gnuarmeclipse.managedbuild.cross.option.cpp.linker.scriptfile.858749115" name="Script files (-T)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.cpp.linker.scriptfile" valueType="stringList">
<listOptionValue builtIn="false" value="&quot;../MK20DN512xxx10_flash.ld&quot;"/>
</option>
<inputType id="ilg.gnuarmeclipse.managedbuild.cross.tool.cpp.linker.input.1918576724" superClass="ilg.gnuarmeclipse.managedbuild.cross.tool.cpp.linker.input">
@@ -245,33 +262,23 @@
</inputType>
</tool>
<tool id="ilg.gnuarmeclipse.managedbuild.cross.tool.archiver.948625665" name="Cross ARM GNU Archiver" superClass="ilg.gnuarmeclipse.managedbuild.cross.tool.archiver"/>
- <tool id="ilg.gnuarmeclipse.managedbuild.cross.tool.createflash.313070024" name="Cross ARM GNU Create Flash Image" superClass="ilg.gnuarmeclipse.managedbuild.cross.tool.createflash"/>
+ <tool id="ilg.gnuarmeclipse.managedbuild.cross.tool.createflash.313070024" name="Cross ARM GNU Create Flash Image" superClass="ilg.gnuarmeclipse.managedbuild.cross.tool.createflash">
+ <option id="ilg.gnuarmeclipse.managedbuild.cross.option.createflash.choice.92658489" name="Output file format (-O)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.createflash.choice" value="ilg.gnuarmeclipse.managedbuild.cross.option.createflash.choice.binary" valueType="enumerated"/>
+ </tool>
<tool id="ilg.gnuarmeclipse.managedbuild.cross.tool.createlisting.400069731" name="Cross ARM GNU Create Listing" superClass="ilg.gnuarmeclipse.managedbuild.cross.tool.createlisting">
- <option id="ilg.gnuarmeclipse.managedbuild.cross.option.createlisting.source.734357325" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.createlisting.source" value="true" valueType="boolean"/>
- <option id="ilg.gnuarmeclipse.managedbuild.cross.option.createlisting.allheaders.927124984" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.createlisting.allheaders" value="true" valueType="boolean"/>
- <option id="ilg.gnuarmeclipse.managedbuild.cross.option.createlisting.demangle.582117248" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.createlisting.demangle" value="true" valueType="boolean"/>
- <option id="ilg.gnuarmeclipse.managedbuild.cross.option.createlisting.linenumbers.407155582" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.createlisting.linenumbers" value="true" valueType="boolean"/>
- <option id="ilg.gnuarmeclipse.managedbuild.cross.option.createlisting.wide.334950927" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.createlisting.wide" value="true" valueType="boolean"/>
+ <option id="ilg.gnuarmeclipse.managedbuild.cross.option.createlisting.source.734357325" name="Display source (--source|-S)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.createlisting.source" value="true" valueType="boolean"/>
+ <option id="ilg.gnuarmeclipse.managedbuild.cross.option.createlisting.allheaders.927124984" name="Display all headers (--all-headers|-x)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.createlisting.allheaders" value="true" valueType="boolean"/>
+ <option id="ilg.gnuarmeclipse.managedbuild.cross.option.createlisting.demangle.582117248" name="Demangle names (--demangle|-C)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.createlisting.demangle" value="true" valueType="boolean"/>
+ <option id="ilg.gnuarmeclipse.managedbuild.cross.option.createlisting.linenumbers.407155582" name="Display line numbers (--line-numbers|-l)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.createlisting.linenumbers" value="true" valueType="boolean"/>
+ <option id="ilg.gnuarmeclipse.managedbuild.cross.option.createlisting.wide.334950927" name="Wide lines (--wide|-w)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.createlisting.wide" value="true" valueType="boolean"/>
</tool>
<tool id="ilg.gnuarmeclipse.managedbuild.cross.tool.printsize.1412550132" name="Cross ARM GNU Print Size" superClass="ilg.gnuarmeclipse.managedbuild.cross.tool.printsize">
- <option id="ilg.gnuarmeclipse.managedbuild.cross.option.printsize.format.345866851" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.printsize.format"/>
+ <option id="ilg.gnuarmeclipse.managedbuild.cross.option.printsize.format.345866851" name="Size format" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.printsize.format"/>
</tool>
</toolChain>
</folderInfo>
- <fileInfo id="ilg.gnuarmeclipse.managedbuild.cross.config.elf.release.1957441832.freertos/Source/portable/MemMang/heap_2.c" name="heap_2.c" rcbsApplicability="disable" resourcePath="freertos/Source/portable/MemMang/heap_2.c" toolsToInvoke="ilg.gnuarmeclipse.managedbuild.cross.tool.c.compiler.867386499.2104453947">
- <tool id="ilg.gnuarmeclipse.managedbuild.cross.tool.c.compiler.867386499.2104453947" name="Cross ARM C Compiler" superClass="ilg.gnuarmeclipse.managedbuild.cross.tool.c.compiler.867386499"/>
- </fileInfo>
- <fileInfo id="ilg.gnuarmeclipse.managedbuild.cross.config.elf.release.1957441832.freertos/Source/portable/MemMang/heap_1.c" name="heap_1.c" rcbsApplicability="disable" resourcePath="freertos/Source/portable/MemMang/heap_1.c" toolsToInvoke="ilg.gnuarmeclipse.managedbuild.cross.tool.c.compiler.867386499.902441384">
- <tool id="ilg.gnuarmeclipse.managedbuild.cross.tool.c.compiler.867386499.902441384" name="Cross ARM C Compiler" superClass="ilg.gnuarmeclipse.managedbuild.cross.tool.c.compiler.867386499"/>
- </fileInfo>
- <fileInfo id="ilg.gnuarmeclipse.managedbuild.cross.config.elf.release.1957441832.freertos/Source/portable/MemMang/heap_5.c" name="heap_5.c" rcbsApplicability="disable" resourcePath="freertos/Source/portable/MemMang/heap_5.c" toolsToInvoke="ilg.gnuarmeclipse.managedbuild.cross.tool.c.compiler.867386499.813566708">
- <tool id="ilg.gnuarmeclipse.managedbuild.cross.tool.c.compiler.867386499.813566708" name="Cross ARM C Compiler" superClass="ilg.gnuarmeclipse.managedbuild.cross.tool.c.compiler.867386499"/>
- </fileInfo>
- <fileInfo id="ilg.gnuarmeclipse.managedbuild.cross.config.elf.release.1957441832.freertos/Source/portable/MemMang/heap_3.c" name="heap_3.c" rcbsApplicability="disable" resourcePath="freertos/Source/portable/MemMang/heap_3.c" toolsToInvoke="ilg.gnuarmeclipse.managedbuild.cross.tool.c.compiler.867386499.1978408613">
- <tool id="ilg.gnuarmeclipse.managedbuild.cross.tool.c.compiler.867386499.1978408613" name="Cross ARM C Compiler" superClass="ilg.gnuarmeclipse.managedbuild.cross.tool.c.compiler.867386499"/>
- </fileInfo>
<sourceEntries>
- <entry excluding="freertos/Source/portable/MemMang/heap_5.c|freertos/Source/portable/MemMang/heap_3.c|freertos/Source/portable/MemMang/heap_2.c|freertos/Source/portable/MemMang/heap_1.c" flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name=""/>
+ <entry excluding="usb_1.1.0/osa/usb_osa_bm.c|usb_1.1.0/device|freertos/Source/portable/MemMang/heap_5.c|freertos/Source/portable/MemMang/heap_3.c|freertos/Source/portable/MemMang/heap_2.c|freertos/Source/portable/MemMang/heap_1.c" flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name=""/>
</sourceEntries>
</configuration>
</storageModule>
@@ -297,4 +304,6 @@
</scannerConfigBuildInfo>
</storageModule>
<storageModule moduleId="org.eclipse.cdt.core.LanguageSettingsProviders"/>
+ <storageModule moduleId="refreshScope"/>
+ <storageModule moduleId="org.eclipse.cdt.make.core.buildtargets"/>
</cproject>
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..ac01e66
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,2 @@
+/Debug/
+/Release/
diff --git a/.settings/language.settings.xml b/.settings/language.settings.xml
index a07f17e..1ba5254 100644
--- a/.settings/language.settings.xml
+++ b/.settings/language.settings.xml
@@ -5,7 +5,7 @@
<provider copy-of="extension" id="org.eclipse.cdt.ui.UserLanguageSettingsProvider"/>
<provider-reference id="org.eclipse.cdt.core.ReferencedProjectsLanguageSettingsProvider" ref="shared-provider"/>
<provider-reference id="org.eclipse.cdt.managedbuilder.core.MBSLanguageSettingsProvider" ref="shared-provider"/>
- <provider class="org.eclipse.cdt.managedbuilder.language.settings.providers.GCCBuiltinSpecsDetector" console="false" env-hash="-1525048453613542296" id="ilg.gnuarmeclipse.managedbuild.cross.GCCBuiltinSpecsDetector" keep-relative-paths="false" name="CDT GCC Built-in Compiler Settings Cross ARM" parameter="${COMMAND} ${FLAGS} ${cross_toolchain_flags} -E -P -v -dD &quot;${INPUTS}&quot;" prefer-non-shared="true">
+ <provider class="org.eclipse.cdt.managedbuilder.language.settings.providers.GCCBuiltinSpecsDetector" console="false" env-hash="-1816812103733345723" id="ilg.gnuarmeclipse.managedbuild.cross.GCCBuiltinSpecsDetector" keep-relative-paths="false" name="CDT GCC Built-in Compiler Settings Cross ARM" parameter="${COMMAND} ${FLAGS} ${cross_toolchain_flags} -E -P -v -dD &quot;${INPUTS}&quot;" prefer-non-shared="true">
<language-scope id="org.eclipse.cdt.core.gcc"/>
<language-scope id="org.eclipse.cdt.core.g++"/>
</provider>
@@ -16,7 +16,7 @@
<provider copy-of="extension" id="org.eclipse.cdt.ui.UserLanguageSettingsProvider"/>
<provider-reference id="org.eclipse.cdt.core.ReferencedProjectsLanguageSettingsProvider" ref="shared-provider"/>
<provider-reference id="org.eclipse.cdt.managedbuilder.core.MBSLanguageSettingsProvider" ref="shared-provider"/>
- <provider class="org.eclipse.cdt.managedbuilder.language.settings.providers.GCCBuiltinSpecsDetector" console="false" env-hash="-1535146452300226770" id="ilg.gnuarmeclipse.managedbuild.cross.GCCBuiltinSpecsDetector" keep-relative-paths="false" name="CDT GCC Built-in Compiler Settings Cross ARM" parameter="${COMMAND} ${FLAGS} ${cross_toolchain_flags} -E -P -v -dD &quot;${INPUTS}&quot;" prefer-non-shared="true">
+ <provider class="org.eclipse.cdt.managedbuilder.language.settings.providers.GCCBuiltinSpecsDetector" console="false" env-hash="-1786576365201881109" id="ilg.gnuarmeclipse.managedbuild.cross.GCCBuiltinSpecsDetector" keep-relative-paths="false" name="CDT GCC Built-in Compiler Settings Cross ARM" parameter="${COMMAND} ${FLAGS} ${cross_toolchain_flags} -E -P -v -dD &quot;${INPUTS}&quot;" prefer-non-shared="true">
<language-scope id="org.eclipse.cdt.core.gcc"/>
<language-scope id="org.eclipse.cdt.core.g++"/>
</provider>
diff --git a/CMSIS/MK20D10_features.h b/CMSIS/MK20D10_features.h
index 3729f04..d42d831 100644
--- a/CMSIS/MK20D10_features.h
+++ b/CMSIS/MK20D10_features.h
@@ -127,7 +127,7 @@
/* @brief DRY availability on the SoC. */
#define FSL_FEATURE_SOC_DRY_COUNT (0)
/* @brief DSPI availability on the SoC. */
- #define FSL_FEATURE_SOC_DSPI_COUNT (2)
+ #define FSL_FEATURE_SOC_DSPI_COUNT (3)
/* @brief EMVSIM availability on the SoC. */
#define FSL_FEATURE_SOC_EMVSIM_COUNT (0)
/* @brief ENC availability on the SoC. */
diff --git a/MK20DN512xxx10_flash.ld b/MK20DN512xxx10_flash.ld
index 31b2d0f..782d555 100644
--- a/MK20DN512xxx10_flash.ld
+++ b/MK20DN512xxx10_flash.ld
@@ -60,7 +60,8 @@ MEMORY
{
m_interrupts (RX) : ORIGIN = 0x00000000, LENGTH = 0x00000400
m_flash_config (RX) : ORIGIN = 0x00000400, LENGTH = 0x00000010
- m_text (RX) : ORIGIN = 0x00000410, LENGTH = 0x0007FBF0
+ m_fw_version (RX) : ORIGIN = 0x00000410, LENGTH = 0x00000004
+ m_text (RX) : ORIGIN = 0x00000414, LENGTH = 0x0007FBEC
m_data (RW) : ORIGIN = 0x1FFF0000, LENGTH = 0x00010000
m_data_2 (RW) : ORIGIN = 0x20000000, LENGTH = 0x00010000
}
@@ -79,10 +80,15 @@ SECTIONS
.flash_config :
{
- . = ALIGN(4);
+ . = ALIGN(4);
KEEP(*(.FlashConfig)) /* Flash Configuration Field (FCF) */
. = ALIGN(4);
} > m_flash_config
+
+ .fw_config :
+ {
+ KEEP(*(.FwVersion)) /* Firmware version */
+ } > m_fw_version
/* The program code and other data goes into internal flash */
.text :
diff --git a/board/board.c b/board/board.c
index c0bbde0..726870b 100644
--- a/board/board.c
+++ b/board/board.c
@@ -32,11 +32,14 @@
#include <stdint.h>
#include "board.h"
+#include "fsl_debug_console.h"
/*!
* @brief initialize debug console to enable printf for this demo/example
*/
void BOARD_InitDebugConsole(void) {
- /* The user initialization should be placed here */
+ uint32_t uartClkSrcFreq = BOARD_DEBUG_UART_CLK_FREQ;
+
+ DbgConsole_Init(BOARD_DEBUG_UART_BASEADDR, BOARD_DEBUG_UART_BAUDRATE, BOARD_DEBUG_UART_TYPE, uartClkSrcFreq);
}
diff --git a/board/board.h b/board/board.h
index bd6d36b..00d185d 100644
--- a/board/board.h
+++ b/board/board.h
@@ -40,6 +40,19 @@
/* The board name */
#define BOARD_NAME "###-not-specified-###"
+#define BOARD_USE_UART
+#define BOARD_DEBUG_UART_TYPE DEBUG_CONSOLE_DEVICE_TYPE_UART
+#define BOARD_DEBUG_UART_BASEADDR (uint32_t) UART3
+#define BOARD_DEBUG_UART_CLKSRC kCLOCK_BusClk
+#define BOARD_DEBUG_UART_CLK_FREQ CLOCK_GetBusClkFreq()
+#define BOARD_UART_IRQ UART3_RX_TX_IRQn
+#define BOARD_UART_IRQ_HANDLER UART3_RX_TX_IRQHandler
+
+#define BOARD_USES_ADC
+
+#ifndef BOARD_DEBUG_UART_BAUDRATE
+#define BOARD_DEBUG_UART_BAUDRATE 115200
+#endif
/*******************************************************************************
* API
diff --git a/board/clock_config.c b/board/clock_config.c
index 41f6eb5..16626ba 100644
--- a/board/clock_config.c
+++ b/board/clock_config.c
@@ -30,6 +30,11 @@
/* This is a template for clock configuration created by New Kinetis SDK 2.x Project Wizard. Enjoy! */
+#include "fsl_device_registers.h"
+#include "fsl_common.h"
+#include "fsl_clock.h"
+#include "fsl_port.h"
+#include "clock_config.h"
/*******************************************************************************
* Definitions
@@ -43,10 +48,51 @@
* Code
******************************************************************************/
-/*!
- * @brief configure clock after reset for this demo/example
- */
-void BOARD_BootClockRUN(void) {
- /* The user configuration should be placed here */
+void BOARD_InitOsc0(void)
+{
+ const osc_config_t oscConfig = {.freq = BOARD_XTAL0_CLK_HZ,
+ .capLoad = 0,
+ .workMode = kOSC_ModeOscLowPower,
+ .oscerConfig = {
+ .enableMode = kOSC_ErClkEnable,
+#if (defined(FSL_FEATURE_OSC_HAS_EXT_REF_CLOCK_DIVIDER) && FSL_FEATURE_OSC_HAS_EXT_REF_CLOCK_DIVIDER)
+ .erclkDiv = 0U,
+#endif
+ }};
+
+ CLOCK_InitOsc0(&oscConfig);
+
+ /* Passing the XTAL0 frequency to clock driver. */
+ CLOCK_SetXtal0Freq(BOARD_XTAL0_CLK_HZ);
+ /* Use RTC_CLKIN input clock directly. */
+ //CLOCK_SetXtal32Freq(BOARD_XTAL32K_CLK_HZ);
+}
+
+void BOARD_BootClockRUN(void)
+{
+ /*
+ * Core clock: 96MHz
+ * Bus clock: 48MHz
+ */
+ mcg_pll_config_t pll0Config = {
+ .enableMode = 0U, .prdiv = 0x3U, .vdiv = 0x18U,
+ };
+ const sim_clock_config_t simConfig = {
+ .pllFllSel = 1U, /* PLLFLLSEL select PLL. */
+ .er32kSrc = 2U, /* ERCLK32K selection, use RTC. */
+ .clkdiv1 = 0x01130000U, /* SIM_CLKDIV1. */
+ };
+
+ CLOCK_SetSimSafeDivs();
+ BOARD_InitOsc0();
+
+ CLOCK_CalcPllDiv(BOARD_XTAL0_CLK_HZ, 96000000U, &pll0Config.prdiv, &pll0Config.vdiv);
+ CLOCK_BootToPeeMode(kMCG_OscselOsc, kMCG_PllClkSelPll0, &pll0Config);
+
+ CLOCK_SetInternalRefClkConfig(kMCG_IrclkEnable, kMCG_IrcSlow, 0);
+ CLOCK_SetSimConfig(&simConfig);
+
+ SystemCoreClock = 96000000U;
}
+
diff --git a/board/clock_config.h b/board/clock_config.h
index e39811f..f9c2406 100644
--- a/board/clock_config.h
+++ b/board/clock_config.h
@@ -36,7 +36,7 @@
/*******************************************************************************
* DEFINITION
******************************************************************************/
-
+#define BOARD_XTAL0_CLK_HZ 8000000U
/*******************************************************************************
* API
******************************************************************************/
diff --git a/board/pin_mux.c b/board/pin_mux.c
index be07825..3a538f5 100644
--- a/board/pin_mux.c
+++ b/board/pin_mux.c
@@ -34,6 +34,8 @@
#include "fsl_common.h"
#include "fsl_port.h"
#include "fsl_gpio.h"
+#include "fsl_debug_console.h"
+#include "gpio_ext.h"
/*******************************************************************************
* Code
@@ -43,54 +45,96 @@
*/
void BOARD_InitPins(void)
{
- gpio_pin_config_t gpio_out_config = {
- kGPIO_DigitalOutput, 0,
- };
+ unsigned int i;
+ gpio_pin_config_t gpio_out_config = {
+ kGPIO_DigitalOutput, 0,
+ };
+ gpio_pin_config_t gpio_out_hi_config = {
+ kGPIO_DigitalOutput, 1,
+ };
+ gpio_pin_config_t gpio_in_config = {
+ kGPIO_DigitalInput,
+ };
+ port_pin_config_t od_config;
- CLOCK_EnableClock(kCLOCK_PortA);
- CLOCK_EnableClock(kCLOCK_PortB);
- CLOCK_EnableClock(kCLOCK_PortC);
- CLOCK_EnableClock(kCLOCK_PortD);
- CLOCK_EnableClock(kCLOCK_PortE);
+ CLOCK_EnableClock(kCLOCK_PortA);
+ CLOCK_EnableClock(kCLOCK_PortB);
+ CLOCK_EnableClock(kCLOCK_PortC);
+ CLOCK_EnableClock(kCLOCK_PortD);
+ CLOCK_EnableClock(kCLOCK_PortE);
- /* Osc pins */
- PORT_SetPinMux(PORTA, 18UL, kPORT_PinDisabledOrAnalog);
- PORT_SetPinMux(PORTA, 19UL, kPORT_PinDisabledOrAnalog);
+ /* Osc pins */
+ PORT_SetPinMux(PORTA, 18UL, kPORT_PinDisabledOrAnalog);
+ PORT_SetPinMux(PORTA, 19UL, kPORT_PinDisabledOrAnalog);
- /* CAN0 pinmux config */
- PORT_SetPinMux(PORTA, 12u, kPORT_MuxAlt2); /* CAN0 TX */
- PORT_SetPinMux(PORTA, 13u, kPORT_MuxAlt2); /* CAN0 RX */
+ /* CAN0 pinmux config */
+ PORT_SetPinMux(PORTA, 12u, kPORT_MuxAlt2); /* CAN0 TX */
+ PORT_SetPinMux(PORTA, 13u, kPORT_MuxAlt2); /* CAN0 RX */
- /* CAN1 pinmux config */
- PORT_SetPinMux(PORTC, 17u, kPORT_MuxAlt2); /* CAN1 TX */
- PORT_SetPinMux(PORTC, 16u, kPORT_MuxAlt2); /* CAN1 RX */
+ /* CAN1 pinmux config */
+ PORT_SetPinMux(PORTC, 17u, kPORT_MuxAlt2); /* CAN1 TX */
+ PORT_SetPinMux(PORTC, 16u, kPORT_MuxAlt2); /* CAN1 RX */
- /* Debug UART3 pinmux config */
- PORT_SetPinMux(PORTB, 11u, kPORT_MuxAlt3); /* UART3 TX */
- PORT_SetPinMux(PORTB, 10u, kPORT_MuxAlt3); /* UART3 RX */
+#ifdef SDK_DEBUGCONSOLE
+ /* Debug UART3 pinmux config */
+ PORT_SetPinMux(PORTB, 11u, kPORT_MuxAlt3); /* UART3 TX */
+ PORT_SetPinMux(PORTB, 10u, kPORT_MuxAlt3); /* UART3 RX */
+#endif
- /* Resistive Touch panel pinmux config */
- PORT_SetPinMux(PORTE, 6u, kPORT_MuxAsGpio);
- GPIO_PinInit(GPIOE, 6u, &gpio_out_config);
- GPIO_SetPinsOutput(GPIOE, 1u << 6); /* Force X+*/
- PORT_SetPinMux(PORTB, 9u, kPORT_MuxAsGpio);
- GPIO_PinInit(GPIOB, 9u, &gpio_out_config);
- GPIO_ClearPinsOutput(GPIOB, 1u << 9); /* Force X-*/
- PORT_SetPinMux(PORTC, 5u, kPORT_MuxAsGpio);
- GPIO_PinInit(GPIOC, 5u, &gpio_out_config);
- GPIO_SetPinsOutput(GPIOC, 1u << 5); /* Force Y+*/
- PORT_SetPinMux(PORTC, 13u, kPORT_MuxAsGpio);
- GPIO_PinInit(GPIOC, 13u, &gpio_out_config);
- GPIO_ClearPinsOutput(GPIOC, 1u << 13); /* Force Y-*/
- PORT_SetPinMux(PORTB, 6UL, kPORT_PinDisabledOrAnalog); /* Sense X+ */
- PORT_SetPinMux(PORTB, 7UL, kPORT_PinDisabledOrAnalog); /* Sense X- */
- PORT_SetPinMux(PORTC, 8UL, kPORT_PinDisabledOrAnalog); /* Sense Y+ */
- PORT_SetPinMux(PORTC, 9UL, kPORT_PinDisabledOrAnalog); /* Sense Y- */
+#ifdef BOARD_USES_ADC
+ /* Resistive Touch panel pinmux config */
+ PORT_SetPinMux(PORTE, 6u, kPORT_MuxAsGpio);
+ GPIO_PinInit(GPIOE, 6u, &gpio_out_hi_config); /* Force X+*/
+ PORT_SetPinMux(PORTB, 9u, kPORT_MuxAsGpio);
+ GPIO_PinInit(GPIOB, 9u, &gpio_out_config); /* Force X-*/
+ PORT_SetPinMux(PORTC, 5u, kPORT_MuxAsGpio);
+ GPIO_PinInit(GPIOC, 5u, &gpio_out_hi_config); /* Force Y+*/
+ PORT_SetPinMux(PORTC, 13u, kPORT_MuxAsGpio);
+ GPIO_PinInit(GPIOC, 13u, &gpio_out_config); /* Force Y-*/
+ PORT_SetPinMux(PORTB, 6UL, kPORT_PinDisabledOrAnalog); /* Sense X+ */
+ GPIO_PinInit(GPIOB, 6u, &gpio_in_config);
+ PORT_SetPinMux(PORTB, 7UL, kPORT_PinDisabledOrAnalog); /* Sense X- */
+ GPIO_PinInit(GPIOB, 7u, &gpio_in_config);
+ PORT_SetPinMux(PORTC, 8UL, kPORT_PinDisabledOrAnalog); /* Sense Y+ */
+ GPIO_PinInit(GPIOC, 8u, &gpio_in_config);
+ PORT_SetPinMux(PORTC, 9UL, kPORT_PinDisabledOrAnalog); /* Sense Y- */
+ GPIO_PinInit(GPIOC, 9u, &gpio_in_config);
- /* SPI2 pinmux config */
- PORT_SetPinMux(PORTB, 21u, kPORT_MuxAlt2); /* SPI2_SCK */
- PORT_SetPinMux(PORTB, 22u, kPORT_MuxAlt2); /* SPI2_SOUT */
- PORT_SetPinMux(PORTB, 23u, kPORT_MuxAlt2); /* SPI2_SIN */
- PORT_SetPinMux(PORTB, 20u, kPORT_MuxAsGpio); /* SPI2_SS */
+ /* Apalis ADC pinmux config */
+ PORT_SetPinMux(PORTB, 0UL, kPORT_PinDisabledOrAnalog); /* ADC0 */
+ PORT_SetPinMux(PORTB, 1UL, kPORT_PinDisabledOrAnalog); /* ADC1 */
+ PORT_SetPinMux(PORTB, 2UL, kPORT_PinDisabledOrAnalog); /* ADC2 */
+ PORT_SetPinMux(PORTB, 3UL, kPORT_PinDisabledOrAnalog); /* ADC3 */
+#endif
+ /* SPI2 pinmux config */
+ PORT_SetPinMux(PORTB, 21u, kPORT_MuxAlt2); /* SPI2_SCK */
+ PORT_SetPinMux(PORTB, 22u, kPORT_MuxAlt2); /* SPI2_SOUT */
+ PORT_SetPinMux(PORTB, 23u, kPORT_MuxAlt2); /* SPI2_SIN */
+ PORT_SetPinMux(PORTB, 20u, kPORT_MuxAlt2); /* SPI2_SS */
+
+ /* Open Drain INT pins config */
+ od_config.mux = kPORT_MuxAsGpio;
+ od_config.openDrainEnable = kPORT_OpenDrainEnable;
+ od_config.pullSelect = kPORT_PullDisable;
+ od_config.slewRate = kPORT_FastSlewRate;
+ od_config.passiveFilterEnable = kPORT_PassiveFilterDisable;
+ od_config.driveStrength = kPORT_LowDriveStrength;
+ od_config.lockRegister = kPORT_UnlockRegister;
+ GPIO_PinInit(GPIOA, 16u, &gpio_out_hi_config);
+ PORT_SetPinConfig(PORTA, 16u, &od_config); /* MCU_INT1 */
+ GPIO_PinInit(GPIOA, 29u, &gpio_out_hi_config);
+ PORT_SetPinConfig(PORTA, 29u, &od_config); /* MCU_INT2 */
+ GPIO_PinInit(GPIOB, 8u, &gpio_out_config);
+ PORT_SetPinConfig(PORTB, 8u, &od_config); /* MCU_INT3 */
+ GPIO_PinInit(GPIOE, 26u, &gpio_out_config);
+ PORT_SetPinConfig(PORTE, 26u, &od_config); /* MCU_INT4 */
+ GPIO_PinInit(GPIOC, 19u, &gpio_out_hi_config);
+ PORT_SetPinConfig(PORTC, 19u, &od_config); /* PMIC_ONKEY */
+
+ /* GPIOs */
+ for (i = 0; i < sizeof(gpio_list)/sizeof(struct gpio_id); i++){
+ PORT_SetPinMux(gpio_list[i].port, gpio_list[i].pin, kPORT_MuxAsGpio);
+ GPIO_PinInit(gpio_list[i].gpio, gpio_list[i].pin, &gpio_in_config);
+ }
}
diff --git a/board/usb_host_config.h b/board/usb_host_config.h
new file mode 100644
index 0000000..0bde321
--- /dev/null
+++ b/board/usb_host_config.h
@@ -0,0 +1,204 @@
+/*
+ * Copyright (c) 2015 - 2016, Freescale Semiconductor, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * o Redistributions of source code must retain the above copyright notice, this list
+ * of conditions and the following disclaimer.
+ *
+ * o Redistributions in binary form must reproduce the above copyright notice, this
+ * list of conditions and the following disclaimer in the documentation and/or
+ * other materials provided with the distribution.
+ *
+ * o Neither the name of Freescale Semiconductor, Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _USB_HOST_CONFIG_H_
+#define _USB_HOST_CONFIG_H_
+
+/* Host Controller Enable */
+/*!
+ * @brief host khci instance count, meantime it indicates khci enable or disable.
+ * - if 0, host khci driver is disable.
+ * - if greater than 0, host khci driver is enable.
+ */
+#define USB_HOST_CONFIG_KHCI (1U)
+
+/*!
+ * @brief host ehci instance count, meantime it indicates ehci enable or disable.
+ * - if 0, host ehci driver is disable.
+ * - if greater than 0, host ehci driver is enable.
+ */
+#define USB_HOST_CONFIG_EHCI (0U)
+
+/* Common configuration macros for all controllers */
+
+/*!
+ * @brief host driver instance max count.
+ * for example: 2 - one for khci, one for ehci.
+ */
+#define USB_HOST_CONFIG_MAX_HOST (2U)
+
+/*!
+ * @brief host pipe max count.
+ * pipe is the host driver resource for device endpoint, one endpoint need one pipe.
+ */
+#define USB_HOST_CONFIG_MAX_PIPES (16U)
+
+/*!
+ * @brief host transfer max count.
+ * transfer is the host driver resource for data transmission mission, one transmission mission need one transfer.
+ */
+#define USB_HOST_CONFIG_MAX_TRANSFERS (16U)
+
+/*!
+ * @brief the max endpoint for one interface.
+ * the max endpoint descriptor number that one interface descriptor contain.
+ */
+#define USB_HOST_CONFIG_INTERFACE_MAX_EP (4U)
+
+/*!
+ * @brief the max interface for one configuration.
+ * the max interface descriptor number that one configuration descriptor can contain.
+ */
+#define USB_HOST_CONFIG_CONFIGURATION_MAX_INTERFACE (5U)
+
+/*!
+ * @brief the max power for one device.
+ * the max power the host can provide for one device.
+ */
+#define USB_HOST_CONFIG_MAX_POWER (250U)
+
+/*!
+ * @brief the max retries for enumeration.
+ * retry time when enumeration fail.
+ */
+#define USB_HOST_CONFIG_ENUMERATION_MAX_RETRIES (3U)
+
+/*!
+ * @brief the max retries for enumeration setup stall.
+ * the max times for one transfer can stall.
+ */
+#define USB_HOST_CONFIG_ENUMERATION_MAX_STALL_RETRIES (1U)
+
+/*!
+ * @brief the max NAK count for one transaction.
+ * when nak count reach to the value, the transaction fail.
+ */
+#define USB_HOST_CONFIG_MAX_NAK (3000U)
+
+/*! @brief Whether the transfer buffer is cache-enabled or not. */
+#define USB_HOST_CONFIG_BUFFER_PROPERTY_CACHEABLE (0U)
+
+/*! @brief if 1, enable usb compliance test codes; if 0, disable usb compliance test codes. */
+#define USB_HOST_CONFIG_COMPLIANCE_TEST (0U)
+
+/*! @brief if 1, class driver clear stall automatically; if 0, class driver don't clear stall. */
+#define USB_HOST_CONFIG_CLASS_AUTO_CLEAR_STALL (0U)
+
+/* KHCI configuration */
+#if ((defined USB_HOST_CONFIG_KHCI) && (USB_HOST_CONFIG_KHCI))
+
+/*!
+ * @brief khci dma align fix buffer size.
+ */
+#define USB_HOST_CONFIG_KHCI_DMA_ALIGN_BUFFER (64U)
+
+#endif
+
+/* EHCI configuration */
+#if ((defined USB_HOST_CONFIG_EHCI) && (USB_HOST_CONFIG_EHCI))
+
+/*!
+ * @brief ehci periodic frame list size.
+ * the value can be 1024, 512, 256, 128, 64, 32, 16 or 8.
+ */
+#define USB_HOST_CONFIG_EHCI_FRAME_LIST_SIZE (1024U)
+
+/*!
+ * @brief ehci QH max count.
+ */
+#define USB_HOST_CONFIG_EHCI_MAX_QH (8U)
+
+/*!
+ * @brief ehci QTD max count.
+ */
+#define USB_HOST_CONFIG_EHCI_MAX_QTD (8U)
+
+/*!
+ * @brief ehci ITD max count.
+ */
+#define USB_HOST_CONFIG_EHCI_MAX_ITD (0U)
+
+/*!
+ * @brief ehci SITD max count.
+ */
+#define USB_HOST_CONFIG_EHCI_MAX_SITD (0U)
+
+#endif
+
+/*!
+ * @brief host HUB class instance count, meantime it indicates HUB class enable or disable.
+ * - if 0, host HUB class driver is disable.
+ * - if greater than 0, host HUB class driver is enable.
+ */
+#define USB_HOST_CONFIG_HUB (0U)
+
+/*!
+ * @brief host HID class instance count, meantime it indicates HID class enable or disable.
+ * - if 0, host HID class driver is disable.
+ * - if greater than 0, host HID class driver is enable.
+ */
+#define USB_HOST_CONFIG_HID (0U)
+
+/*!
+ * @brief host MSD class instance count, meantime it indicates MSD class enable or disable.
+ * - if 0, host MSD class driver is disable.
+ * - if greater than 0, host MSD class driver is enable.
+ */
+#define USB_HOST_CONFIG_MSD (0U)
+
+/*!
+ * @brief host CDC class instance count, meantime it indicates CDC class enable or disable.
+ * - if 0, host CDC class driver is disable.
+ * - if greater than 0, host CDC class driver is enable.
+ */
+#define USB_HOST_CONFIG_CDC (0U)
+
+/*!
+ * @brief host AUDIO class instance count, meantime it indicates AUDIO class enable or disable.
+ * - if 0, host AUDIO class driver is disable.
+ * - if greater than 0, host AUDIO class driver is enable.
+ */
+#define USB_HOST_CONFIG_AUDIO (0U)
+
+/*!
+ * @brief host PHDC class instance count, meantime it indicates PHDC class enable or disable.
+ * - if 0, host PHDC class driver is disable.
+ * - if greater than 0, host PHDC class driver is enable.
+ */
+#define USB_HOST_CONFIG_PHDC (0U)
+
+/*!
+ * @brief host printer class instance count, meantime it indicates printer class enable or disable.
+ * - if 0, host printer class driver is disable.
+ * - if greater than 0, host printer class driver is enable.
+ */
+#define USB_HOST_CONFIG_PRINTER (0U)
+
+#endif /* _USB_HOST_CONFIG_H_ */
diff --git a/drivers/fsl_adc16.c b/drivers/fsl_adc16.c
index 4fee1a8..800d1dc 100644
--- a/drivers/fsl_adc16.c
+++ b/drivers/fsl_adc16.c
@@ -152,7 +152,7 @@ status_t ADC16_DoAutoCalibration(ADC_Type *base)
volatile uint32_t tmp32; /* 'volatile' here is for the dummy read of ADCx_R[0] register. */
status_t status = kStatus_Success;
- /* The calibration would be failed when in hardwar mode.
+ /* The calibration would be failed when in hardware mode.
* Remember the hardware trigger state here and restore it later if the hardware trigger is enabled.*/
if (0U != (ADC_SC2_ADTRG_MASK & base->SC2))
{
diff --git a/k20_tester_Debug_Segger.launch b/k20_tester_Debug_Segger.launch
index b856cca..4c60bc3 100644
--- a/k20_tester_Debug_Segger.launch
+++ b/k20_tester_Debug_Segger.launch
@@ -1,31 +1,70 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<launchConfiguration type="ilg.gnuarmeclipse.debug.gdbjtag.jlink.launchConfigurationType">
+<booleanAttribute key="ilg.gnuarmeclipse.debug.gdbjtag.jlink.doConnectToRunning" value="false"/>
+<booleanAttribute key="ilg.gnuarmeclipse.debug.gdbjtag.jlink.doContinue" value="true"/>
+<booleanAttribute key="ilg.gnuarmeclipse.debug.gdbjtag.jlink.doDebugInRam" value="false"/>
+<booleanAttribute key="ilg.gnuarmeclipse.debug.gdbjtag.jlink.doFirstReset" value="true"/>
+<booleanAttribute key="ilg.gnuarmeclipse.debug.gdbjtag.jlink.doGdbServerAllocateConsole" value="true"/>
+<booleanAttribute key="ilg.gnuarmeclipse.debug.gdbjtag.jlink.doGdbServerAllocateSemihostingConsole" value="true"/>
+<booleanAttribute key="ilg.gnuarmeclipse.debug.gdbjtag.jlink.doGdbServerInitRegs" value="true"/>
+<booleanAttribute key="ilg.gnuarmeclipse.debug.gdbjtag.jlink.doGdbServerLocalOnly" value="true"/>
+<booleanAttribute key="ilg.gnuarmeclipse.debug.gdbjtag.jlink.doGdbServerSilent" value="false"/>
+<booleanAttribute key="ilg.gnuarmeclipse.debug.gdbjtag.jlink.doGdbServerVerifyDownload" value="true"/>
+<booleanAttribute key="ilg.gnuarmeclipse.debug.gdbjtag.jlink.doSecondReset" value="true"/>
+<booleanAttribute key="ilg.gnuarmeclipse.debug.gdbjtag.jlink.doStartGdbServer" value="true"/>
+<booleanAttribute key="ilg.gnuarmeclipse.debug.gdbjtag.jlink.enableFlashBreakpoints" value="true"/>
+<booleanAttribute key="ilg.gnuarmeclipse.debug.gdbjtag.jlink.enableSemihosting" value="true"/>
+<booleanAttribute key="ilg.gnuarmeclipse.debug.gdbjtag.jlink.enableSemihostingIoclientGdbClient" value="false"/>
+<booleanAttribute key="ilg.gnuarmeclipse.debug.gdbjtag.jlink.enableSemihostingIoclientTelnet" value="true"/>
+<booleanAttribute key="ilg.gnuarmeclipse.debug.gdbjtag.jlink.enableSwo" value="true"/>
+<intAttribute key="ilg.gnuarmeclipse.debug.gdbjtag.jlink.firstResetSpeed" value="1000"/>
+<stringAttribute key="ilg.gnuarmeclipse.debug.gdbjtag.jlink.firstResetType" value=""/>
+<stringAttribute key="ilg.gnuarmeclipse.debug.gdbjtag.jlink.gdbClientOtherCommands" value="set mem inaccessible-by-default off"/>
+<stringAttribute key="ilg.gnuarmeclipse.debug.gdbjtag.jlink.gdbClientOtherOptions" value=""/>
<stringAttribute key="ilg.gnuarmeclipse.debug.gdbjtag.jlink.gdbServerConnection" value="usb"/>
+<stringAttribute key="ilg.gnuarmeclipse.debug.gdbjtag.jlink.gdbServerConnectionAddress" value=""/>
<stringAttribute key="ilg.gnuarmeclipse.debug.gdbjtag.jlink.gdbServerDebugInterface" value="swd"/>
<stringAttribute key="ilg.gnuarmeclipse.debug.gdbjtag.jlink.gdbServerDeviceEndianness" value="little"/>
<stringAttribute key="ilg.gnuarmeclipse.debug.gdbjtag.jlink.gdbServerDeviceName" value="MK20DN512xxx10"/>
<stringAttribute key="ilg.gnuarmeclipse.debug.gdbjtag.jlink.gdbServerDeviceSpeed" value="1000"/>
<stringAttribute key="ilg.gnuarmeclipse.debug.gdbjtag.jlink.gdbServerExecutable" value="${jlink_path}/${jlink_gdbserver}"/>
+<intAttribute key="ilg.gnuarmeclipse.debug.gdbjtag.jlink.gdbServerGdbPortNumber" value="2331"/>
+<stringAttribute key="ilg.gnuarmeclipse.debug.gdbjtag.jlink.gdbServerLog" value=""/>
+<stringAttribute key="ilg.gnuarmeclipse.debug.gdbjtag.jlink.gdbServerOther" value="-singlerun -strict -timeout 0 -nogui -rtos /opt/SEGGER/JLink/GDBServer/RTOSPlugin_FreeRTOS.so"/>
<intAttribute key="ilg.gnuarmeclipse.debug.gdbjtag.jlink.gdbServerSwoPortNumber" value="2332"/>
<intAttribute key="ilg.gnuarmeclipse.debug.gdbjtag.jlink.gdbServerTelnetPortNumber" value="2332"/>
+<stringAttribute key="ilg.gnuarmeclipse.debug.gdbjtag.jlink.interfaceSpeed" value="adaptive"/>
+<stringAttribute key="ilg.gnuarmeclipse.debug.gdbjtag.jlink.otherInitCommands" value=""/>
+<stringAttribute key="ilg.gnuarmeclipse.debug.gdbjtag.jlink.otherRunCommands" value=""/>
+<stringAttribute key="ilg.gnuarmeclipse.debug.gdbjtag.jlink.secondResetType" value=""/>
+<intAttribute key="ilg.gnuarmeclipse.debug.gdbjtag.jlink.swoEnableTargetCpuFreq" value="0"/>
<stringAttribute key="ilg.gnuarmeclipse.debug.gdbjtag.jlink.swoEnableTargetPortMask" value="0x1"/>
<intAttribute key="ilg.gnuarmeclipse.debug.gdbjtag.jlink.swoEnableTargetSwoFreq" value="0"/>
+<stringAttribute key="org.eclipse.cdt.debug.gdbjtag.core.imageFileName" value=""/>
+<stringAttribute key="org.eclipse.cdt.debug.gdbjtag.core.imageOffset" value=""/>
<stringAttribute key="org.eclipse.cdt.debug.gdbjtag.core.ipAddress" value="localhost"/>
<stringAttribute key="org.eclipse.cdt.debug.gdbjtag.core.jtagDevice" value="GNU ARM J-Link"/>
<booleanAttribute key="org.eclipse.cdt.debug.gdbjtag.core.loadImage" value="true"/>
<booleanAttribute key="org.eclipse.cdt.debug.gdbjtag.core.loadSymbols" value="true"/>
+<stringAttribute key="org.eclipse.cdt.debug.gdbjtag.core.pcRegister" value=""/>
<intAttribute key="org.eclipse.cdt.debug.gdbjtag.core.portNumber" value="2331"/>
<booleanAttribute key="org.eclipse.cdt.debug.gdbjtag.core.setPcRegister" value="false"/>
<booleanAttribute key="org.eclipse.cdt.debug.gdbjtag.core.setStopAt" value="true"/>
<stringAttribute key="org.eclipse.cdt.debug.gdbjtag.core.stopAt" value="main"/>
+<stringAttribute key="org.eclipse.cdt.debug.gdbjtag.core.symbolsFileName" value=""/>
+<stringAttribute key="org.eclipse.cdt.debug.gdbjtag.core.symbolsOffset" value=""/>
<booleanAttribute key="org.eclipse.cdt.debug.gdbjtag.core.useFileForImage" value="false"/>
<booleanAttribute key="org.eclipse.cdt.debug.gdbjtag.core.useFileForSymbols" value="false"/>
<booleanAttribute key="org.eclipse.cdt.debug.gdbjtag.core.useProjBinaryForImage" value="true"/>
<booleanAttribute key="org.eclipse.cdt.debug.gdbjtag.core.useProjBinaryForSymbols" value="true"/>
<booleanAttribute key="org.eclipse.cdt.debug.gdbjtag.core.useRemoteTarget" value="true"/>
<stringAttribute key="org.eclipse.cdt.dsf.gdb.DEBUG_NAME" value="${cross_prefix}gdb${cross_suffix}"/>
+<booleanAttribute key="org.eclipse.cdt.dsf.gdb.UPDATE_THREADLIST_ON_SUSPEND" value="false"/>
+<intAttribute key="org.eclipse.cdt.launch.ATTR_BUILD_BEFORE_LAUNCH_ATTR" value="2"/>
+<stringAttribute key="org.eclipse.cdt.launch.DEBUGGER_REGISTER_GROUPS" value=""/>
<stringAttribute key="org.eclipse.cdt.launch.PROGRAM_NAME" value="Debug/k20_tester.elf"/>
<stringAttribute key="org.eclipse.cdt.launch.PROJECT_ATTR" value="k20_tester"/>
+<booleanAttribute key="org.eclipse.cdt.launch.PROJECT_BUILD_CONFIG_AUTO_ATTR" value="false"/>
<stringAttribute key="org.eclipse.cdt.launch.PROJECT_BUILD_CONFIG_ID_ATTR" value=""/>
<listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_PATHS">
<listEntry value="/k20_tester"/>
@@ -33,6 +72,7 @@
<listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_TYPES">
<listEntry value="4"/>
</listAttribute>
-<stringAttribute key="org.eclipse.dsf.launch.MEMORY_BLOCKS" value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&lt;memoryBlockExpressionList context=&quot;reserved-for-future-use&quot;&gt;&#10;"/>
+<stringAttribute key="org.eclipse.dsf.launch.MEMORY_BLOCKS" value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#10;&lt;memoryBlockExpressionList context=&quot;Context string&quot;/&gt;&#10;"/>
<stringAttribute key="process_factory_id" value="org.eclipse.cdt.dsf.gdb.GdbProcessFactory"/>
+<stringAttribute key="saved_expressions&lt;seperator&gt;Unknown" value="0xE000E3F0,0xE000E3F0+0x35,0xE000E3F0+0x35+0x10"/>
</launchConfiguration>
diff --git a/source/adc_task.c b/source/adc_task.c
new file mode 100644
index 0000000..67d5bd0
--- /dev/null
+++ b/source/adc_task.c
@@ -0,0 +1,343 @@
+/*
+ * adc_task.c
+ *
+ */
+
+#include "com_task.h"
+#include "adc_task.h"
+#include "fsl_adc16.h"
+#include "fsl_port.h"
+#include "errno.h"
+#include "stdlib.h"
+
+/*
+ * Apalis ADC0 -> PTB0 -> ADC0_SE8
+ * Apalis ADC1 -> PTB1 -> ADC0_SE9
+ * Apalis ADC2 -> PTB2 -> ADC0_SE12
+ * Apalis ADC3 -> PTB3 -> ADC0_SE13
+ *
+ * Touch screen:
+ * Force:
+ * PTE6 X+ hi-off
+ * PTB9 X- lo-off
+ * PTC5 Y+ hi-off
+ * PTC13 Y- lo-off
+ * Sense:
+ * PTB7 -> ADC1_SE13 X-
+ * PTB6 -> ADC1_SE12 X+
+ * PTC9 -> ADC1_SE5b Y-
+ * PTC8 -> ADC1_SE4b Y+
+ */
+const uint8_t adc0_channels[ADC0_CHANNEL_CNT] = {8, 9, 12, 13};
+const uint8_t tsc_channels[TSC0_CHANNEL_CNT] = {13, 12, 5, 4};
+
+static int adc_task_init(void)
+{
+ adc16_config_t adc_config;
+#ifdef BOARD_USES_ADC
+ ADC16_GetDefaultConfig(&adc_config);
+ adc_config.resolution = kADC16_ResolutionSE16Bit;
+ adc_config.longSampleMode = kADC16_LongSampleDisabled;
+ adc_config.clockDivider = kADC16_ClockDivider8;
+ ADC16_Init(ADC0, &adc_config);
+ ADC16_SetHardwareAverage(ADC0, kADC16_HardwareAverageDisabled);
+ return 0;
+#else
+ return -ENODEV;
+#endif
+}
+
+static int tsc_task_init(void)
+{
+ adc16_config_t adc_config;
+#ifdef BOARD_USES_ADC
+ ADC16_GetDefaultConfig(&adc_config);
+ adc_config.resolution = kADC16_ResolutionSE12Bit;
+ adc_config.longSampleMode = kADC16_LongSampleDisabled;
+ adc_config.clockDivider = kADC16_ClockDivider8;
+ ADC16_Init(ADC1, &adc_config);
+ ADC16_SetChannelMuxMode(ADC1, kADC16_ChannelMuxB);
+ ADC16_SetHardwareAverage(ADC1, kADC16_HardwareAverageCount32);
+ return 0;
+#else
+ return -ENODEV;
+#endif
+}
+
+#ifdef BOARD_USES_ADC
+static void ts_force_drive(uint8_t xm, uint8_t xp, uint8_t ym, uint8_t yp)
+{
+ if (xp == 0)
+ GPIO_SetPinsOutput(GPIOE, 1 << 6);
+ else
+ GPIO_ClearPinsOutput(GPIOE, 1 << 6);
+
+ if (xm > 0)
+ GPIO_SetPinsOutput(GPIOB, 1 << 9);
+ else
+ GPIO_ClearPinsOutput(GPIOB, 1 << 9);
+
+ if (yp == 0)
+ GPIO_SetPinsOutput(GPIOC, 1 << 5);
+ else
+ GPIO_ClearPinsOutput(GPIOC, 1 << 5);
+
+ if (ym > 0)
+ GPIO_SetPinsOutput(GPIOC, 1 << 13);
+ else
+ GPIO_ClearPinsOutput(GPIOC, 1 << 13);
+}
+
+static inline uint16_t do_adc_conversion(ADC_Type *base, adc16_channel_config_t *channel)
+{
+ ADC16_SetChannelConfig(base, 0, channel);
+ while(ADC16_GetChannelStatusFlags(base, 0) == 0){vTaskDelay(0);}
+ return (uint16_t)ADC16_GetChannelConversionValue(base, 0);
+}
+
+void adc_task(void *pvParameters)
+{
+ adc16_channel_config_t channel;
+ int i;
+ if (adc_task_init() < 0)
+ return;
+
+ channel.enableDifferentialConversion = false;
+ channel.enableInterruptOnConversionCompleted = false;
+
+ while(1) {
+ for (i = 0; i < ADC0_CHANNEL_CNT;i ++){
+ channel.channelNumber = adc0_channels[i];
+ gen_regs.adc[i] = do_adc_conversion(ADC0, &channel);
+ }
+ vTaskDelay(1);
+ }
+
+}
+
+enum touch_status {
+ PEN_UP,
+ PEN_DOWN
+};
+
+#define MIN_TOUCH_DET 5
+
+/* PTB7 -> ADC1_SE13 X-
+ * PTB6 -> ADC1_SE12 X+
+ * PTC9 -> ADC1_SE5b Y-
+ * PTC8 -> ADC1_SE4b Y+
+ */
+void tsc_task(void *pvParameters)
+{
+ adc16_channel_config_t channel;
+ port_pin_config_t pin_config_pd, pin_config_ana;
+ int old_status, status = PEN_UP;
+ int irq_stat = 0;
+ if (tsc_task_init() < 0)
+ return;
+
+ pin_config_pd.mux = kPORT_MuxAsGpio;
+ pin_config_pd.openDrainEnable = kPORT_OpenDrainDisable;
+ pin_config_pd.pullSelect = kPORT_PullDown;
+ pin_config_pd.slewRate = kPORT_FastSlewRate;
+ pin_config_pd.passiveFilterEnable = kPORT_PassiveFilterDisable;
+ pin_config_pd.driveStrength = kPORT_LowDriveStrength;
+ pin_config_pd.lockRegister = kPORT_UnlockRegister;
+
+ pin_config_ana.mux = kPORT_PinDisabledOrAnalog;
+ pin_config_ana.openDrainEnable = kPORT_OpenDrainDisable;
+ pin_config_ana.pullSelect = kPORT_PullDisable;
+ pin_config_ana.slewRate = kPORT_FastSlewRate;
+ pin_config_ana.passiveFilterEnable = kPORT_PassiveFilterDisable;
+ pin_config_ana.driveStrength = kPORT_LowDriveStrength;
+ pin_config_ana.lockRegister = kPORT_UnlockRegister;
+
+ channel.enableDifferentialConversion = false;
+ channel.enableInterruptOnConversionCompleted = false;
+
+ while(1) {
+ //Touch detect power Y+, enable pulldown on xp and read xp GPIO
+ ts_force_drive(0, 0, 0, 1);
+ PORT_SetPinConfig(PORTB, 6u, &pin_config_pd);
+ vTaskDelay(10);
+ old_status = status;
+ status = GPIO_ReadPinInput(GPIOB, 6u) ? PEN_DOWN:PEN_UP;
+ PORT_SetPinConfig(PORTB, 6u, &pin_config_ana);
+
+ if (status != old_status)
+ irq_stat = 0;
+
+ if (status == PEN_DOWN) {
+ //probe ym with power across Y plane
+ ts_force_drive(0, 0, 1, 1);
+ vTaskDelay(10);
+ channel.channelNumber = tsc_channels[0];
+ gen_regs.tsc_ym = do_adc_conversion(ADC1, &channel);
+
+ //probe yp with power across Y plane
+ channel.channelNumber = tsc_channels[1];
+ gen_regs.tsc_yp = do_adc_conversion(ADC1, &channel);
+
+ //probe xm with power across X plane
+ ts_force_drive(1, 1, 0, 0);
+ vTaskDelay(10);
+ channel.channelNumber = tsc_channels[2];
+ gen_regs.tsc_xm = do_adc_conversion(ADC1, &channel);
+
+ //probe xp with power across X plane
+ channel.channelNumber = tsc_channels[3];
+ gen_regs.tsc_xp = do_adc_conversion(ADC1, &channel);
+
+ if (irq_stat == 0) {
+ generate_irq(APALIS_TK1_K20_TSC_IRQ);
+ irq_stat = 1;
+ }
+ } else {
+ gen_regs.tsc_xm = 0;
+ gen_regs.tsc_xp = 0;
+ gen_regs.tsc_ym = 0;
+ gen_regs.tsc_yp = 0;
+ vTaskDelay(20);
+ if (irq_stat == 0) {
+ generate_irq(APALIS_TK1_K20_TSC_IRQ);
+ irq_stat = 1;
+ }
+ }
+ vTaskDelay(10);
+ }
+
+}
+
+int tsc_registers(uint8_t *rx_buf, uint8_t *tx_buf)
+{
+ if (rx_buf[0] == APALIS_TK1_K20_READ_INST) {
+ switch (rx_buf[1]) {
+ case APALIS_TK1_K20_TSCREG:
+ tx_buf[0] = 0x00;
+ return 1;
+ case APALIS_TK1_K20_TSC_XML:
+ tx_buf[0] = gen_regs.tsc_xm & 0xFF;
+ return 1;
+ case APALIS_TK1_K20_TSC_XMH:
+ tx_buf[0] = (gen_regs.tsc_xm >> 8) & 0xFF;
+ return 1;
+ case APALIS_TK1_K20_TSC_XPL:
+ tx_buf[0] = gen_regs.tsc_xp & 0xFF;
+ return 1;
+ case APALIS_TK1_K20_TSC_XPH:
+ tx_buf[0] = (gen_regs.tsc_xp >> 8) & 0xFF;
+ return 1;
+ case APALIS_TK1_K20_TSC_YML:
+ tx_buf[0] = gen_regs.tsc_ym & 0xFF;
+ return 1;
+ case APALIS_TK1_K20_TSC_YMH:
+ tx_buf[0] = (gen_regs.tsc_ym >> 8) & 0xFF;
+ return 1;
+ case APALIS_TK1_K20_TSC_YPL:
+ tx_buf[0] = gen_regs.tsc_yp & 0xFF;
+ return 1;
+ case APALIS_TK1_K20_TSC_YPH:
+ tx_buf[0] = (gen_regs.tsc_yp >> 8) & 0xFF;
+ return 1;
+ default:
+ return -ENOENT;
+ }
+ } else if (rx_buf[0] == APALIS_TK1_K20_WRITE_INST) {
+ switch (rx_buf[1]) {
+ case APALIS_TK1_K20_TSCREG:
+ return -ENOENT;
+ default:
+ return -ENOENT;
+ }
+ } else if (rx_buf[0] == APALIS_TK1_K20_BULK_READ_INST) {
+ switch (rx_buf[1]){
+ case APALIS_TK1_K20_TSC_XML:
+ tx_buf[0] = gen_regs.tsc_xm & 0xFF;
+ tx_buf[1] = (gen_regs.tsc_xm >> 8) & 0xFF;
+ return 2;
+ case APALIS_TK1_K20_TSC_XPL:
+ tx_buf[0] = gen_regs.tsc_xp & 0xFF;
+ tx_buf[1] = (gen_regs.tsc_xp >> 8) & 0xFF;
+ return 2;
+ case APALIS_TK1_K20_TSC_YML:
+ tx_buf[0] = gen_regs.tsc_ym & 0xFF;
+ tx_buf[1] = (gen_regs.tsc_ym >> 8) & 0xFF;
+ return 2;
+ case APALIS_TK1_K20_TSC_YPL:
+ tx_buf[0] = gen_regs.tsc_yp & 0xFF;
+ tx_buf[1] = (gen_regs.tsc_yp >> 8) & 0xFF;
+ return 2;
+ default:
+ return -ENOENT;
+ }
+ }
+ return -ENOENT;
+}
+
+int adc_registers(uint8_t *rx_buf, uint8_t *tx_buf)
+{
+ if (rx_buf[0] == APALIS_TK1_K20_READ_INST) {
+ switch (rx_buf[1]) {
+ case APALIS_TK1_K20_ADCREG:
+ tx_buf[0] = 0x00;
+ return 1;
+ case APALIS_TK1_K20_ADC_CH0L:
+ tx_buf[0] = gen_regs.adc[0] & 0xFF;
+ return 1;
+ case APALIS_TK1_K20_ADC_CH0H:
+ tx_buf[0] = (gen_regs.adc[0] >> 8) & 0xFF;
+ return 1;
+ case APALIS_TK1_K20_ADC_CH1L:
+ tx_buf[0] = gen_regs.adc[1] & 0xFF;
+ return 1;
+ case APALIS_TK1_K20_ADC_CH1H:
+ tx_buf[0] = (gen_regs.adc[1] >> 8) & 0xFF;
+ return 1;
+ case APALIS_TK1_K20_ADC_CH2L:
+ tx_buf[0] = gen_regs.adc[2] & 0xFF;
+ return 1;
+ case APALIS_TK1_K20_ADC_CH2H:
+ tx_buf[0] = (gen_regs.adc[2] >> 8) & 0xFF;
+ return 1;
+ case APALIS_TK1_K20_ADC_CH3L:
+ tx_buf[0] = gen_regs.adc[3] & 0xFF;
+ return 1;
+ case APALIS_TK1_K20_ADC_CH3H:
+ tx_buf[0] = (gen_regs.adc[3] >> 8) & 0xFF;
+ return 1;
+ default:
+ return -ENOENT;
+ }
+ } else if (rx_buf[0] == APALIS_TK1_K20_WRITE_INST) {
+ switch (rx_buf[1]) {
+ case APALIS_TK1_K20_ADCREG:
+ return -ENOENT;
+ default:
+ return -ENOENT;
+ }
+ } else if (rx_buf[0] == APALIS_TK1_K20_BULK_READ_INST) {
+ switch (rx_buf[1]){
+ case APALIS_TK1_K20_ADC_CH0L:
+ tx_buf[0] = gen_regs.adc[0] & 0xFF;
+ tx_buf[1] = (gen_regs.adc[0] >> 8) & 0xFF;
+ return 2;
+ case APALIS_TK1_K20_ADC_CH1L:
+ tx_buf[0] = gen_regs.adc[1] & 0xFF;
+ tx_buf[1] = (gen_regs.adc[1] >> 8) & 0xFF;
+ return 2;
+ case APALIS_TK1_K20_ADC_CH2L:
+ tx_buf[0] = gen_regs.adc[2] & 0xFF;
+ tx_buf[1] = (gen_regs.adc[2] >> 8) & 0xFF;
+ return 2;
+ case APALIS_TK1_K20_ADC_CH3L:
+ tx_buf[0] = gen_regs.adc[3] & 0xFF;
+ tx_buf[1] = (gen_regs.adc[3] >> 8) & 0xFF;
+ return 2;
+
+ default:
+ return -ENOENT;
+ }
+ }
+ return -ENOENT;
+}
+#endif
diff --git a/source/adc_task.h b/source/adc_task.h
new file mode 100644
index 0000000..3dafddb
--- /dev/null
+++ b/source/adc_task.h
@@ -0,0 +1,19 @@
+/*
+ * adc_task.h
+ *
+ */
+
+#ifndef SOURCE_ADC_TASK_H_
+#define SOURCE_ADC_TASK_H_
+#include "board.h"
+
+#ifdef BOARD_USES_ADC
+TaskHandle_t adc_task_handle;
+TaskHandle_t tsc_task_handle;
+void adc_task(void *pvParameters);
+void tsc_task(void *pvParameters);
+int adc_registers(uint8_t *rx_buf, uint8_t *tx_buf);
+int tsc_registers(uint8_t *rx_buf, uint8_t *tx_buf);
+#endif
+
+#endif /* SOURCE_ADC_TASK_H_ */
diff --git a/source/com_task.c b/source/com_task.c
new file mode 100644
index 0000000..348c3e1
--- /dev/null
+++ b/source/com_task.c
@@ -0,0 +1,205 @@
+
+#include "com_task.h"
+#include "gpio_ext.h"
+#include "adc_task.h"
+
+/* Put FW version at known address in binary. Make it 32-bit to have room for the future*/
+const uint32_t __attribute__((section(".FwVersion"))) fw_version = APALIS_TK1_K20_FW_VER;
+
+#define MAX_TRANSFER_SIZE 32U
+static dspi_slave_handle_t spi_handle;
+static uint8_t slaveRxData[MAX_TRANSFER_SIZE] = {0U};
+static uint8_t slaveTxData[MAX_TRANSFER_SIZE] = {0U};
+
+void generate_irq(uint8_t irq) {
+ gen_regs.irq = gen_regs.irq | BIT(irq);
+ /* Toggle INT1 pin */
+ GPIO_TogglePinsOutput(GPIOA, 1u << 16u);
+}
+
+void clear_irq_flag(uint8_t irq) {
+ gen_regs.irq = ~irq & gen_regs.irq;
+}
+
+uint8_t get_control_reg()
+{
+ return gen_regs.control;
+
+}
+
+void set_control_reg(uint8_t value)
+{
+ gen_regs.control = value;
+}
+
+uint8_t get_status_reg()
+{
+ return gen_regs.status;
+
+}
+
+void set_status_reg(uint8_t value)
+{
+ gen_regs.status = value;
+}
+
+uint8_t get_mask_reg()
+{
+ return gen_regs.irq_mask;
+
+}
+
+void set_mask_reg(uint8_t value)
+{
+ gen_regs.irq_mask = value;
+}
+
+uint8_t get_irq_reg()
+{
+ return gen_regs.irq;
+
+}
+
+void set_irq_reg(uint8_t value)
+{
+ /* Clear IRQ flag on 1 */
+ clear_irq_flag(value);
+
+}
+
+int inline general_registers(uint8_t *rx_buf, uint8_t * tx_buf) {
+
+ if (rx_buf[0] == APALIS_TK1_K20_READ_INST) {
+ switch (rx_buf[1]) {
+ case APALIS_TK1_K20_STAREG:
+ tx_buf[0] = get_status_reg();
+ return 1;
+ case APALIS_TK1_K20_REVREG:
+ tx_buf[0] = APALIS_TK1_K20_FW_VER;
+ return 1;
+ case APALIS_TK1_K20_IRQREG:
+ tx_buf[0] = get_irq_reg();
+ return 1;
+ case APALIS_TK1_K20_CTRREG:
+ tx_buf[0] = get_control_reg();
+ return 1;
+ case APALIS_TK1_K20_MSQREG:
+ tx_buf[0] = get_mask_reg();
+ return 1;
+ default:
+ return -ENOENT;
+ }
+ } else if (rx_buf[0] == APALIS_TK1_K20_WRITE_INST) {
+ switch (rx_buf[1]) {
+ case APALIS_TK1_K20_STAREG:
+ set_status_reg(rx_buf[2]);
+ return 0;
+ case APALIS_TK1_K20_REVREG:
+ return -ENOENT;
+ case APALIS_TK1_K20_IRQREG:
+ set_irq_reg(rx_buf[2]);
+ return 0;
+ case APALIS_TK1_K20_CTRREG:
+ set_control_reg(rx_buf[2]);
+ return 0;
+ case APALIS_TK1_K20_MSQREG:
+ set_mask_reg(rx_buf[2]);
+ return 0;
+ default:
+ return -ENOENT;
+ }
+ }
+
+
+ return -ENOENT;
+}
+
+static void SPI_callback(SPI_Type *base, dspi_slave_handle_t *handle, status_t status, void *userData)
+{
+ callback_message_t * cb = (callback_message_t*) userData;
+ BaseType_t reschedule = pdFALSE;
+
+ if (status == kStatus_Success)
+ {
+ xSemaphoreGiveFromISR(cb->sem, &reschedule);
+ }
+
+ if (status == kStatus_DSPI_Error)
+ {
+ __NOP();
+ }
+ portYIELD_FROM_ISR(reschedule);
+}
+
+static void SPI_init() {
+ dspi_slave_config_t slaveConfig;
+ /* Slave config */
+ slaveConfig.whichCtar = kDSPI_Ctar0;
+ slaveConfig.ctarConfig.bitsPerFrame = 8;
+ slaveConfig.ctarConfig.cpol = kDSPI_ClockPolarityActiveHigh;
+ slaveConfig.ctarConfig.cpha = kDSPI_ClockPhaseSecondEdge;
+ slaveConfig.enableContinuousSCK = true;
+ slaveConfig.enableRxFifoOverWrite = false;
+ slaveConfig.enableModifiedTimingFormat = false;
+ slaveConfig.samplePoint = kDSPI_SckToSin0Clock;
+
+ DSPI_SlaveInit(SPI2, &slaveConfig);
+ DSPI_SlaveTransferCreateHandle(SPI2, &spi_handle, SPI_callback, spi_handle.userData);
+
+ /* Set dspi slave interrupt priority higher. */
+ NVIC_SetPriority(SPI2_IRQn, 5U);
+ GPIO_ClearPinsOutput(GPIOA, 1u << 29u); /* INT2 active */
+ PRINTF("SPI init done \r\n");
+
+}
+
+void spi_task(void *pvParameters) {
+ callback_message_t cb_msg;
+ dspi_transfer_t slaveXfer;
+ int ret;
+
+ cb_msg.sem = xSemaphoreCreateBinary();
+ spi_handle.userData = &cb_msg;
+ SPI_init();
+ GPIO_SetPinsOutput(GPIOA, 1u << 29u); /* INT2 idle */
+
+ while(1){
+ slaveXfer.txData = slaveTxData;
+ slaveXfer.rxData = slaveRxData;
+ slaveXfer.dataSize = 3;
+ slaveXfer.configFlags = kDSPI_SlaveCtar0;
+ /* Wait for instructions from SoC */
+ DSPI_SlaveTransferNonBlocking(SPI2, &spi_handle, &slaveXfer);
+ xSemaphoreTake(cb_msg.sem, portMAX_DELAY);
+ if (slaveRxData[1] <= 0x05) {
+ ret = general_registers(slaveRxData, &slaveTxData[1]);
+#ifdef BOARD_USES_ADC
+ } else if ((slaveRxData[1] >= APALIS_TK1_K20_ADCREG) && (slaveRxData[1] <= APALIS_TK1_K20_ADC_CH3H)) {
+ ret = adc_registers(slaveRxData, &slaveTxData[1]);
+
+ } else if ((slaveRxData[1] >= APALIS_TK1_K20_TSCREG) && (slaveRxData[1] <= APALIS_TK1_K20_TSC_YPH)) {
+ ret = tsc_registers(slaveRxData, &slaveTxData[1]);
+#endif
+ } else if ((slaveRxData[1] >= APALIS_TK1_K20_GPIOREG) && (slaveRxData[1] <= APALIS_TK1_K20_GPIO_STA)) {
+ ret = gpio_registers(slaveRxData, &slaveTxData[1]);
+
+ } else {
+ /* Register not defined */
+ ret = -EINVAL;
+ }
+
+ if (ret < 0) {
+ slaveTxData[0] = TK1_K20_INVAL;
+ slaveTxData[1] = TK1_K20_INVAL;
+ } else {
+ slaveTxData[0] = TK1_K20_SENTINEL;
+ }
+
+ if (slaveRxData[0] == APALIS_TK1_K20_READ_INST || slaveRxData[0] == APALIS_TK1_K20_BULK_READ_INST)
+ {
+ slaveXfer.dataSize = (ret >= 0) ? (ret + 1):2; /* Extra byte is for sentinel */
+ DSPI_SlaveTransferNonBlocking(SPI2, &spi_handle, &slaveXfer);
+ xSemaphoreTake(cb_msg.sem, portMAX_DELAY);
+ }
+ }
+}
diff --git a/source/com_task.h b/source/com_task.h
new file mode 100644
index 0000000..14c742e
--- /dev/null
+++ b/source/com_task.h
@@ -0,0 +1,130 @@
+/*
+ * com_task.h
+ */
+
+#ifndef COM_TASK_H_
+#define COM_TASK_H_
+
+#include "board.h"
+#include "fsl_debug_console.h"
+#include "fsl_dspi.h"
+#include "fsl_gpio.h"
+
+/* FreeRTOS kernel includes. */
+#include "FreeRTOS.h"
+#include "task.h"
+#include "queue.h"
+#include "timers.h"
+#include "semphr.h"
+#include "errno.h"
+
+typedef struct _callback_message_t
+{
+ status_t async_status;
+ SemaphoreHandle_t sem;
+} callback_message_t;
+
+TaskHandle_t spi_task_handle;
+void generate_irq(uint8_t irq);
+void clear_irq_flag(uint8_t irq);
+void spi_task(void *pvParameters);
+
+#define BIT(nr) (1UL << (nr))
+
+
+/* Commands and registers used in SPI communication */
+
+/* Commands*/
+#define APALIS_TK1_K20_READ_INST 0x0F
+#define APALIS_TK1_K20_WRITE_INST 0xF0
+#define APALIS_TK1_K20_BULK_WRITE_INST 0x3C
+#define APALIS_TK1_K20_BULK_READ_INST 0xC3
+
+#define APALIS_TK1_K20_MAX_BULK (64)
+
+/* General registers*/
+#define APALIS_TK1_K20_STAREG 0x00 /* General status register RO */
+#define APALIS_TK1_K20_REVREG 0x01 /* FW revision register RO*/
+#define APALIS_TK1_K20_IRQREG 0x02 /* IRQ status RW(write of 1 will reset the bit) */
+#define APALIS_TK1_K20_CTRREG 0x03 /* General control register RW */
+#define APALIS_TK1_K20_MSQREG 0x04 /* IRQ mask register RW */
+
+/* CAN Registers */
+#define APALIS_TK1_K20_CANREG 0x10 /* CAN control & status register RW */
+#define APALIS_TK1_K20_CAN_BAUD_REG 0x11 /* CAN Baud set register RW */
+#define APALIS_TK1_K20_CAN_IN_BUF_CNT 0x12 /* CAN IN BUF Received Data Count RO */
+#define APALIS_TK1_K20_CAN_IN_BUF 0x13 /* CAN IN BUF RO */
+#define APALIS_TK1_K20_CAN_OUT_BUF_CNT 0x14 /* CAN OUT BUF Data Count WO, must be written before bulk write to APALIS_TK1_K20_CAN0_OUT_BUF_CNT */
+#define APALIS_TK1_K20_CAN_OUT_FIF0 0x15 /* CAN OUT BUF WO */
+
+#define APALIS_TK1_K20_CAN_DEV_OFFSET(x) (x ? 0:0x10)
+
+/* ADC Registers */
+#define APALIS_TK1_K20_ADCREG 0x30 /* ADC control & status register RW */
+#define APALIS_TK1_K20_ADC_CH0L 0x31 /* ADC Channel 0 LSB RO */
+#define APALIS_TK1_K20_ADC_CH0H 0x32 /* ADC Channel 0 MSB RO */
+#define APALIS_TK1_K20_ADC_CH1L 0x33 /* ADC Channel 1 LSB RO */
+#define APALIS_TK1_K20_ADC_CH1H 0x34 /* ADC Channel 1 MSB RO */
+#define APALIS_TK1_K20_ADC_CH2L 0x35 /* ADC Channel 2 LSB RO */
+#define APALIS_TK1_K20_ADC_CH2H 0x36 /* ADC Channel 2 MSB RO */
+#define APALIS_TK1_K20_ADC_CH3L 0x37 /* ADC Channel 3 LSB RO */
+#define APALIS_TK1_K20_ADC_CH3H 0x38 /* ADC Channel 3 MSB RO */
+/* Bulk read of LSB register can be use to read entire 16-bit in one command */
+
+/* TSC Register */
+#define APALIS_TK1_K20_TSCREG 0x40 /* TSC control & status register RW */
+#define APALIS_TK1_K20_TSC_XML 0x41 /* TSC X- data LSB RO */
+#define APALIS_TK1_K20_TSC_XMH 0x42 /* TSC X- data MSB RO */
+#define APALIS_TK1_K20_TSC_XPL 0x43 /* TSC X+ data LSB RO */
+#define APALIS_TK1_K20_TSC_XPH 0x44 /* TSC X+ data MSB RO */
+#define APALIS_TK1_K20_TSC_YML 0x45 /* TSC Y- data LSB RO */
+#define APALIS_TK1_K20_TSC_YMH 0x46 /* TSC Y- data MSB RO */
+#define APALIS_TK1_K20_TSC_YPL 0x47 /* TSC Y+ data LSB RO */
+#define APALIS_TK1_K20_TSC_YPH 0x48 /* TSC Y+ data MSB RO */
+/* Bulk read of LSB register can be use to read entire 16-bit in one command */
+#define APALIS_TK1_K20_TSC_ENA BIT(0)
+#define APALIS_TK1_K20_TSC_ENA_MASK 0xFE
+
+/* GPIO Registers */
+#define APALIS_TK1_K20_GPIOREG 0x50 /* GPIO control & status register RW */
+#define APALIS_TK1_K20_GPIO_NO 0x51 /* currently configured GPIO RW */
+#define APALIS_TK1_K20_GPIO_STA 0x52 /* Status register for the APALIS_TK1_K20_GPIO_NO GPIO RW */
+/* MSB | 0 ... 0 | VALUE | Output-1 / Input-0 | LSB */
+#define APALIS_TK1_K20_GPIO_STA_OE BIT(0)
+#define APALIS_TK1_K20_GPIO_STA_VAL BIT(1)
+
+/* Interrupt flags */
+#define APALIS_TK1_K20_GEN_IRQ 0
+#define APALIS_TK1_K20_CAN0_IRQ 1
+#define APALIS_TK1_K20_CAN1_IRQ 2
+#define APALIS_TK1_K20_ADC_IRQ 3
+#define APALIS_TK1_K20_TSC_IRQ 4
+#define APALIS_TK1_K20_GPIO_IRQ 5
+
+#define APALIS_TK1_K20_FW_VER 0x05
+
+#define FW_MINOR (APALIS_TK1_K20_FW_VER & 0x0F)
+#define FW_MAJOR ((APALIS_TK1_K20_FW_VER & 0xF0) >> 8)
+
+#define TK1_K20_SENTINEL 0x55
+#define TK1_K20_INVAL 0xAA
+
+#define ADC0_CHANNEL_CNT 4
+
+#define TSC0_CHANNEL_CNT 4
+
+/* Structure with general registers */
+struct register_struct {
+ uint8_t status;
+ uint8_t control;
+ uint8_t irq_mask;
+ uint8_t irq;
+ uint8_t gpio_no;
+ uint16_t adc[ADC0_CHANNEL_CNT];
+ uint16_t tsc_xm;
+ uint16_t tsc_xp;
+ uint16_t tsc_ym;
+ uint16_t tsc_yp;
+} gen_regs;
+
+#endif /* COM_TASK_H_ */
diff --git a/source/gpio_ext.c b/source/gpio_ext.c
new file mode 100644
index 0000000..5741cb5
--- /dev/null
+++ b/source/gpio_ext.c
@@ -0,0 +1,141 @@
+/*
+ * gpio_ext.c
+ *
+ */
+
+#include "gpio_ext.h"
+#include "com_task.h"
+#include "errno.h"
+
+
+static inline int port_type_to_int(PORT_Type *port)
+{
+ switch ((int) port) {
+ case PORTA_BASE:
+ return 0;
+ case PORTB_BASE:
+ return 1;
+ case PORTC_BASE:
+ return 2;
+ case PORTD_BASE:
+ return 3;
+ case PORTE_BASE:
+ return 4;
+ default:
+ return -EINVAL;
+ }
+}
+
+/* returns GPIO index in gpio_list table and -EINVAL
+ * if there is no entry for this gpio.
+ */
+int is_gpio_valid(uint8_t pin)
+{
+ uint16_t i;
+ int temp;
+ if (pin == 0xFF)
+ return -EINVAL;
+
+ for (i = 0; i < sizeof(gpio_list)/sizeof(struct gpio_id); i++){
+ temp = port_type_to_int(gpio_list[i].port) * 32;
+ temp += gpio_list[i].pin;
+ if ( temp == pin )
+ return i;
+ }
+
+ return -EINVAL;
+}
+
+int set_gpio_status(uint8_t status, uint8_t pin)
+{
+ gpio_pin_config_t gpio_config;
+ int index;
+
+ gpio_config.pinDirection = (status & APALIS_TK1_K20_GPIO_STA_OE) ? kGPIO_DigitalOutput : kGPIO_DigitalInput;
+ gpio_config.outputLogic = (status & APALIS_TK1_K20_GPIO_STA_VAL);
+
+ index = is_gpio_valid(pin);
+
+ if (index >= 0)
+ GPIO_PinInit(gpio_list[index].gpio, gpio_list[index].pin, &gpio_config);
+ else
+ return index;
+
+ return 0;
+}
+
+
+uint8_t get_gpio_status(uint8_t pin)
+{
+ uint8_t status;
+ int index;
+ GPIO_Type *base;
+ uint32_t gpio_pin;
+
+ index = is_gpio_valid(pin);
+ if (index == -EINVAL)
+ return 0xFF;
+ base = gpio_list[index].gpio;
+ gpio_pin = gpio_list[index].pin;
+
+ if (((base->PDDR) >> gpio_pin) & 0x01U) {
+ status = APALIS_TK1_K20_GPIO_STA_OE;
+ status += (((base->PDOR) >> gpio_pin) & 0x01U) ? APALIS_TK1_K20_GPIO_STA_VAL : 0x00;
+ } else {
+ status = 0x00;
+ status += (((base->PDIR) >> gpio_pin) & 0x01U) ? APALIS_TK1_K20_GPIO_STA_VAL : 0x00;
+ }
+
+ return status;
+}
+
+int gpio_registers(uint8_t *rx_buf, uint8_t *tx_buf){
+ if (rx_buf[0] == APALIS_TK1_K20_READ_INST) {
+ switch (rx_buf[1]) {
+ case APALIS_TK1_K20_GPIOREG:
+ return -ENOENT;
+ break;
+ case APALIS_TK1_K20_GPIO_NO:
+ if (gen_regs.gpio_no != 0xFF){
+ tx_buf[0] = gen_regs.gpio_no;
+ return 1;
+ } else
+ return -ENOENT;
+ break;
+ case APALIS_TK1_K20_GPIO_STA:
+ if (gen_regs.gpio_no != 0xFF){
+ tx_buf[0] = get_gpio_status(gen_regs.gpio_no);
+ return 1;
+ } else
+ return -ENOENT;
+ break;
+ default:
+ return -ENOENT;
+ }
+ } else if (rx_buf[0] == APALIS_TK1_K20_WRITE_INST) {
+ switch (rx_buf[1]) {
+ case APALIS_TK1_K20_GPIOREG:
+ return -ENOENT;
+ break;
+ case APALIS_TK1_K20_GPIO_NO:
+ if (is_gpio_valid(rx_buf[2]) >= 0){
+ gen_regs.gpio_no = rx_buf[2];
+ return 0;
+ } else {
+ gen_regs.gpio_no = 0xFF;
+ return -ENOENT;
+ }
+ break;
+ case APALIS_TK1_K20_GPIO_STA:
+ return set_gpio_status(rx_buf[2], gen_regs.gpio_no);
+ break;
+ default:
+ return -ENOENT;
+ }
+ }
+ return -ENOENT;
+}
+
+
+
+
diff --git a/source/gpio_ext.h b/source/gpio_ext.h
new file mode 100644
index 0000000..5edbf3a
--- /dev/null
+++ b/source/gpio_ext.h
@@ -0,0 +1,73 @@
+/*
+ * gpio_ext.h
+ *
+ */
+
+#ifndef SOURCE_GPIO_EXT_H_
+#define SOURCE_GPIO_EXT_H_
+
+#include "fsl_device_registers.h"
+#include "fsl_debug_console.h"
+#include "board.h"
+
+struct gpio_id{
+ PORT_Type *port;
+ GPIO_Type *gpio;
+ uint32_t pin;
+};
+
+struct gpio_id gpio_list [] = {
+ {PORTA, GPIOA, 3},
+ {PORTA, GPIOA, 5},
+ {PORTA, GPIOA, 17},
+#ifndef BOARD_USES_ADC
+ {PORTB, GPIOB, 1},
+ {PORTB, GPIOB, 2},
+ {PORTB, GPIOB, 3},
+#endif
+#ifndef SDK_DEBUGCONSOLE
+ {PORTB, GPIOB, 10},
+ {PORTB, GPIOB, 11},
+#endif
+ {PORTB, GPIOB, 16},
+ {PORTB, GPIOB, 17},
+ {PORTB, GPIOB, 18},
+ {PORTB, GPIOB, 19},
+ {PORTC, GPIOC, 0},
+ {PORTC, GPIOC, 1},
+ {PORTC, GPIOC, 2},
+ {PORTC, GPIOC, 3},
+ {PORTC, GPIOC, 4},
+ {PORTC, GPIOC, 6},
+ {PORTC, GPIOC, 7},
+ {PORTD, GPIOD, 0},
+ {PORTD, GPIOD, 1},
+ {PORTD, GPIOD, 2},
+ {PORTD, GPIOD, 3},
+ {PORTD, GPIOD, 4},
+ {PORTD, GPIOD, 5},
+ {PORTD, GPIOD, 6},
+ {PORTD, GPIOD, 7},
+ {PORTD, GPIOD, 8},
+ {PORTD, GPIOD, 9},
+ {PORTD, GPIOD, 11},
+ {PORTD, GPIOD, 12},
+ {PORTD, GPIOD, 13},
+ {PORTD, GPIOD, 14},
+ {PORTD, GPIOD, 15},
+ {PORTE, GPIOE, 0},
+ {PORTE, GPIOE, 1},
+ {PORTE, GPIOE, 2},
+ {PORTE, GPIOE, 3},
+ {PORTE, GPIOE, 4},
+ {PORTE, GPIOE, 5},
+ {PORTE, GPIOE, 24},
+ {PORTE, GPIOE, 25}
+};
+
+int is_gpio_valid(uint8_t pin);
+int set_gpio_status(uint8_t status, uint8_t pin);
+uint8_t get_gpio_status(uint8_t pin);
+int gpio_registers(uint8_t *rx_buf, uint8_t *tx_buf);
+
+#endif /* SOURCE_GPIO_EXT_H_ */
diff --git a/source/main.c b/source/main.c
index 094da3a..e035d4e 100644
--- a/source/main.c
+++ b/source/main.c
@@ -37,7 +37,9 @@
#include "board.h"
#include "pin_mux.h"
#include "clock_config.h"
-/*#include "fsl_debug_console.h"*/
+#include "fsl_debug_console.h"
+#include "com_task.h"
+#include "adc_task.h"
/* FreeRTOS kernel includes. */
#include "FreeRTOS.h"
@@ -46,38 +48,77 @@
#include "timers.h"
+#if ((defined USB_HOST_CONFIG_KHCI) && (USB_HOST_CONFIG_KHCI))
+#define CONTROLLER_ID kUSB_ControllerKhci0
+#endif
+#if ((defined USB_HOST_CONFIG_EHCI) && (USB_HOST_CONFIG_EHCI))
+#define CONTROLLER_ID kUSB_ControllerEhci0
+#endif
+
/* Task priorities. */
-#define hello_task_PRIORITY (configMAX_PRIORITIES - 1)
+#define debug_task_PRIORITY 1
+#define USB_HOST_INTERRUPT_PRIORITY (5U)
+
+/* Task handles */
+
+TaskHandle_t usb_task_handle;
+#ifdef SDK_DEBUGCONSOLE
+TaskHandle_t debug_task_handle;
+#endif
+
/*!
- * @brief Task responsible for printing of "Hello world." message.
+ * @brief Debug task
*/
-static void hello_task(void *pvParameters) {
- for (;;) {
- /*PRINTF("Hello world.\r\n");*/
- /* Add your code here */
- vTaskSuspend(NULL);
- }
+#ifdef SDK_DEBUGCONSOLE
+static void debug_task(void *pvParameters) {
+ for (;;) {
+ vTaskDelay(10000);
+ }
}
-
+#endif
/*!
* @brief Application entry point.
*/
int main(void) {
- /* Init board hardware. */
- BOARD_InitPins();
- BOARD_BootClockRUN();
- BOARD_InitDebugConsole();
- /* Add your code here */
+ /* Init board hardware. */
+ BOARD_InitPins();
+ BOARD_BootClockRUN();
+ BOARD_InitDebugConsole();
+ PRINTF("Apalis K20 Firmware Version %d.%d\r\n", FW_MAJOR, FW_MINOR);
+
+ /* Create RTOS task */
+ if(xTaskCreate(spi_task, "SPI_task", 2000L / sizeof(portSTACK_TYPE), NULL, 4, &spi_task_handle) != pdPASS)
+ {
+ PRINTF("create SPI task error\r\n");
+ }
+
+#ifdef BOARD_USES_ADC
+ if(xTaskCreate(adc_task, "ADC_task", 2000L / sizeof(portSTACK_TYPE), NULL, 2, &adc_task_handle) != pdPASS)
+ {
+ PRINTF("create ADC task error\r\n");
+ }
+
+ if(xTaskCreate(tsc_task, "TSC_task", 2000L / sizeof(portSTACK_TYPE), NULL, 2, &tsc_task_handle) != pdPASS)
+ {
+ PRINTF("create TSC task error\r\n");
+ }
+#endif
+
+#ifdef SDK_DEBUGCONSOLE
+ if(xTaskCreate(debug_task, "Debug_task", configMINIMAL_STACK_SIZE, NULL, debug_task_PRIORITY, &debug_task_handle) != pdPASS)
+ {
+ PRINTF("create hello task error\r\n");
+ }
+#endif
- /* Create RTOS task */
- xTaskCreate(hello_task, "Hello_task", configMINIMAL_STACK_SIZE, NULL, hello_task_PRIORITY, NULL);
- vTaskStartScheduler();
+ NVIC_SetPriorityGrouping( 0 );
+ vTaskStartScheduler();
- for(;;) { /* Infinite loop to avoid leaving the main function */
- __asm("NOP"); /* something to use as a breakpoint stop while looping */
- }
+ for(;;) { /* Infinite loop to avoid leaving the main function */
+ __asm("NOP"); /* something to use as a breakpoint stop while looping */
+ }
}
diff --git a/usb_1.1.0/device/usb_device.h b/usb_1.1.0/device/usb_device.h
new file mode 100644
index 0000000..6301c97
--- /dev/null
+++ b/usb_1.1.0/device/usb_device.h
@@ -0,0 +1,508 @@
+/*
+ * Copyright (c) 2015 - 2016, Freescale Semiconductor, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * o Redistributions of source code must retain the above copyright notice, this list
+ * of conditions and the following disclaimer.
+ *
+ * o Redistributions in binary form must reproduce the above copyright notice, this
+ * list of conditions and the following disclaimer in the documentation and/or
+ * other materials provided with the distribution.
+ *
+ * o Neither the name of Freescale Semiconductor, Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __USB_DEVICE_H__
+#define __USB_DEVICE_H__
+
+/*!
+ * @addtogroup usb_device_driver
+ * @{
+ */
+
+/*******************************************************************************
+ * Definitions
+ ******************************************************************************/
+
+/*! @brief Defines Get/Set status Types */
+typedef enum _usb_device_status
+{
+ kUSB_DeviceStatusTestMode = 1U, /*!< Test mode */
+ kUSB_DeviceStatusSpeed, /*!< Current speed */
+ kUSB_DeviceStatusOtg, /*!< OTG status */
+ kUSB_DeviceStatusDevice, /*!< Device status */
+ kUSB_DeviceStatusEndpoint, /*!< Endpoint state usb_device_endpoint_status_t */
+ kUSB_DeviceStatusDeviceState, /*!< Device state */
+ kUSB_DeviceStatusAddress, /*!< Device address */
+ kUSB_DeviceStatusSynchFrame, /*!< Current frame */
+ kUSB_DeviceStatusBus, /*!< Bus status */
+} usb_device_status_t;
+
+/*! @brief Defines USB 2.0 device state */
+typedef enum _usb_device_state
+{
+ kUSB_DeviceStateConfigured = 0U, /*!< Device state, Configured*/
+ kUSB_DeviceStateAddress, /*!< Device state, Address*/
+ kUSB_DeviceStateDefault, /*!< Device state, Default*/
+ kUSB_DeviceStateAddressing, /*!< Device state, Address setting*/
+ kUSB_DeviceStateTestMode, /*!< Device state, Test mode*/
+} usb_device_state_t;
+
+/*! @brief Defines endpoint state */
+typedef enum _usb_endpoint_status
+{
+ kUSB_DeviceEndpointStateIdle = 0U, /*!< Endpoint state, idle*/
+ kUSB_DeviceEndpointStateStalled, /*!< Endpoint state, stalled*/
+} usb_device_endpoint_status_t;
+
+/*! @brief Control endpoint index */
+#define USB_CONTROL_ENDPOINT (0U)
+/*! @brief Control endpoint maxPacketSize */
+#define USB_CONTROL_MAX_PACKET_SIZE (64U)
+
+#if (USB_DEVICE_CONFIG_EHCI && (USB_CONTROL_MAX_PACKET_SIZE != (64U)))
+#error For high speed, USB_CONTROL_MAX_PACKET_SIZE must be 64!!!
+#endif
+
+/*! @brief The setup packet size of USB control transfer. */
+#define USB_SETUP_PACKET_SIZE (8U)
+/*! @brief USB endpoint mask */
+#define USB_ENDPOINT_NUMBER_MASK (0x0FU)
+
+/*! @brief Default invalid value or the endpoint callback length of cancelled transfer */
+#define USB_UNINITIALIZED_VAL_32 (0xFFFFFFFFU)
+
+/*! @brief Available common EVENT types in device callback */
+typedef enum _usb_device_event
+{
+ kUSB_DeviceEventBusReset = 1U, /*!< USB bus reset signal detected */
+ kUSB_DeviceEventSuspend, /*!< USB bus suspend signal detected */
+ kUSB_DeviceEventResume, /*!< USB bus resume signal detected. The resume signal is driven by itself or a host */
+ kUSB_DeviceEventError, /*!< An error is happened in the bus. */
+ kUSB_DeviceEventDetach, /*!< USB device is disconnected from a host. */
+ kUSB_DeviceEventAttach, /*!< USB device is connected to a host. */
+ kUSB_DeviceEventSetConfiguration, /*!< Set configuration. */
+ kUSB_DeviceEventSetInterface, /*!< Set interface. */
+
+ kUSB_DeviceEventGetDeviceDescriptor, /*!< Get device descriptor. */
+ kUSB_DeviceEventGetConfigurationDescriptor, /*!< Get configuration descriptor. */
+ kUSB_DeviceEventGetStringDescriptor, /*!< Get string descriptor. */
+ kUSB_DeviceEventGetHidDescriptor, /*!< Get HID descriptor. */
+ kUSB_DeviceEventGetHidReportDescriptor, /*!< Get HID report descriptor. */
+ kUSB_DeviceEventGetHidPhysicalDescriptor, /*!< Get HID physical descriptor. */
+ kUSB_DeviceEventGetDeviceQualifierDescriptor, /*!< Get device qualifier descriptor. */
+ kUSB_DeviceEventVendorRequest, /*!< Vendor request. */
+ kUSB_DeviceEventSetRemoteWakeup, /*!< Enable or disable remote wakeup function. */
+ kUSB_DeviceEventGetConfiguration, /*!< Get current configuration index */
+ kUSB_DeviceEventGetInterface, /*!< Get current interface alternate setting value */
+} usb_device_event_t;
+
+/*! @brief Endpoint callback message structure */
+typedef struct _usb_device_endpoint_callback_message_struct
+{
+ uint8_t *buffer; /*!< Transferred buffer */
+ uint32_t length; /*!< Transferred data length */
+ uint8_t isSetup; /*!< Is in a setup phase */
+} usb_device_endpoint_callback_message_struct_t;
+
+/*!
+ * @brief Endpoint callback function typedef.
+ *
+ * This callback function is used to notify the upper layer what the transfer result is.
+ * This callback pointer is passed when a specified endpoint is initialized by calling API #USB_DeviceInitEndpoint.
+ *
+ * @param handle The device handle. It equals to the value returned from #USB_DeviceInit.
+ * @param message The result of a transfer, which includes transfer buffer, transfer length, and whether is in a
+ * setup phase.
+ * phase for control pipe.
+ * @param callbackParam The parameter for this callback. It is same with
+ * usb_device_endpoint_callback_struct_t::callbackParam.
+ *
+ * @return A USB error code or kStatus_USB_Success.
+ */
+typedef usb_status_t (*usb_device_endpoint_callback_t)(usb_device_handle handle,
+ usb_device_endpoint_callback_message_struct_t *message,
+ void *callbackParam);
+
+/*!
+ * @brief Device callback function typedef.
+ *
+ * This callback function is used to notify the upper layer that the device status has changed.
+ * This callback pointer is passed by calling API #USB_DeviceInit.
+ *
+ * @param handle The device handle. It equals the value returned from #USB_DeviceInit.
+ * @param callbackEvent The callback event type. See enumeration #usb_device_event_t.
+ * @param eventParam The event parameter for this callback. The parameter type is determined by the callback event.
+ *
+ * @return A USB error code or kStatus_USB_Success.
+ */
+typedef usb_status_t (*usb_device_callback_t)(usb_device_handle handle, uint32_t callbackEvent, void *eventParam);
+
+/*! @brief Endpoint callback structure */
+typedef struct _usb_device_endpoint_callback_struct
+{
+ usb_device_endpoint_callback_t callbackFn; /*!< Endpoint callback function*/
+ void *callbackParam; /*!< Parameter for callback function*/
+} usb_device_endpoint_callback_struct_t;
+
+/*! @brief Endpoint initialization structure */
+typedef struct _usb_device_endpoint_init_struct
+{
+ uint16_t maxPacketSize; /*!< Endpoint maximum packet size */
+ uint8_t endpointAddress; /*!< Endpoint address*/
+ uint8_t transferType; /*!< Endpoint transfer type*/
+ uint8_t zlt; /*!< ZLT flag*/
+} usb_device_endpoint_init_struct_t;
+
+/*! @brief Endpoint status structure */
+typedef struct _usb_device_endpoint_status_struct
+{
+ uint8_t endpointAddress; /*!< Endpoint address */
+ uint16_t endpointStatus; /*!< Endpoint status : idle or stalled */
+} usb_device_endpoint_status_struct_t;
+
+#if defined(__cplusplus)
+extern "C" {
+#endif /* __cplusplus*/
+
+/*!
+ * @name USB device APIs
+ * @{
+ */
+
+/*******************************************************************************
+ * API
+ ******************************************************************************/
+
+/*!
+ * @brief Initializes the USB device stack.
+ *
+ * This function initializes the USB device module specified by the controllerId.
+ *
+ * @param[in] controllerId The controller ID of the USB IP. See the enumeration #usb_controller_index_t.
+ * @param[in] deviceCallback Function pointer of the device callback.
+ * @param[out] handle It is an out parameter used to return the pointer of the device handle to the caller.
+ *
+ * @retval kStatus_USB_Success The device is initialized successfully.
+ * @retval kStatus_USB_InvalidHandle The handle is a NULL pointer.
+ * @retval kStatus_USB_Busy Cannot allocate a device handle.
+ * @retval kStatus_USB_ControllerNotFound Cannot find the controller according to the controller id.
+ * @retval kStatus_USB_InvalidControllerInterface The controller driver interfaces is invalid. There is an empty
+ * interface entity.
+ * @retval kStatus_USB_Error The macro USB_DEVICE_CONFIG_ENDPOINTS is more than the IP's endpoint number.
+ * Or, the device has been initialized.
+ * Or, the mutex or message queue is created failed.
+ */
+extern usb_status_t USB_DeviceInit(uint8_t controllerId,
+ usb_device_callback_t deviceCallback,
+ usb_device_handle *handle);
+
+/*!
+ * @brief Enables the device functionality.
+ *
+ * The function enables the device functionality, so that the device can be recognized by the host when the device
+ * detects that it has been connected to a host.
+ *
+ * @param[in] handle The device handle got from #USB_DeviceInit.
+ *
+ * @retval kStatus_USB_Success The device is run successfully.
+ * @retval kStatus_USB_ControllerNotFound Cannot find the controller.
+ * @retval kStatus_USB_InvalidHandle The device handle is a NULL pointer. Or the controller handle is invalid.
+ *
+ */
+extern usb_status_t USB_DeviceRun(usb_device_handle handle);
+
+/*!
+ * @brief Disables the device functionality.
+ *
+ * The function disables the device functionality. After this function called, even if the device is detached to the
+ * host,
+ * it can't work.
+ *
+ * @param[in] handle The device handle received from #USB_DeviceInit.
+ *
+ * @retval kStatus_USB_Success The device is stopped successfully.
+ * @retval kStatus_USB_ControllerNotFound Cannot find the controller.
+ * @retval kStatus_USB_InvalidHandle The device handle is a NULL pointer or the controller handle is invalid.
+ */
+extern usb_status_t USB_DeviceStop(usb_device_handle handle);
+
+/*!
+ * @brief De-initializes the device controller.
+ *
+ * The function de-initializes the device controller specified by the handle.
+ *
+ * @param[in] handle The device handle got from #USB_DeviceInit.
+ *
+ * @retval kStatus_USB_Success The device is stopped successfully.
+ * @retval kStatus_USB_InvalidHandle The device handle is a NULL pointer or the controller handle is invalid.
+ */
+extern usb_status_t USB_DeviceDeinit(usb_device_handle handle);
+
+/*!
+ * @brief Sends data through a specified endpoint.
+ *
+ * The function is used to send data through a specified endpoint.
+ *
+ * @param[in] handle The device handle got from #USB_DeviceInit.
+ * @param[in] endpointAddress Endpoint index.
+ * @param[in] buffer The memory address to hold the data need to be sent.
+ * @param[in] length The data length need to be sent.
+ *
+ * @retval kStatus_USB_Success The send request is sent successfully.
+ * @retval kStatus_USB_InvalidHandle The handle is a NULL pointer. Or the controller handle is invalid.
+ * @retval kStatus_USB_Busy Cannot allocate DTDS for current transfer in EHCI driver.
+ * @retval kStatus_USB_ControllerNotFound Cannot find the controller.
+ * @retval kStatus_USB_Error The device is doing reset.
+ *
+ * @note The return value indicates whether the sending request is successful or not. The transfer done is notified by
+ * the
+ * corresponding callback function.
+ * Currently, only one transfer request can be supported for one specific endpoint.
+ * If there is a specific requirement to support multiple transfer requests for one specific endpoint, the application
+ * should implement a queue on the application level.
+ * The subsequent transfer can begin only when the previous transfer is done (get notification through the endpoint
+ * callback).
+ */
+extern usb_status_t USB_DeviceSendRequest(usb_device_handle handle,
+ uint8_t endpointAddress,
+ uint8_t *buffer,
+ uint32_t length);
+
+/*!
+ * @brief Receives data through a specified endpoint.
+ *
+ * The function is used to receive data through a specified endpoint.
+ *
+ * @param[in] handle The device handle got from #USB_DeviceInit.
+ * @param[in] endpointAddress Endpoint index.
+ * @param[in] buffer The memory address to save the received data.
+ * @param[in] length The data length want to be received.
+ *
+ * @retval kStatus_USB_Success The receive request is sent successfully.
+ * @retval kStatus_USB_InvalidHandle The handle is a NULL pointer. Or the controller handle is invalid.
+ * @retval kStatus_USB_Busy Cannot allocate DTDS for current transfer in EHCI driver.
+ * @retval kStatus_USB_ControllerNotFound Cannot find the controller.
+ * @retval kStatus_USB_Error The device is doing reset.
+ *
+ * @note The return value indicates whether the receiving request is successful or not. The transfer done is notified by
+ * the
+ * corresponding callback function.
+ * Currently, only one transfer request can be supported for one specific endpoint.
+ * If there is a specific requirement to support multiple transfer requests for one specific endpoint, the application
+ * should implement a queue on the application level.
+ * The subsequent transfer can begin only when the previous transfer is done (get notification through the endpoint
+ * callback).
+ */
+extern usb_status_t USB_DeviceRecvRequest(usb_device_handle handle,
+ uint8_t endpointAddress,
+ uint8_t *buffer,
+ uint32_t length);
+
+/*!
+ * @brief Cancels the pending transfer in a specified endpoint.
+ *
+ * The function is used to cancel the pending transfer in a specified endpoint.
+ *
+ * @param[in] handle The device handle got from #USB_DeviceInit.
+ * @param[in] endpointAddress Endpoint address, bit7 is the direction of endpoint, 1U - IN, and 0U - OUT.
+ *
+ * @retval kStatus_USB_Success The transfer is cancelled.
+ * @retval kStatus_USB_InvalidHandle The handle is a NULL pointer or the controller handle is invalid.
+ * @retval kStatus_USB_ControllerNotFound Cannot find the controller.
+ */
+extern usb_status_t USB_DeviceCancel(usb_device_handle handle, uint8_t endpointAddress);
+
+/*!
+ * @brief Initializes a specified endpoint.
+ *
+ * The function is used to initialize a specified endpoint. The corresponding endpoint callback is also initialized.
+ *
+ * @param[in] handle The device handle received from #USB_DeviceInit.
+ * @param[in] epInit Endpoint initialization structure. See the structure usb_device_endpoint_init_struct_t.
+ * @param[in] endpointCallback Endpoint callback structure. See the structure
+ * usb_device_endpoint_callback_struct_t.
+ *
+ * @retval kStatus_USB_Success The endpoint is initialized successfully.
+ * @retval kStatus_USB_InvalidHandle The handle is a NULL pointer. Or the controller handle is invalid.
+ * @retval kStatus_USB_InvalidParameter The epInit or endpointCallback is NULL pointer. Or the endpoint number is
+ * more than USB_DEVICE_CONFIG_ENDPOINTS.
+ * @retval kStatus_USB_Busy The endpoint is busy in EHCI driver.
+ * @retval kStatus_USB_ControllerNotFound Cannot find the controller.
+ */
+extern usb_status_t USB_DeviceInitEndpoint(usb_device_handle handle,
+ usb_device_endpoint_init_struct_t *epInit,
+ usb_device_endpoint_callback_struct_t *endpointCallback);
+
+/*!
+ * @brief Deinitializes a specified endpoint.
+ *
+ * The function is used to deinitializes a specified endpoint.
+ *
+ * @param[in] handle The device handle got from #USB_DeviceInit.
+ * @param[in] endpointAddress Endpoint address, bit7 is the direction of endpoint, 1U - IN, and 0U - OUT.
+ *
+ * @retval kStatus_USB_Success The endpoint is de-initialized successfully.
+ * @retval kStatus_USB_InvalidHandle The handle is a NULL pointer. Or the controller handle is invalid.
+ * @retval kStatus_USB_InvalidParameter The endpoint number is more than USB_DEVICE_CONFIG_ENDPOINTS.
+ * @retval kStatus_USB_Busy The endpoint is busy in EHCI driver.
+ * @retval kStatus_USB_ControllerNotFound Cannot find the controller.
+ */
+extern usb_status_t USB_DeviceDeinitEndpoint(usb_device_handle handle, uint8_t endpointAddress);
+
+/*!
+ * @brief Stalls a specified endpoint.
+ *
+ * The function is used to stall a specified endpoint.
+ *
+ * @param[in] handle The device handle received from #USB_DeviceInit.
+ * @param[in] endpointAddress Endpoint address, bit7 is the direction of endpoint, 1U - IN, and 0U - OUT.
+ *
+ * @retval kStatus_USB_Success The endpoint is stalled successfully.
+ * @retval kStatus_USB_InvalidHandle The handle is a NULL pointer. Or the controller handle is invalid.
+ * @retval kStatus_USB_InvalidParameter The endpoint number is more than USB_DEVICE_CONFIG_ENDPOINTS.
+ * @retval kStatus_USB_ControllerNotFound Cannot find the controller.
+ */
+extern usb_status_t USB_DeviceStallEndpoint(usb_device_handle handle, uint8_t endpointAddress);
+
+/*!
+ * @brief Unstalls a specified endpoint.
+ *
+ * The function is used to unstall a specified endpoint.
+ *
+ * @param[in] handle The device handle received from #USB_DeviceInit.
+ * @param[in] endpointAddress Endpoint address, bit7 is the direction of endpoint, 1U - IN, and 0U - OUT.
+ *
+ * @retval kStatus_USB_Success The endpoint is unstalled successfully.
+ * @retval kStatus_USB_InvalidHandle The handle is a NULL pointer. Or the controller handle is invalid.
+ * @retval kStatus_USB_InvalidParameter The endpoint number is more than USB_DEVICE_CONFIG_ENDPOINTS.
+ * @retval kStatus_USB_ControllerNotFound Cannot find the controller.
+ */
+extern usb_status_t USB_DeviceUnstallEndpoint(usb_device_handle handle, uint8_t endpointAddress);
+
+/*!
+ * @brief Gets the status of the selected item.
+ *
+ * The function is used to get the status of the selected item.
+ *
+ * @param[in] handle The device handle got from #USB_DeviceInit.
+ * @param[in] type The selected item. See the structure #usb_device_status_t.
+ * @param[out] param The parameter type is determined by the selected item.
+ *
+ * @retval kStatus_USB_Success Get status successfully.
+ * @retval kStatus_USB_InvalidHandle The handle is a NULL pointer. Or the controller handle is invalid.
+ * @retval kStatus_USB_InvalidParameter The parameter is NULL pointer.
+ * @retval kStatus_USB_ControllerNotFound Cannot find the controller.
+ * @retval kStatus_USB_Error Unsupported type.
+ */
+extern usb_status_t USB_DeviceGetStatus(usb_device_handle handle, usb_device_status_t type, void *param);
+
+/*!
+ * @brief Sets the status of the selected item.
+ *
+ * The function is used to set the status of the selected item.
+ *
+ * @param[in] handle The device handle got from #USB_DeviceInit.
+ * @param[in] type The selected item. See the structure #usb_device_status_t.
+ * @param[in] param The parameter type is determined by the selected item.
+ *
+ * @retval kStatus_USB_Success Set status successfully.
+ * @retval kStatus_USB_InvalidHandle The handle is a NULL pointer. Or the controller handle is invalid.
+ * @retval kStatus_USB_ControllerNotFound Cannot find the controller.
+ * @retval kStatus_USB_Error Unsupported type or the parameter is NULL pointer.
+ */
+extern usb_status_t USB_DeviceSetStatus(usb_device_handle handle, usb_device_status_t type, void *param);
+
+/*!
+ * @brief Device task function.
+ *
+ * The function is used to handle the controller message.
+ * This function should not be called in the application directly.
+ *
+ * @param[in] deviceHandle The device handle got from #USB_DeviceInit.
+ */
+extern void USB_DeviceTaskFunction(void *deviceHandle);
+
+#if ((defined(USB_DEVICE_CONFIG_KHCI)) && (USB_DEVICE_CONFIG_KHCI > 0U))
+/*!
+ * @brief Device KHCI task function.
+ *
+ * The function is used to handle the KHCI controller message.
+ * In the bare metal environment, this function should be called periodically in the main function.
+ * In the RTOS environment, this function should be used as a function entry to create a task.
+ *
+ * @param[in] deviceHandle The device handle got from #USB_DeviceInit.
+ */
+#define USB_DeviceKhciTaskFunction(deviceHandle) USB_DeviceTaskFunction(deviceHandle)
+#endif
+
+#if ((defined(USB_DEVICE_CONFIG_EHCI)) && (USB_DEVICE_CONFIG_EHCI > 0U))
+/*!
+ * @brief Device EHCI task function.
+ *
+ * The function is used to handle the EHCI controller message.
+ * In the bare metal environment, this function should be called periodically in the main function.
+ * In the RTOS environment, this function should be used as a function entry to create a task.
+ *
+ * @param[in] deviceHandle The device handle got from #USB_DeviceInit.
+ */
+#define USB_DeviceEhciTaskFunction(deviceHandle) USB_DeviceTaskFunction(deviceHandle)
+#endif
+
+#if ((defined(USB_DEVICE_CONFIG_KHCI)) && (USB_DEVICE_CONFIG_KHCI > 0U))
+/*!
+ * @brief Device KHCI ISR function.
+ *
+ * The function is the KHCI interrupt service routine.
+ *
+ * @param[in] deviceHandle The device handle got from #USB_DeviceInit.
+ */
+extern void USB_DeviceKhciIsrFunction(void *deviceHandle);
+#endif
+
+#if ((defined(USB_DEVICE_CONFIG_EHCI)) && (USB_DEVICE_CONFIG_EHCI > 0U))
+/*!
+ * @brief Device EHCI ISR function.
+ *
+ * The function is the EHCI interrupt service routine.
+ *
+ * @param[in] deviceHandle The device handle got from #USB_DeviceInit.
+ */
+extern void USB_DeviceEhciIsrFunction(void *deviceHandle);
+#endif
+
+/*!
+ * @brief Gets the device stack version function.
+ *
+ * The function is used to get the device stack version.
+ *
+ * @param[out] version The version structure pointer to keep the device stack version.
+ *
+ */
+extern void USB_DeviceGetVersion(uint32_t *version);
+
+/*! @}*/
+
+#if defined(__cplusplus)
+}
+#endif /* __cplusplus*/
+
+/*! @}*/
+
+#endif /* __USB_DEVICE_H__ */
diff --git a/usb_1.1.0/device/usb_device_dci.c b/usb_1.1.0/device/usb_device_dci.c
new file mode 100644
index 0000000..e876c24
--- /dev/null
+++ b/usb_1.1.0/device/usb_device_dci.c
@@ -0,0 +1,1109 @@
+/*
+ * Copyright (c) 2015 - 2016, Freescale Semiconductor, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * o Redistributions of source code must retain the above copyright notice, this list
+ * of conditions and the following disclaimer.
+ *
+ * o Redistributions in binary form must reproduce the above copyright notice, this
+ * list of conditions and the following disclaimer in the documentation and/or
+ * other materials provided with the distribution.
+ *
+ * o Neither the name of Freescale Semiconductor, Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "usb_device_config.h"
+#include "usb.h"
+
+#include "usb_device.h"
+#include "usb_device_dci.h"
+
+#include "fsl_device_registers.h"
+
+#if ((defined(USB_DEVICE_CONFIG_NUM)) && (USB_DEVICE_CONFIG_NUM > 0U))
+
+#if ((defined(USB_DEVICE_CONFIG_KHCI)) && (USB_DEVICE_CONFIG_KHCI > 0U))
+#include "usb_device_khci.h"
+#endif
+
+#if ((defined(USB_DEVICE_CONFIG_EHCI)) && (USB_DEVICE_CONFIG_EHCI > 0U))
+#include "usb_device_ehci.h"
+#endif
+
+#include "usb_device_ch9.h"
+
+/*******************************************************************************
+ * Definitions
+ ******************************************************************************/
+
+/*******************************************************************************
+ * Prototypes
+ ******************************************************************************/
+static usb_status_t USB_DeviceAllocateHandle(uint8_t controllerId, usb_device_struct_t **handle);
+static usb_status_t USB_DeviceFreeHandle(usb_device_struct_t *handle);
+static usb_status_t USB_DeviceGetControllerInterface(
+ uint8_t controllerId, const usb_device_controller_interface_struct_t **controllerInterface);
+static usb_status_t USB_DeviceTransfer(usb_device_handle handle,
+ uint8_t endpointAddress,
+ uint8_t *buffer,
+ uint32_t length);
+static usb_status_t USB_DeviceControl(usb_device_handle handle, usb_device_control_type_t type, void *param);
+static usb_status_t USB_DeviceResetNotification(usb_device_struct_t *handle,
+ usb_device_callback_message_struct_t *message);
+#if ((defined(USB_DEVICE_CONFIG_LOW_POWER_MODE) && (USB_DEVICE_CONFIG_LOW_POWER_MODE > 0U)) || \
+ (defined(USB_DEVICE_CONFIG_REMOTE_WAKEUP) && (USB_DEVICE_CONFIG_REMOTE_WAKEUP > 0U)))
+static usb_status_t USB_DeviceSuspendNotification(usb_device_struct_t *handle,
+ usb_device_callback_message_struct_t *message);
+static usb_status_t USB_DeviceSuspendNotification(usb_device_struct_t *handle,
+ usb_device_callback_message_struct_t *message);
+#endif
+#if (defined(USB_DEVICE_CONFIG_DETACH_ENABLE) && (USB_DEVICE_CONFIG_DETACH_ENABLE > 0U))
+static usb_status_t USB_DeviceDetachNotification(usb_device_struct_t *handle,
+ usb_device_callback_message_struct_t *message);
+static usb_status_t USB_DeviceAttachNotification(usb_device_struct_t *handle,
+ usb_device_callback_message_struct_t *message);
+#endif
+static usb_status_t USB_DeviceNotification(usb_device_struct_t *handle, usb_device_callback_message_struct_t *message);
+
+/*******************************************************************************
+ * Variables
+ ******************************************************************************/
+
+USB_GLOBAL static usb_device_struct_t s_UsbDevice[USB_DEVICE_CONFIG_NUM];
+
+/*******************************************************************************
+ * Code
+ ******************************************************************************/
+
+/*!
+ * @brief Allocate a device handle.
+ *
+ * This function allocates a device handle.
+ *
+ * @param controllerId The controller id of the USB IP. Please refer to the enumeration usb_controller_index_t.
+ * @param handle It is out parameter, is used to return pointer of the device handle to the caller.
+ *
+ * @retval kStatus_USB_Success Get a device handle successfully.
+ * @retval kStatus_USB_Busy Cannot allocate a device handle.
+ * @retval kStatus_USB_Error The device has been initialized.
+ */
+static usb_status_t USB_DeviceAllocateHandle(uint8_t controllerId, usb_device_struct_t **handle)
+{
+ uint32_t count;
+ USB_OSA_SR_ALLOC();
+
+ USB_OSA_ENTER_CRITICAL();
+ /* Check the controller is initialized or not. */
+ for (count = 0U; count < USB_DEVICE_CONFIG_NUM; count++)
+ {
+ if ((NULL != s_UsbDevice[count].controllerHandle) && (controllerId == s_UsbDevice[count].controllerId))
+ {
+ USB_OSA_EXIT_CRITICAL();
+ return kStatus_USB_Error;
+ }
+ }
+ /* Get a free device handle. */
+ for (count = 0U; count < USB_DEVICE_CONFIG_NUM; count++)
+ {
+ if (NULL == s_UsbDevice[count].controllerHandle)
+ {
+ s_UsbDevice[count].controllerId = controllerId;
+ *handle = &s_UsbDevice[count];
+ USB_OSA_EXIT_CRITICAL();
+ return kStatus_USB_Success;
+ }
+ }
+ USB_OSA_EXIT_CRITICAL();
+ return kStatus_USB_Busy;
+}
+
+/*!
+ * @brief Free a device handle.
+ *
+ * This function frees a device handle.
+ *
+ * @param handle The device handle.
+ *
+ * @retval kStatus_USB_Success Free device handle successfully.
+ */
+static usb_status_t USB_DeviceFreeHandle(usb_device_struct_t *handle)
+{
+ USB_OSA_SR_ALLOC();
+
+ USB_OSA_ENTER_CRITICAL();
+ handle->controllerHandle = NULL;
+ handle->controllerId = 0U;
+ USB_OSA_EXIT_CRITICAL();
+ return kStatus_USB_Success;
+}
+
+#if ((defined(USB_DEVICE_CONFIG_KHCI)) && (USB_DEVICE_CONFIG_KHCI > 0U))
+/* KHCI device driver interface */
+static const usb_device_controller_interface_struct_t s_UsbDeviceKhciInterface = {
+ USB_DeviceKhciInit, USB_DeviceKhciDeinit, USB_DeviceKhciSend,
+ USB_DeviceKhciRecv, USB_DeviceKhciCancel, USB_DeviceKhciControl};
+#endif
+
+#if ((defined(USB_DEVICE_CONFIG_EHCI)) && (USB_DEVICE_CONFIG_EHCI > 0U))
+/* EHCI device driver interface */
+static const usb_device_controller_interface_struct_t s_UsbDeviceEhciInterface = {
+ USB_DeviceEhciInit, USB_DeviceEhciDeinit, USB_DeviceEhciSend,
+ USB_DeviceEhciRecv, USB_DeviceEhciCancel, USB_DeviceEhciControl};
+#endif
+
+/*!
+ * @brief Get the controller interface handle.
+ *
+ * This function is used to get the controller interface handle.
+ *
+ * @param controllerId The controller id of the USB IP. Please refer to the enumeration usb_controller_index_t.
+ * @param controllerInterface It is out parameter, is used to return pointer of the device controller handle to the
+ * caller.
+ *
+ * @retval kStatus_USB_Success Get a device handle successfully.
+ * @retval kStatus_USB_ControllerNotFound The controller id is invalided.
+ */
+static usb_status_t USB_DeviceGetControllerInterface(
+ uint8_t controllerId, const usb_device_controller_interface_struct_t **controllerInterface)
+{
+ usb_status_t error = kStatus_USB_ControllerNotFound;
+ switch (controllerId)
+ {
+#if ((defined(USB_DEVICE_CONFIG_KHCI)) && (USB_DEVICE_CONFIG_KHCI > 0U))
+ /* Get the KHCI controller driver interface */
+ case kUSB_ControllerKhci0:
+ case kUSB_ControllerKhci1:
+ *controllerInterface = (const usb_device_controller_interface_struct_t *)&s_UsbDeviceKhciInterface;
+ error = kStatus_USB_Success;
+ break;
+#endif
+#if ((defined(USB_DEVICE_CONFIG_EHCI)) && (USB_DEVICE_CONFIG_EHCI > 0U))
+ /* Get the EHCI controller driver interface */
+ case kUSB_ControllerEhci0:
+ case kUSB_ControllerEhci1:
+ error = kStatus_USB_Success;
+ *controllerInterface = (const usb_device_controller_interface_struct_t *)&s_UsbDeviceEhciInterface;
+ break;
+#endif
+ default:
+ break;
+ }
+ return error;
+}
+
+/*!
+ * @brief Start a new transfer.
+ *
+ * This function is used to start a new transfer.
+ *
+ * @param handle The device handle. It equals the value returned from USB_DeviceInit.
+ * @param endpointAddress Endpoint address. Bit7 is direction, 0U - USB_OUT, 1U - USB_IN.
+ * @param buffer The memory address to be transferred, or the memory address to hold the data need to be
+ * sent.
+ * @param length The length of the data.
+ *
+ * @retval kStatus_USB_Success Get a device handle successfully.
+ * @retval kStatus_USB_InvalidHandle The device handle is invalided.
+ * @retval kStatus_USB_ControllerNotFound The controller interface is not found.
+ * @retval kStatus_USB_Error The device is doing reset.
+ */
+static usb_status_t USB_DeviceTransfer(usb_device_handle handle,
+ uint8_t endpointAddress,
+ uint8_t *buffer,
+ uint32_t length)
+{
+ usb_device_struct_t *deviceHandle = (usb_device_struct_t *)handle;
+ usb_status_t error = kStatus_USB_Error;
+
+ if (NULL == deviceHandle)
+ {
+ return kStatus_USB_InvalidHandle;
+ }
+
+ if (NULL != deviceHandle->controllerInterface)
+ {
+ if (endpointAddress & USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_MASK)
+ {
+#if (defined(USB_DEVICE_CONFIG_BUFFER_PROPERTY_CACHEABLE) && (USB_DEVICE_CONFIG_BUFFER_PROPERTY_CACHEABLE > 0U))
+ if (length)
+ {
+ USB_CacheFlushLines((void *)buffer, length);
+ }
+#endif
+ /* Call the controller send interface. */
+ error = deviceHandle->controllerInterface->deviceSend(deviceHandle->controllerHandle, endpointAddress,
+ buffer, length);
+ }
+ else
+ {
+#if (defined(USB_DEVICE_CONFIG_BUFFER_PROPERTY_CACHEABLE) && (USB_DEVICE_CONFIG_BUFFER_PROPERTY_CACHEABLE > 0U))
+ if (length)
+ {
+ USB_CacheInvalidateLines((void *)buffer, length);
+ }
+#endif
+ /* Call the controller receive interface. */
+ error = deviceHandle->controllerInterface->deviceRecv(deviceHandle->controllerHandle, endpointAddress,
+ buffer, length);
+ }
+ }
+ else
+ {
+ error = kStatus_USB_ControllerNotFound;
+ }
+ return error;
+}
+
+/*!
+ * @brief Control the status of the selected item.
+ *
+ * This function is used to control the status of the selected item..
+ *
+ * @param handle The device handle. It equals the value returned from USB_DeviceInit.
+ * @param type The control type, please refer to the enumeration usb_device_control_type_t.
+ * @param param The param type is determined by the selected item.
+ *
+ * @retval kStatus_USB_Success Get a device handle successfully.
+ * @retval kStatus_USB_InvalidHandle The device handle is invalided.
+ * @retval kStatus_USB_ControllerNotFound The controller interface is not found.
+ * @retval kStatus_USB_Error Unsupport type.
+ * Or, the param is NULL pointer.
+ */
+static usb_status_t USB_DeviceControl(usb_device_handle handle, usb_device_control_type_t type, void *param)
+{
+ usb_device_struct_t *deviceHandle = (usb_device_struct_t *)handle;
+ usb_status_t error = kStatus_USB_Error;
+
+ if (NULL == deviceHandle)
+ {
+ return kStatus_USB_InvalidHandle;
+ }
+
+ if (NULL != deviceHandle->controllerInterface)
+ {
+ /* Call the controller control interface. */
+ error = deviceHandle->controllerInterface->deviceControl(deviceHandle->controllerHandle, type, param);
+ }
+ else
+ {
+ error = kStatus_USB_ControllerNotFound;
+ }
+ return error;
+}
+
+/*!
+ * @brief Handle the reset notification.
+ *
+ * This function is used to handle the reset notification.
+ *
+ * @param handle The device handle. It equals the value returned from USB_DeviceInit.
+ * @param message The device callback message handle.
+ *
+ * @retval kStatus_USB_Success Get a device handle successfully.
+ */
+static usb_status_t USB_DeviceResetNotification(usb_device_struct_t *handle,
+ usb_device_callback_message_struct_t *message)
+{
+ handle->isResetting = 1U;
+ /* Set the controller to default status. */
+ USB_DeviceControl(handle, kUSB_DeviceControlSetDefaultStatus, NULL);
+
+ handle->state = kUSB_DeviceStateDefault;
+ handle->deviceAddress = 0U;
+
+ for (uint32_t count = 0U; count < (USB_DEVICE_CONFIG_ENDPOINTS * 2U); count++)
+ {
+ handle->endpointCallback[count].callbackFn = (usb_device_endpoint_callback_t)NULL;
+ handle->endpointCallback[count].callbackParam = NULL;
+ }
+
+ /* Call device callback to notify the application that the USB bus reset signal detected. */
+ handle->deviceCallback(handle, kUSB_DeviceEventBusReset, NULL);
+
+ handle->isResetting = 0U;
+ return kStatus_USB_Success;
+}
+
+#if ((defined(USB_DEVICE_CONFIG_LOW_POWER_MODE) && (USB_DEVICE_CONFIG_LOW_POWER_MODE > 0U)) || \
+ (defined(USB_DEVICE_CONFIG_REMOTE_WAKEUP) && (USB_DEVICE_CONFIG_REMOTE_WAKEUP > 0U)))
+/*!
+ * @brief Handle the suspend notification.
+ *
+ * This function is used to handle the suspend notification.
+ *
+ * @param handle The device handle. It equals the value returned from USB_DeviceInit.
+ * @param message The device callback message handle.
+ *
+ * @return A USB error code or kStatus_USB_Success.
+ */
+static usb_status_t USB_DeviceSuspendNotification(usb_device_struct_t *handle,
+ usb_device_callback_message_struct_t *message)
+{
+ /* Call device callback to notify the application that the USB bus suspend signal detected. */
+ return handle->deviceCallback(handle, kUSB_DeviceEventSuspend, NULL);
+}
+
+/*!
+ * @brief Handle the resume notification.
+ *
+ * This function is used to handle the resume notification.
+ *
+ * @param handle The device handle. It equals the value returned from USB_DeviceInit.
+ * @param message The device callback message handle.
+ *
+ * @return A USB error code or kStatus_USB_Success.
+ */
+static usb_status_t USB_DeviceResumeNotification(usb_device_struct_t *handle,
+ usb_device_callback_message_struct_t *message)
+{
+ /* Call device callback to notify the application that the USB bus resume signal detected. */
+ return handle->deviceCallback(handle, kUSB_DeviceEventResume, NULL);
+}
+
+#endif
+
+#if (defined(USB_DEVICE_CONFIG_KHCI_ERROR_HANDLING) && USB_DEVICE_CONFIG_KHCI_ERROR_HANDLING) || \
+ (defined(USB_DEVICE_CONFIG_EHCI_ERROR_HANDLING) && USB_DEVICE_CONFIG_EHCI_ERROR_HANDLING)
+usb_status_t USB_DeviceErrorNotification(usb_device_struct_t *handle, usb_device_callback_message_struct_t *message)
+{
+ /* Call device callback to notify the application that the USB bus error signal detected. */
+ return handle->deviceCallback(handle, kUSB_DeviceEventError, NULL);
+}
+#endif
+
+#if (defined(USB_DEVICE_CONFIG_DETACH_ENABLE) && (USB_DEVICE_CONFIG_DETACH_ENABLE > 0U))
+/*!
+ * @brief Handle the detach notification.
+ *
+ * This function is used to handle the detach notification.
+ *
+ * @param handle The device handle. It equals the value returned from USB_DeviceInit.
+ * @param message The device callback message handle.
+ *
+ * @return A USB error code or kStatus_USB_Success.
+ */
+static usb_status_t USB_DeviceDetachNotification(usb_device_struct_t *handle,
+ usb_device_callback_message_struct_t *message)
+{
+ /* Call device callback to notify the application that the device is disconnected from a host. */
+ return handle->deviceCallback(handle, kUSB_DeviceEventDetach, NULL);
+}
+
+/*!
+ * @brief Handle the attach notification.
+ *
+ * This function is used to handle the attach notification.
+ *
+ * @param handle The device handle. It equals the value returned from USB_DeviceInit.
+ * @param message The device callback message handle.
+ *
+ * @return A USB error code or kStatus_USB_Success.
+ */
+static usb_status_t USB_DeviceAttachNotification(usb_device_struct_t *handle,
+ usb_device_callback_message_struct_t *message)
+{
+ /* Call device callback to notify the application that the device is connected to a host. */
+ return handle->deviceCallback(handle, kUSB_DeviceEventAttach, NULL);
+}
+#endif
+
+/*!
+ * @brief Handle the attach notification.
+ *
+ * This function is used to handle the attach notification.
+ *
+ * @param handle The device handle. It equals the value returned from USB_DeviceInit.
+ * @param message The device callback message handle.
+ *
+ * @return A USB error code or kStatus_USB_Success.
+ */
+static usb_status_t USB_DeviceNotification(usb_device_struct_t *handle, usb_device_callback_message_struct_t *message)
+{
+ uint8_t endpoint = message->code & USB_ENDPOINT_NUMBER_MASK;
+ uint8_t direction = (message->code & USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_MASK) >>
+ USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_SHIFT;
+ usb_status_t error = kStatus_USB_Error;
+
+ switch (message->code)
+ {
+ case kUSB_DeviceNotifyBusReset:
+ error = USB_DeviceResetNotification(handle, message);
+ break;
+#if ((USB_DEVICE_CONFIG_LOW_POWER_MODE) || (USB_DEVICE_CONFIG_REMOTE_WAKEUP))
+ case kUSB_DeviceNotifySuspend:
+ error = USB_DeviceSuspendNotification(handle, message);
+ break;
+ case kUSB_DeviceNotifyResume:
+ error = USB_DeviceResumeNotification(handle, message);
+ break;
+#endif
+
+#if (defined(USB_DEVICE_CONFIG_KHCI_ERROR_HANDLING) && USB_DEVICE_CONFIG_KHCI_ERROR_HANDLING) || \
+ (defined(USB_DEVICE_CONFIG_EHCI_ERROR_HANDLING) && USB_DEVICE_CONFIG_EHCI_ERROR_HANDLING)
+ case kUSB_DeviceNotifyError:
+ error = USB_DeviceErrorNotification(handle, message);
+ break;
+#endif
+
+#if USB_DEVICE_CONFIG_DETACH_ENABLE
+ case kUSB_DeviceNotifyDetach:
+ error = USB_DeviceDetachNotification(handle, message);
+ break;
+ case kUSB_DeviceNotifyAttach:
+ error = USB_DeviceAttachNotification(handle, message);
+ break;
+#endif
+ default:
+ if (endpoint < USB_DEVICE_CONFIG_ENDPOINTS)
+ {
+ if (handle->endpointCallback[(uint8_t)((uint32_t)endpoint << 1U) | direction].callbackFn)
+ {
+ usb_device_endpoint_callback_message_struct_t endpointCallbackMessage;
+ endpointCallbackMessage.buffer = message->buffer;
+ endpointCallbackMessage.length = message->length;
+ endpointCallbackMessage.isSetup = message->isSetup;
+ /* Call endpoint callback */
+ error = handle->endpointCallback[(uint8_t)((uint32_t)endpoint << 1U) | direction].callbackFn(
+ handle, &endpointCallbackMessage,
+ handle->endpointCallback[(uint8_t)((uint32_t)endpoint << 1U) | direction].callbackParam);
+ }
+ }
+ break;
+ }
+ return error;
+}
+
+/*!
+ * @brief Notify the device that the controller status changed.
+ *
+ * This function is used to notify the device that the controller status changed.
+ *
+ * @param handle The device handle. It equals the value returned from USB_DeviceInit.
+ * @param message The device callback message handle.
+ *
+ * @return A USB error code or kStatus_USB_Success.
+ */
+usb_status_t USB_DeviceNotificationTrigger(void *handle, void *msg)
+{
+ usb_device_struct_t *deviceHandle = (usb_device_struct_t *)handle;
+ usb_device_callback_message_struct_t *message = (usb_device_callback_message_struct_t *)msg;
+
+ if ((NULL == msg) || (NULL == handle))
+ {
+ return kStatus_USB_InvalidHandle;
+ }
+
+ /* The device callback is invalid or not. */
+ if (!deviceHandle->deviceCallback)
+ {
+ return kStatus_USB_Error;
+ }
+
+#if USB_DEVICE_CONFIG_USE_TASK
+ if (deviceHandle->isResetting)
+ {
+ if ((message->code & USB_ENDPOINT_NUMBER_MASK) && (!(message->code & 0x70U)))
+ {
+ return USB_DeviceNotification(deviceHandle, message);
+ }
+ }
+
+ /* Add the message to message queue when the device task is enabled. */
+ if (kStatus_USB_OSA_Success != USB_OsaMsgqSend(deviceHandle->notificationQueue, (void *)message))
+ {
+ return kStatus_USB_Busy;
+ }
+ return kStatus_USB_Success;
+#else
+ /* Handle the notification by calling USB_DeviceNotification. */
+ return USB_DeviceNotification(deviceHandle, message);
+#endif
+}
+
+/*!
+ * @brief Initialize the USB device stack.
+ *
+ * This function initializes the USB device module specified by the controllerId.
+ *
+ * @param controllerId The controller id of the USB IP. Please refer to the enumeration usb_controller_index_t.
+ * @param deviceCallback Function pointer of the device callback.
+ * @param handle It is out parameter, is used to return pointer of the device handle to the caller.
+ *
+ * @retval kStatus_USB_Success The device is initialized successfully.
+ * @retval kStatus_USB_InvalidHandle The handle is a NULL pointer.
+ * @retval kStatus_USB_Busy Cannot allocate a device handle.
+ * @retval kStatus_USB_ControllerNotFound Cannot find the controller according to the controller id.
+ * @retval kStatus_USB_InvalidControllerInterface The controller driver interfaces is invaild, There is an empty
+ * interface entity.
+ * @retval kStatus_USB_Error The macro USB_DEVICE_CONFIG_ENDPOINTS is more than IP's endpoint number.
+ * Or, the device has been initialized.
+ * Or, the message queue is created failed.
+ */
+usb_status_t USB_DeviceInit(uint8_t controllerId, usb_device_callback_t deviceCallback, usb_device_handle *handle)
+{
+ usb_device_struct_t *deviceHandle = NULL;
+ usb_status_t error;
+ uint32_t count;
+
+ if (NULL == handle)
+ {
+ return kStatus_USB_InvalidHandle;
+ }
+
+ /* Allocate a device handle by using the controller id. */
+ error = USB_DeviceAllocateHandle(controllerId, &deviceHandle);
+
+ if (kStatus_USB_Success != error)
+ {
+ return error;
+ }
+
+ /* Save the device callback */
+ deviceHandle->deviceCallback = deviceCallback;
+ /* Save the controller id */
+ deviceHandle->controllerId = controllerId;
+ /* Clear the device address */
+ deviceHandle->deviceAddress = 0U;
+ /* Clear the device reset state */
+ deviceHandle->isResetting = 0U;
+
+ /* Initialize the enpoints */
+ for (count = 0U; count < (USB_DEVICE_CONFIG_ENDPOINTS * 2U); count++)
+ {
+ deviceHandle->endpointCallback[count].callbackFn = (usb_device_endpoint_callback_t)NULL;
+ deviceHandle->endpointCallback[count].callbackParam = NULL;
+ }
+
+ /* Get the controller interface according to the controller id */
+ error = USB_DeviceGetControllerInterface(controllerId, &deviceHandle->controllerInterface);
+ if (kStatus_USB_Success != error)
+ {
+ USB_DeviceFreeHandle(deviceHandle);
+ return error;
+ }
+ if (NULL == deviceHandle->controllerInterface)
+ {
+ USB_DeviceFreeHandle(deviceHandle);
+ return kStatus_USB_ControllerNotFound;
+ }
+ if (((usb_device_controller_init_t)NULL == deviceHandle->controllerInterface->deviceInit) ||
+ ((usb_device_controller_deinit_t)NULL == deviceHandle->controllerInterface->deviceDeinit) ||
+ ((usb_device_controller_send_t)NULL == deviceHandle->controllerInterface->deviceSend) ||
+ ((usb_device_controller_recv_t)NULL == deviceHandle->controllerInterface->deviceRecv) ||
+ ((usb_device_controller_cancel_t)NULL == deviceHandle->controllerInterface->deviceCancel) ||
+ ((usb_device_controller_control_t)NULL == deviceHandle->controllerInterface->deviceControl))
+ {
+ USB_DeviceFreeHandle(deviceHandle);
+ return kStatus_USB_InvalidControllerInterface;
+ }
+
+#if USB_DEVICE_CONFIG_USE_TASK
+ /* Create a message queue when the device handle is enabled. */
+ if (kStatus_USB_OSA_Success !=
+ USB_OsaMsgqCreate(&deviceHandle->notificationQueue, USB_DEVICE_CONFIG_MAX_MESSAGES,
+ (1U + (sizeof(usb_device_callback_message_struct_t) - 1U) / sizeof(uint32_t))))
+ {
+ USB_DeviceDeinit(deviceHandle);
+ return kStatus_USB_Error;
+ }
+#endif
+ /* Initialize the controller */
+ error = deviceHandle->controllerInterface->deviceInit(controllerId, deviceHandle, &deviceHandle->controllerHandle);
+ if (kStatus_USB_Success != error)
+ {
+ USB_DeviceDeinit(deviceHandle);
+ return error;
+ }
+ /* Set the device to deafult state */
+ deviceHandle->state = kUSB_DeviceStateDefault;
+ *handle = deviceHandle;
+
+ return error;
+}
+
+/*!
+ * @brief Enable the device functionality.
+ *
+ * The function enables the device functionality, so that the device can be recognized by the host when the device
+ * detects that it has been connected to a host.
+ *
+ * @param handle The device handle got from USB_DeviceInit.
+ *
+ * @retval kStatus_USB_Success The device is run successfully.
+ * @retval kStatus_USB_ControllerNotFound Cannot find the controller.
+ * @retval kStatus_USB_InvalidHandle The device handle is a NULL pointer. Or the controller handle is invalid.
+ *
+ */
+usb_status_t USB_DeviceRun(usb_device_handle handle)
+{
+ return USB_DeviceControl(handle, kUSB_DeviceControlRun, NULL);
+}
+/*!
+ * @brief Disable the device functionality.
+ *
+ * The function disables the device functionality, after this function called, even the device is detached to the host,
+ * and the device can't work.
+ *
+ * @param handle The device handle got from USB_DeviceInit.
+ *
+ * @retval kStatus_USB_Success The device is stopped successfully.
+ * @retval kStatus_USB_ControllerNotFound Cannot find the controller.
+ * @retval kStatus_USB_InvalidHandle The device handle is a NULL pointer. Or the controller handle is invalid.
+ */
+usb_status_t USB_DeviceStop(usb_device_handle handle)
+{
+ return USB_DeviceControl(handle, kUSB_DeviceControlStop, NULL);
+}
+/*!
+ * @brief De-initialize the device controller.
+ *
+ * The function de-initializes the device controller specified by the handle.
+ *
+ * @param handle The device handle got from USB_DeviceInit.
+ *
+ * @retval kStatus_USB_Success The device is stopped successfully.
+ * @retval kStatus_USB_InvalidHandle The device handle is a NULL pointer. Or the controller handle is invalid.
+ */
+usb_status_t USB_DeviceDeinit(usb_device_handle handle)
+{
+ usb_device_struct_t *deviceHandle = (usb_device_struct_t *)handle;
+
+ if (NULL == deviceHandle)
+ {
+ return kStatus_USB_InvalidHandle;
+ }
+ /* De-initialize the controller */
+ if (NULL != deviceHandle->controllerInterface)
+ {
+ deviceHandle->controllerInterface->deviceDeinit(deviceHandle->controllerHandle);
+ deviceHandle->controllerInterface = (usb_device_controller_interface_struct_t *)NULL;
+ }
+
+#if USB_DEVICE_CONFIG_USE_TASK
+ /* Destroy the message queue. */
+ if (NULL != deviceHandle->notificationQueue)
+ {
+ USB_OsaMsgqDestroy(deviceHandle->notificationQueue);
+ deviceHandle->notificationQueue = NULL;
+ }
+#endif
+
+ /* Free the device handle. */
+ USB_DeviceFreeHandle(deviceHandle);
+ return kStatus_USB_Success;
+}
+
+/*!
+ * @brief Send data through a specified endpoint.
+ *
+ * The function is used to send data through a specified endpoint.
+ *
+ * @param handle The device handle got from USB_DeviceInit.
+ * @param endpointAddress Endpoint index.
+ * @param buffer The memory address to hold the data need to be sent.
+ * @param length The data length need to be sent.
+ *
+ * @retval kStatus_USB_Success The send request is sent successfully.
+ * @retval kStatus_USB_InvalidHandle The handle is a NULL pointer. Or the controller handle is invalid.
+ * @retval kStatus_USB_Busy Cannot allocate dtds for current tansfer in EHCI driver.
+ * @retval kStatus_USB_ControllerNotFound Cannot find the controller.
+ * @retval kStatus_USB_Error The device is doing reset.
+ *
+ * @note The return value just means if the sending request is successful or not; the transfer done is notified by the
+ * corresponding callback function.
+ * Currently, only one transfer request can be supported for one specific endpoint.
+ * If there is a specific requirement to support multiple transfer requests for one specific endpoint, the application
+ * should implement a queue in the application level.
+ * The subsequent transfer could begin only when the previous transfer is done (get notification through the endpoint
+ * callback).
+ */
+usb_status_t USB_DeviceSendRequest(usb_device_handle handle, uint8_t endpointAddress, uint8_t *buffer, uint32_t length)
+{
+ return USB_DeviceTransfer(handle, (endpointAddress & USB_ENDPOINT_NUMBER_MASK) |
+ (USB_IN << USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_SHIFT),
+ buffer, length);
+}
+
+/*!
+ * @brief Receive data through a specified endpoint.
+ *
+ * The function is used to receive data through a specified endpoint.
+ *
+ * @param handle The device handle got from USB_DeviceInit.
+ * @param endpointAddress Endpoint index.
+ * @param buffer The memory address to save the received data.
+ * @param length The data length want to be received.
+ *
+ * @retval kStatus_USB_Success The receive request is sent successfully.
+ * @retval kStatus_USB_InvalidHandle The handle is a NULL pointer. Or the controller handle is invalid.
+ * @retval kStatus_USB_Busy Cannot allocate dtds for current tansfer in EHCI driver.
+ * @retval kStatus_USB_ControllerNotFound Cannot find the controller.
+ * @retval kStatus_USB_Error The device is doing reset.
+ *
+ * @note The return value just means if the receiving request is successful or not; the transfer done is notified by the
+ * corresponding callback function.
+ * Currently, only one transfer request can be supported for one specific endpoint.
+ * If there is a specific requirement to support multiple transfer requests for one specific endpoint, the application
+ * should implement a queue in the application level.
+ * The subsequent transfer could begin only when the previous transfer is done (get notification through the endpoint
+ * callback).
+ */
+usb_status_t USB_DeviceRecvRequest(usb_device_handle handle, uint8_t endpointAddress, uint8_t *buffer, uint32_t length)
+{
+ return USB_DeviceTransfer(handle, (endpointAddress & USB_ENDPOINT_NUMBER_MASK) |
+ (USB_OUT << USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_SHIFT),
+ buffer, length);
+}
+
+/*!
+ * @brief Cancel the pending transfer in a specified endpoint.
+ *
+ * The function is used to cancel the pending transfer in a specified endpoint.
+ *
+ * @param handle The device handle got from USB_DeviceInit.
+ * @param endpointAddress Endpoint address, bit7 is the direction of endpoint, 1U - IN, abd 0U - OUT.
+ *
+ * @retval kStatus_USB_Success The transfer is cancelled.
+ * @retval kStatus_USB_InvalidHandle The handle is a NULL pointer. Or the controller handle is invalid.
+ * @retval kStatus_USB_ControllerNotFound Cannot find the controller.
+ */
+usb_status_t USB_DeviceCancel(usb_device_handle handle, uint8_t endpointAddress)
+{
+ usb_device_struct_t *deviceHandle = (usb_device_struct_t *)handle;
+ usb_status_t error = kStatus_USB_Error;
+
+ if (NULL == deviceHandle)
+ {
+ return kStatus_USB_InvalidHandle;
+ }
+
+ if (NULL != deviceHandle->controllerInterface)
+ {
+ error = deviceHandle->controllerInterface->deviceCancel(deviceHandle->controllerHandle, endpointAddress);
+ }
+ else
+ {
+ error = kStatus_USB_ControllerNotFound;
+ }
+ return error;
+}
+
+/*!
+ * @brief Initialize a specified endpoint.
+ *
+ * The function is used to initialize a specified endpoint and the corresponding endpoint callback is also initialized.
+ *
+ * @param handle The device handle got from USB_DeviceInit.
+ * @param epInit Endpoint initizlization structure. Please refer to the structure usb_device_endpoint_init_struct_t.
+ * @param endpointCallback Endpoint callback structure. Please refer to the structure
+ * usb_device_endpoint_callback_struct_t.
+ *
+ * @retval kStatus_USB_Success The endpoint is initialized successfully.
+ * @retval kStatus_USB_InvalidHandle The handle is a NULL pointer. Or the controller handle is invalid.
+ * @retval kStatus_USB_InvalidParameter The epInit or endpointCallback is NULL pointer. Or the endpoint number is
+ * more than USB_DEVICE_CONFIG_ENDPOINTS.
+ * @retval kStatus_USB_Busy The endpoint is busy in EHCI driver.
+ * @retval kStatus_USB_ControllerNotFound Cannot find the controller.
+ */
+usb_status_t USB_DeviceInitEndpoint(usb_device_handle handle,
+ usb_device_endpoint_init_struct_t *epInit,
+ usb_device_endpoint_callback_struct_t *endpointCallback)
+{
+ usb_device_struct_t *deviceHandle = (usb_device_struct_t *)handle;
+ uint8_t endpoint;
+ uint8_t direction;
+
+ if (!deviceHandle)
+ {
+ return kStatus_USB_InvalidHandle;
+ }
+
+ if ((!epInit) || (!endpointCallback))
+ {
+ return kStatus_USB_InvalidParameter;
+ }
+
+ endpoint = epInit->endpointAddress & USB_ENDPOINT_NUMBER_MASK;
+ direction = (epInit->endpointAddress & USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_MASK) >>
+ USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_SHIFT;
+
+ if (endpoint < USB_DEVICE_CONFIG_ENDPOINTS)
+ {
+ deviceHandle->endpointCallback[(uint8_t)((uint32_t)endpoint << 1U) | direction].callbackFn =
+ endpointCallback->callbackFn;
+ deviceHandle->endpointCallback[(uint8_t)((uint32_t)endpoint << 1U) | direction].callbackParam =
+ endpointCallback->callbackParam;
+ }
+ else
+ {
+ return kStatus_USB_InvalidParameter;
+ }
+ return USB_DeviceControl(handle, kUSB_DeviceControlEndpointInit, epInit);
+}
+
+/*!
+ * @brief De-initizlize a specified endpoint.
+ *
+ * The function is used to de-initizlize a specified endpoint.
+ *
+ * @param handle The device handle got from USB_DeviceInit.
+ * @param endpointAddress Endpoint address, bit7 is the direction of endpoint, 1U - IN, abd 0U - OUT.
+ *
+ * @retval kStatus_USB_Success The endpoint is de-initialized successfully.
+ * @retval kStatus_USB_InvalidHandle The handle is a NULL pointer. Or the controller handle is invalid.
+ * @retval kStatus_USB_InvalidParameter The endpoint number is more than USB_DEVICE_CONFIG_ENDPOINTS.
+ * @retval kStatus_USB_Busy The endpoint is busy in EHCI driver.
+ * @retval kStatus_USB_ControllerNotFound Cannot find the controller.
+ */
+usb_status_t USB_DeviceDeinitEndpoint(usb_device_handle handle, uint8_t endpointAddress)
+{
+ usb_device_struct_t *deviceHandle = (usb_device_struct_t *)handle;
+ uint8_t endpoint = endpointAddress & USB_ENDPOINT_NUMBER_MASK;
+ uint8_t direction = (endpointAddress & USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_MASK) >>
+ USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_SHIFT;
+ usb_status_t error = kStatus_USB_Error;
+
+ if (!deviceHandle)
+ {
+ return kStatus_USB_InvalidHandle;
+ }
+ error = USB_DeviceControl(handle, kUSB_DeviceControlEndpointDeinit, &endpointAddress);
+ if (endpoint < USB_DEVICE_CONFIG_ENDPOINTS)
+ {
+ deviceHandle->endpointCallback[(uint8_t)((uint32_t)endpoint << 1U) | direction].callbackFn =
+ (usb_device_endpoint_callback_t)NULL;
+ deviceHandle->endpointCallback[(uint8_t)((uint32_t)endpoint << 1U) | direction].callbackParam = NULL;
+ }
+ else
+ {
+ return kStatus_USB_InvalidParameter;
+ }
+ return error;
+}
+
+/*!
+ * @brief Stall a specified endpoint.
+ *
+ * The function is used to stall a specified endpoint.
+ *
+ * @param handle The device handle got from USB_DeviceInit.
+ * @param endpointAddress Endpoint address, bit7 is the direction of endpoint, 1U - IN, abd 0U - OUT.
+ *
+ * @retval kStatus_USB_Success The endpoint is stalled successfully.
+ * @retval kStatus_USB_InvalidHandle The handle is a NULL pointer. Or the controller handle is invalid.
+ * @retval kStatus_USB_InvalidParameter The endpoint number is more than USB_DEVICE_CONFIG_ENDPOINTS.
+ * @retval kStatus_USB_ControllerNotFound Cannot find the controller.
+ */
+usb_status_t USB_DeviceStallEndpoint(usb_device_handle handle, uint8_t endpointAddress)
+{
+ if ((endpointAddress & USB_ENDPOINT_NUMBER_MASK) < USB_DEVICE_CONFIG_ENDPOINTS)
+ {
+ return USB_DeviceControl(handle, kUSB_DeviceControlEndpointStall, &endpointAddress);
+ }
+ else
+ {
+ return kStatus_USB_InvalidParameter;
+ }
+}
+
+/*!
+ * @brief Un-stall a specified endpoint.
+ *
+ * The function is used to un-stall a specified endpoint.
+ *
+ * @param handle The device handle got from USB_DeviceInit.
+ * @param endpointAddress Endpoint address, bit7 is the direction of endpoint, 1U - IN, abd 0U - OUT.
+ *
+ * @retval kStatus_USB_Success The endpoint is un-stalled successfully.
+ * @retval kStatus_USB_InvalidHandle The handle is a NULL pointer. Or the controller handle is invalid.
+ * @retval kStatus_USB_InvalidParameter The endpoint number is more than USB_DEVICE_CONFIG_ENDPOINTS.
+ * @retval kStatus_USB_ControllerNotFound Cannot find the controller.
+ */
+usb_status_t USB_DeviceUnstallEndpoint(usb_device_handle handle, uint8_t endpointAddress)
+{
+ if ((endpointAddress & USB_ENDPOINT_NUMBER_MASK) < USB_DEVICE_CONFIG_ENDPOINTS)
+ {
+ return USB_DeviceControl(handle, kUSB_DeviceControlEndpointUnstall, &endpointAddress);
+ }
+ else
+ {
+ return kStatus_USB_InvalidParameter;
+ }
+}
+
+/*!
+ * @brief Get the status of the selected item.
+ *
+ * The function is used to get the status of the selected item.
+ *
+ * @param handle The device handle got from USB_DeviceInit.
+ * @param type The selected item. Please refer to the structure usb_device_status_t.
+ * @param param The param type is determined by the selected item.
+ *
+ * @retval kStatus_USB_Success Get status successfully.
+ * @retval kStatus_USB_InvalidHandle The handle is a NULL pointer. Or the controller handle is invalid.
+ * @retval kStatus_USB_InvalidParameter The param is NULL pointer.
+ * @retval kStatus_USB_ControllerNotFound Cannot find the controller.
+ * @retval kStatus_USB_Error Unsupported type.
+ */
+usb_status_t USB_DeviceGetStatus(usb_device_handle handle, usb_device_status_t type, void *param)
+{
+ uint8_t *temp8;
+ usb_status_t error = kStatus_USB_Error;
+
+ if (NULL == param)
+ {
+ return kStatus_USB_InvalidParameter;
+ }
+ switch (type)
+ {
+ case kUSB_DeviceStatusSpeed:
+ error = USB_DeviceControl(handle, kUSB_DeviceControlGetSpeed, param);
+ break;
+ case kUSB_DeviceStatusOtg:
+ error = USB_DeviceControl(handle, kUSB_DeviceControlGetOtgStatus, param);
+ break;
+ case kUSB_DeviceStatusDeviceState:
+ temp8 = (uint8_t *)param;
+ error = kStatus_USB_Success;
+ *temp8 = ((usb_device_struct_t *)handle)->state;
+ break;
+ case kUSB_DeviceStatusAddress:
+ temp8 = (uint8_t *)param;
+ error = kStatus_USB_Success;
+ *temp8 = ((usb_device_struct_t *)handle)->deviceAddress;
+ break;
+ case kUSB_DeviceStatusDevice:
+ error = USB_DeviceControl(handle, kUSB_DeviceControlGetDeviceStatus, param);
+ break;
+ case kUSB_DeviceStatusEndpoint:
+ error = USB_DeviceControl(handle, kUSB_DeviceControlGetEndpointStatus, param);
+ break;
+ case kUSB_DeviceStatusSynchFrame:
+ error = USB_DeviceControl(handle, kUSB_DeviceControlGetSynchFrame, param);
+ break;
+ default:
+ break;
+ }
+ return error;
+}
+
+/*!
+ * @brief Set the status of the selected item.
+ *
+ * The function is used to set the status of the selected item.
+ *
+ * @param handle The device handle got from USB_DeviceInit.
+ * @param type The selected item. Please refer to the structure usb_device_status_t.
+ * @param param The param type is determined by the selected item.
+ *
+ * @retval kStatus_USB_Success Set status successfully.
+ * @retval kStatus_USB_InvalidHandle The handle is a NULL pointer. Or the controller handle is invalid.
+ * @retval kStatus_USB_ControllerNotFound Cannot find the controller.
+ * @retval kStatus_USB_Error Unsupported type, or the param is NULL pointer.
+ */
+usb_status_t USB_DeviceSetStatus(usb_device_handle handle, usb_device_status_t type, void *param)
+{
+ usb_status_t error = kStatus_USB_Error;
+ switch (type)
+ {
+#if (defined(USB_DEVICE_CONFIG_EHCI) && (USB_DEVICE_CONFIG_EHCI > 0U)) && \
+ (defined(USB_DEVICE_CONFIG_EHCI_TEST_MODE) && (USB_DEVICE_CONFIG_EHCI_TEST_MODE > 0U))
+ case kUSB_DeviceStatusTestMode:
+ error = USB_DeviceControl(handle, kUSB_DeviceControlSetTestMode, param);
+ break;
+#endif
+ case kUSB_DeviceStatusOtg:
+ error = USB_DeviceControl(handle, kUSB_DeviceControlSetOtgStatus, param);
+ break;
+ case kUSB_DeviceStatusDeviceState:
+ if (NULL != param)
+ {
+ error = kStatus_USB_Success;
+ ((usb_device_struct_t *)handle)->state = (uint8_t)(*(uint8_t *)param);
+ }
+ break;
+ case kUSB_DeviceStatusAddress:
+ if (kUSB_DeviceStateAddressing != ((usb_device_struct_t *)handle)->state)
+ {
+ if (NULL != param)
+ {
+ error = kStatus_USB_Success;
+ ((usb_device_struct_t *)handle)->deviceAddress = (uint8_t)(*(uint8_t *)param);
+ ((usb_device_struct_t *)handle)->state = kUSB_DeviceStateAddressing;
+ }
+ }
+ else
+ {
+ error = USB_DeviceControl(handle, kUSB_DeviceControlSetDeviceAddress,
+ &((usb_device_struct_t *)handle)->deviceAddress);
+ }
+ break;
+ case kUSB_DeviceStatusBus:
+ error = USB_DeviceControl(handle, kUSB_DeviceControlResume, param);
+ break;
+ default:
+ break;
+ }
+ return error;
+}
+
+#if USB_DEVICE_CONFIG_USE_TASK
+/*!
+ * @brief Device task function.
+ *
+ * The function is used to handle controller message.
+ * This function should not be called in applicartion directly.
+ *
+ * @param handle The device handle got from USB_DeviceInit.
+ */
+void USB_DeviceTaskFunction(void *deviceHandle)
+{
+ usb_device_struct_t *handle = (usb_device_struct_t *)deviceHandle;
+ static usb_device_callback_message_struct_t message;
+
+ if (deviceHandle)
+ {
+ /* Get the message from the queue */
+ if (kStatus_USB_OSA_Success == USB_OsaMsgqRecv(handle->notificationQueue, (uint32_t *)&message, 0U))
+ {
+ /* Handle the message */
+ USB_DeviceNotification(handle, &message);
+ }
+ }
+}
+#endif
+
+/*!
+ * @brief Get dvice stack version function.
+ *
+ * The function is used to get dvice stack version.
+ *
+ * @param[out] version The version structure pointer to keep the device stack version.
+ *
+ */
+void USB_DeviceGetVersion(uint32_t *version)
+{
+ if (version)
+ {
+ *version =
+ (uint32_t)USB_MAKE_VERSION(USB_STACK_VERSION_MAJOR, USB_STACK_VERSION_MINOR, USB_STACK_VERSION_BUGFIX);
+ }
+}
+#endif /* USB_DEVICE_CONFIG_NUM */
diff --git a/usb_1.1.0/device/usb_device_dci.h b/usb_1.1.0/device/usb_device_dci.h
new file mode 100644
index 0000000..03f3618
--- /dev/null
+++ b/usb_1.1.0/device/usb_device_dci.h
@@ -0,0 +1,150 @@
+/*
+ * Copyright (c) 2015 - 2016, Freescale Semiconductor, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * o Redistributions of source code must retain the above copyright notice, this list
+ * of conditions and the following disclaimer.
+ *
+ * o Redistributions in binary form must reproduce the above copyright notice, this
+ * list of conditions and the following disclaimer in the documentation and/or
+ * other materials provided with the distribution.
+ *
+ * o Neither the name of Freescale Semiconductor, Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __USB_DEVICE_DCI_H__
+#define __USB_DEVICE_DCI_H__
+
+/*!
+ * @addtogroup usb_device_controller_driver
+ * @{
+ */
+
+/*******************************************************************************
+ * Definitions
+ ******************************************************************************/
+
+/*! @brief Macro to define controller handle */
+#define usb_device_controller_handle usb_device_handle
+
+/*! @brief Available notify types for device notification */
+typedef enum _usb_device_notification
+{
+ kUSB_DeviceNotifyBusReset = 0x10U, /*!< Reset signal detected */
+ kUSB_DeviceNotifySuspend, /*!< Suspend signal detected */
+ kUSB_DeviceNotifyResume, /*!< Resume signal detected */
+ kUSB_DeviceNotifyError, /*!< Errors happened in bus */
+ kUSB_DeviceNotifyDetach, /*!< Device disconnected from a host */
+ kUSB_DeviceNotifyAttach, /*!< Device connected to a host */
+} usb_device_notification_t;
+
+/*! @brief Device notification message structure */
+typedef struct _usb_device_callback_message_struct
+{
+ uint8_t *buffer; /*!< Transferred buffer */
+ uint32_t length; /*!< Transferred data length */
+ uint8_t code; /*!< Notification code */
+ uint8_t isSetup; /*!< Is in a setup phase */
+} usb_device_callback_message_struct_t;
+
+/*! @brief Control type for controller */
+typedef enum _usb_device_control_type
+{
+ kUSB_DeviceControlRun = 0U, /*!< Enable the device functionality */
+ kUSB_DeviceControlStop, /*!< Disable the device functionality */
+ kUSB_DeviceControlEndpointInit, /*!< Initialize a specified endpoint */
+ kUSB_DeviceControlEndpointDeinit, /*!< De-initialize a specified endpoint */
+ kUSB_DeviceControlEndpointStall, /*!< Stall a specified endpoint */
+ kUSB_DeviceControlEndpointUnstall, /*!< Unstall a specified endpoint */
+ kUSB_DeviceControlGetDeviceStatus, /*!< Get device status */
+ kUSB_DeviceControlGetEndpointStatus, /*!< Get endpoint status */
+ kUSB_DeviceControlSetDeviceAddress, /*!< Set device address */
+ kUSB_DeviceControlGetSynchFrame, /*!< Get current frame */
+ kUSB_DeviceControlResume, /*!< Drive controller to generate a resume signal in USB bus */
+ kUSB_DeviceControlSetDefaultStatus, /*!< Set controller to default status */
+ kUSB_DeviceControlGetSpeed, /*!< Get current speed */
+ kUSB_DeviceControlGetOtgStatus, /*!< Get OTG status */
+ kUSB_DeviceControlSetOtgStatus, /*!< Set OTG status */
+ kUSB_DeviceControlSetTestMode, /*!< Drive xCHI into test mode */
+} usb_device_control_type_t;
+
+/*! @brief USB device controller initialization function typedef */
+typedef usb_status_t (*usb_device_controller_init_t)(uint8_t controllerId,
+ usb_device_handle handle,
+ usb_device_controller_handle *controllerHandle);
+
+/*! @brief USB device controller de-initialization function typedef */
+typedef usb_status_t (*usb_device_controller_deinit_t)(usb_device_controller_handle controllerHandle);
+
+/*! @brief USB device controller send data function typedef */
+typedef usb_status_t (*usb_device_controller_send_t)(usb_device_controller_handle controllerHandle,
+ uint8_t endpointAddress,
+ uint8_t *buffer,
+ uint32_t length);
+
+/*! @brief USB device controller receive data function typedef */
+typedef usb_status_t (*usb_device_controller_recv_t)(usb_device_controller_handle controllerHandle,
+ uint8_t endpointAddress,
+ uint8_t *buffer,
+ uint32_t length);
+
+/*! @brief USB device controller cancel transfer function in a specified endpoint typedef */
+typedef usb_status_t (*usb_device_controller_cancel_t)(usb_device_controller_handle controllerHandle,
+ uint8_t endpointAddress);
+
+/*! @brief USB device controller control function typedef */
+typedef usb_status_t (*usb_device_controller_control_t)(usb_device_controller_handle controllerHandle,
+ usb_device_control_type_t command,
+ void *param);
+
+/*! @brief USB device controller interface structure */
+typedef struct _usb_device_controller_interface_struct
+{
+ usb_device_controller_init_t deviceInit; /*!< Controller initialization */
+ usb_device_controller_deinit_t deviceDeinit; /*!< Controller de-initialization */
+ usb_device_controller_send_t deviceSend; /*!< Controller send data */
+ usb_device_controller_recv_t deviceRecv; /*!< Controller receive data */
+ usb_device_controller_cancel_t deviceCancel; /*!< Controller cancel transfer */
+ usb_device_controller_control_t deviceControl; /*!< Controller control */
+} usb_device_controller_interface_struct_t;
+
+/*! @brief USB device status structure */
+typedef struct _usb_device_struct
+{
+ usb_device_controller_handle controllerHandle; /*!< Controller handle */
+ const usb_device_controller_interface_struct_t *controllerInterface; /*!< Controller interface handle */
+#if USB_DEVICE_CONFIG_USE_TASK
+ usb_osa_msgq_handle notificationQueue; /*!< Message queue */
+#endif
+ usb_device_callback_t deviceCallback; /*!< Device callback function pointer */
+ usb_device_endpoint_callback_struct_t
+ endpointCallback[USB_DEVICE_CONFIG_ENDPOINTS << 1U]; /*!< Endpoint callback function structure */
+ uint8_t deviceAddress; /*!< Current device address */
+ uint8_t controllerId; /*!< Controller ID */
+ uint8_t state; /*!< Current device state */
+ uint8_t isResetting; /*!< Is doing device reset or not */
+} usb_device_struct_t;
+
+/*******************************************************************************
+ * API
+ ******************************************************************************/
+
+/*! @}*/
+
+#endif /* __USB_DEVICE_DCI_H__ */
diff --git a/usb_1.1.0/device/usb_device_khci.c b/usb_1.1.0/device/usb_device_khci.c
new file mode 100644
index 0000000..fcafe97
--- /dev/null
+++ b/usb_1.1.0/device/usb_device_khci.c
@@ -0,0 +1,1355 @@
+/*
+ * Copyright (c) 2015 - 2016, Freescale Semiconductor, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * o Redistributions of source code must retain the above copyright notice, this list
+ * of conditions and the following disclaimer.
+ *
+ * o Redistributions in binary form must reproduce the above copyright notice, this
+ * list of conditions and the following disclaimer in the documentation and/or
+ * other materials provided with the distribution.
+ *
+ * o Neither the name of Freescale Semiconductor, Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "usb_device_config.h"
+#include "usb.h"
+
+#include "usb_device.h"
+
+#include "fsl_device_registers.h"
+
+#if ((defined(USB_DEVICE_CONFIG_KHCI)) && (USB_DEVICE_CONFIG_KHCI > 0U))
+
+#include "usb_khci.h"
+#include "usb_device_dci.h"
+
+#include "usb_device_khci.h"
+
+/*******************************************************************************
+ * Definitions
+ ******************************************************************************/
+
+/*******************************************************************************
+ * Prototypes
+ ******************************************************************************/
+static usb_status_t USB_DeviceKhciEndpointTransfer(
+ usb_device_khci_state_struct_t *khciState, uint8_t endpoint, uint8_t direction, uint8_t *buffer, uint32_t length);
+static void USB_DeviceKhciPrimeNextSetup(usb_device_khci_state_struct_t *khciState);
+static void USB_DeviceKhciSetDefaultState(usb_device_khci_state_struct_t *khciState);
+static usb_status_t USB_DeviceKhciEndpointInit(usb_device_khci_state_struct_t *khciState,
+ usb_device_endpoint_init_struct_t *epInit);
+static usb_status_t USB_DeviceKhciEndpointDeinit(usb_device_khci_state_struct_t *khciState, uint8_t ep);
+static usb_status_t USB_DeviceKhciEndpointStall(usb_device_khci_state_struct_t *khciState, uint8_t ep);
+static usb_status_t USB_DeviceKhciEndpointUnstall(usb_device_khci_state_struct_t *khciState, uint8_t ep);
+static void USB_DeviceKhciInterruptTokenDone(usb_device_khci_state_struct_t *khciState);
+static void USB_DeviceKhciInterruptReset(usb_device_khci_state_struct_t *khciState);
+#if ((defined(USB_DEVICE_CONFIG_LOW_POWER_MODE) && (USB_DEVICE_CONFIG_LOW_POWER_MODE > 0U)) || \
+ (defined(USB_DEVICE_CONFIG_REMOTE_WAKEUP) && (USB_DEVICE_CONFIG_REMOTE_WAKEUP > 0U)))
+static void USB_DeviceKhciInterruptSleep(usb_device_khci_state_struct_t *khciState);
+static void USB_DeviceKhciInterruptResume(usb_device_khci_state_struct_t *khciState);
+#endif /* USB_DEVICE_CONFIG_LOW_POWER_MODE || USB_DEVICE_CONFIG_REMOTE_WAKEUP */
+static void USB_DeviceKhciInterruptStall(usb_device_khci_state_struct_t *khciState);
+#if defined(USB_DEVICE_CONFIG_KHCI_ERROR_HANDLING) && (USB_DEVICE_CONFIG_KHCI_ERROR_HANDLING > 0U)
+static void USB_DeviceKhciInterruptError(usb_device_khci_state_struct_t *khciState);
+#endif /* USB_DEVICE_CONFIG_KHCI_ERROR_HANDLING */
+
+extern usb_status_t USB_DeviceNotificationTrigger(void *handle, void *msg);
+
+/*******************************************************************************
+ * Variables
+ ******************************************************************************/
+
+/* Apply for BDT buffer, 512-byte alignment */
+USB_RAM_ADDRESS_ALGINMENT_512 USB_BDT static uint8_t s_UsbDeviceKhciBdtBuffer[USB_DEVICE_CONFIG_KHCI][512U];
+
+/* Apply for khci device state structure */
+USB_GLOBAL static usb_device_khci_state_struct_t s_UsbDeviceKhciState[USB_DEVICE_CONFIG_KHCI];
+/* Apply for KHCI DMA aligned buffer when marco USB_DEVICE_CONFIG_KHCI_DMA_ALIGN enabled */
+USB_GLOBAL static uint32_t s_UsbDeviceKhciDmaAlignBuffer
+ [USB_DEVICE_CONFIG_KHCI][((USB_DEVICE_CONFIG_KHCI_DMA_ALIGN_BUFFER_LENGTH - 1U) >> 2U) + 1U];
+
+/*******************************************************************************
+ * Code
+ ******************************************************************************/
+
+/*!
+ * @brief Write the BDT to start a transfer.
+ *
+ * The function is used to start a transfer by writing the BDT.
+ *
+ * @param khciState Pointer of the device KHCI state structure.
+ * @param endpoint Endpoint number.
+ * @param direction The direction of the endpoint, 0U - USB_OUT, 1U - USB_IN.
+ * @param buffer The memory address to save the received data, or the memory address to hold the data need to
+ * be sent.
+ * @param length The length of the data.
+ *
+ * @return A USB error code or kStatus_USB_Success.
+ */
+static usb_status_t USB_DeviceKhciEndpointTransfer(
+ usb_device_khci_state_struct_t *khciState, uint8_t endpoint, uint8_t direction, uint8_t *buffer, uint32_t length)
+{
+ uint32_t index = ((uint32_t)endpoint << 1U) | (uint32_t)direction;
+ USB_OSA_SR_ALLOC();
+
+ /* Enter critical */
+ USB_OSA_ENTER_CRITICAL();
+
+ /* Flag the endpoint is busy. */
+ khciState->endpointState[index].stateUnion.stateBitField.transferring = 1U;
+
+ /* Add the data buffer address to the BDT. */
+ USB_KHCI_BDT_SET_ADDRESS((uint32_t)khciState->bdt, endpoint, direction,
+ khciState->endpointState[index].stateUnion.stateBitField.bdtOdd, (uint32_t)buffer);
+
+ /* Change the BDT control field to start the transfer. */
+ USB_KHCI_BDT_SET_CONTROL(
+ (uint32_t)khciState->bdt, endpoint, direction, khciState->endpointState[index].stateUnion.stateBitField.bdtOdd,
+ USB_LONG_TO_LITTLE_ENDIAN(USB_KHCI_BDT_BC(length) | USB_KHCI_BDT_OWN | USB_KHCI_BDT_DTS |
+ USB_KHCI_BDT_DATA01(khciState->endpointState[index].stateUnion.stateBitField.data0)));
+
+ /* Exit critical */
+ USB_OSA_EXIT_CRITICAL();
+
+ /* Clear the token busy state */
+ khciState->registerBase->CTL &= ~USB_CTL_TXSUSPENDTOKENBUSY_MASK;
+ return kStatus_USB_Success;
+}
+
+/*!
+ * @brief Prime a next setup transfer.
+ *
+ * The function is used to prime a buffer in control out pipe to wait for receiving the host's setup packet.
+ *
+ * @param khciState Pointer of the device KHCI state structure.
+ *
+ */
+static void USB_DeviceKhciPrimeNextSetup(usb_device_khci_state_struct_t *khciState)
+{
+/* Update the endpoint state */
+/* Save the buffer address used to receive the setup packet. */
+#if defined(FSL_FEATURE_USB_KHCI_KEEP_ALIVE_ENABLED) && (FSL_FEATURE_USB_KHCI_KEEP_ALIVE_ENABLED > 0U) \
+&& defined(USB_DEVICE_CONFIG_KEEP_ALIVE_MODE) && \
+ (USB_DEVICE_CONFIG_KEEP_ALIVE_MODE > 0U) && defined(FSL_FEATURE_USB_KHCI_USB_RAM) && \
+ (FSL_FEATURE_USB_KHCI_USB_RAM > 0U)
+ /* In case of lowpower mode enabled, it requires to put the setup packet buffer(16 bytes) into the USB RAM so
+ * that the setup packet would wake up the USB.
+ */
+ khciState->endpointState[(USB_CONTROL_ENDPOINT << 1U) | USB_OUT].transferBuffer =
+ (uint8_t *)(khciState->bdt + 0x200U - 0x10U) +
+ khciState->endpointState[(USB_CONTROL_ENDPOINT << 1U) | USB_OUT].stateUnion.stateBitField.bdtOdd *
+ USB_SETUP_PACKET_SIZE;
+#else
+ khciState->endpointState[(USB_CONTROL_ENDPOINT << 1U) | USB_OUT].transferBuffer =
+ (uint8_t *)&khciState->setupPacketBuffer[0] +
+ khciState->endpointState[(USB_CONTROL_ENDPOINT << 1U) | USB_OUT].stateUnion.stateBitField.bdtOdd *
+ USB_SETUP_PACKET_SIZE;
+#endif
+ /* Clear the transferred length. */
+ khciState->endpointState[(USB_CONTROL_ENDPOINT << 1U) | USB_OUT].transferDone = 0U;
+ /* Save the data length expected to get from a host. */
+ khciState->endpointState[(USB_CONTROL_ENDPOINT << 1U) | USB_OUT].transferLength = USB_SETUP_PACKET_SIZE;
+ /* Save the data buffer DMA align flag. */
+ khciState->endpointState[(USB_CONTROL_ENDPOINT << 1U) | USB_OUT].stateUnion.stateBitField.dmaAlign = 1U;
+ /* Set the DATA0/1 to DATA0. */
+ khciState->endpointState[(USB_CONTROL_ENDPOINT << 1U) | USB_OUT].stateUnion.stateBitField.data0 = 0U;
+
+ USB_DeviceKhciEndpointTransfer(khciState, USB_CONTROL_ENDPOINT, USB_OUT,
+ khciState->endpointState[(USB_CONTROL_ENDPOINT << 1U) | USB_OUT].transferBuffer,
+ USB_SETUP_PACKET_SIZE);
+}
+
+/*!
+ * @brief Set device controller state to default state.
+ *
+ * The function is used to set device controller state to default state.
+ * The function will be called when USB_DeviceKhciInit called or the control type kUSB_DeviceControlGetEndpointStatus
+ * received in USB_DeviceKhciControl.
+ *
+ * @param khciState Pointer of the device KHCI state structure.
+ *
+ */
+static void USB_DeviceKhciSetDefaultState(usb_device_khci_state_struct_t *khciState)
+{
+ uint8_t interruptFlag;
+
+ /* Clear the error state register */
+ khciState->registerBase->ERRSTAT = 0xFFU;
+
+ /* Setting this bit to 1U resets all the BDT ODD ping/pong fields to 0U, which then specifies the EVEN BDT bank. */
+ khciState->registerBase->CTL |= USB_CTL_ODDRST_MASK;
+
+ /* Clear the device address */
+ khciState->registerBase->ADDR = 0U;
+
+ /* Clear the endpoint state and disable the endpoint */
+ for (uint8_t count = 0U; count < USB_DEVICE_CONFIG_ENDPOINTS; count++)
+ {
+ USB_KHCI_BDT_SET_CONTROL((uint32_t)khciState->bdt, count, USB_OUT, 0U, 0U);
+ USB_KHCI_BDT_SET_CONTROL((uint32_t)khciState->bdt, count, USB_OUT, 1U, 0U);
+ USB_KHCI_BDT_SET_CONTROL((uint32_t)khciState->bdt, count, USB_IN, 0U, 0U);
+ USB_KHCI_BDT_SET_CONTROL((uint32_t)khciState->bdt, count, USB_IN, 1U, 0U);
+
+ khciState->endpointState[((uint32_t)count << 1U) | USB_OUT].stateUnion.state = 0U;
+ khciState->endpointState[((uint32_t)count << 1U) | USB_IN].stateUnion.state = 0U;
+ khciState->registerBase->ENDPOINT[count].ENDPT = 0x00U;
+ }
+ khciState->isDmaAlignBufferInusing = 0U;
+
+ /* Clear the BDT odd reset flag */
+ khciState->registerBase->CTL &= ~USB_CTL_ODDRST_MASK;
+
+ /* Enable all error */
+ khciState->registerBase->ERREN = 0xFFU;
+
+ /* Enable reset, sof, token, stall interrupt */
+ interruptFlag = kUSB_KhciInterruptReset
+#if 0U
+ | kUSB_KhciInterruptSofToken
+#endif
+ | kUSB_KhciInterruptTokenDone | kUSB_KhciInterruptStall;
+
+#if ((defined(USB_DEVICE_CONFIG_LOW_POWER_MODE) && (USB_DEVICE_CONFIG_LOW_POWER_MODE > 0U)) || \
+ (defined(USB_DEVICE_CONFIG_REMOTE_WAKEUP) && (USB_DEVICE_CONFIG_REMOTE_WAKEUP > 0U)))
+ /* Enable suspend interruprt */
+ interruptFlag |= kUSB_KhciInterruptSleep;
+#endif /* USB_DEVICE_CONFIG_LOW_POWER_MODE || USB_DEVICE_CONFIG_REMOTE_WAKEUP */
+
+#if defined(USB_DEVICE_CONFIG_KHCI_ERROR_HANDLING) && (USB_DEVICE_CONFIG_KHCI_ERROR_HANDLING > 0U)
+ /* Enable error interruprt */
+ interruptFlag |= kUSB_KhciInterruptError;
+#endif /* USB_DEVICE_CONFIG_KHCI_ERROR_HANDLING */
+ /* Write the interrupt enable register */
+ khciState->registerBase->INTEN = interruptFlag;
+
+ /* Clear reset flag */
+ khciState->isResetting = 0U;
+
+ khciState->registerBase->CTL &= ~USB_CTL_TXSUSPENDTOKENBUSY_MASK;
+}
+
+/*!
+ * @brief Initialize a specified endpoint.
+ *
+ * The function is used to initialize a specified endpoint.
+ *
+ * @param khciState Pointer of the device KHCI state structure.
+ * @param epInit The endpoint initialization structure pointer.
+ *
+ * @return A USB error code or kStatus_USB_Success.
+ */
+static usb_status_t USB_DeviceKhciEndpointInit(usb_device_khci_state_struct_t *khciState,
+ usb_device_endpoint_init_struct_t *epInit)
+{
+ uint16_t maxPacketSize = epInit->maxPacketSize;
+ uint8_t endpoint = (epInit->endpointAddress & USB_ENDPOINT_NUMBER_MASK);
+ uint8_t direction = (epInit->endpointAddress & USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_MASK) >>
+ USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_SHIFT;
+ uint8_t index = ((uint8_t)((uint32_t)endpoint << 1U)) | (uint8_t)direction;
+
+ /* Make the endpoint max packet size align with USB Specification 2.0. */
+ if (USB_ENDPOINT_ISOCHRONOUS == epInit->transferType)
+ {
+ if (maxPacketSize > USB_DEVICE_MAX_FS_ISO_MAX_PACKET_SIZE)
+ {
+ maxPacketSize = USB_DEVICE_MAX_FS_ISO_MAX_PACKET_SIZE;
+ }
+ }
+ else
+ {
+ if (maxPacketSize > USB_DEVICE_MAX_FS_NONE_ISO_MAX_PACKET_SIZE)
+ {
+ maxPacketSize = USB_DEVICE_MAX_FS_NONE_ISO_MAX_PACKET_SIZE;
+ }
+ /* Enable an endpoint to perform handshaking during a transaction to this endpoint. */
+ khciState->registerBase->ENDPOINT[endpoint].ENDPT |= USB_ENDPT_EPHSHK_MASK;
+ }
+ /* Set the endpoint idle */
+ khciState->endpointState[index].stateUnion.stateBitField.transferring = 0U;
+ /* Save the max packet size of the endpoint */
+ khciState->endpointState[index].stateUnion.stateBitField.maxPacketSize = maxPacketSize;
+ /* Set the data toggle to DATA0 */
+ khciState->endpointState[index].stateUnion.stateBitField.data0 = 0U;
+ /* Clear the endpoint stalled state */
+ khciState->endpointState[index].stateUnion.stateBitField.stalled = 0U;
+ /* Enable the endpoint. */
+ khciState->registerBase->ENDPOINT[endpoint].ENDPT |=
+ (USB_IN == direction) ? USB_ENDPT_EPTXEN_MASK : USB_ENDPT_EPRXEN_MASK;
+
+ /* Prime a transfer to receive next setup packet when the endpoint is control out endpoint. */
+ if ((USB_CONTROL_ENDPOINT == endpoint) && (USB_OUT == direction))
+ {
+ USB_DeviceKhciPrimeNextSetup(khciState);
+ }
+
+ return kStatus_USB_Success;
+}
+
+/*!
+ * @brief De-initialize a specified endpoint.
+ *
+ * The function is used to de-initialize a specified endpoint.
+ * Current transfer of the endpoint will be canceled and the specified endpoint will be disabled.
+ *
+ * @param khciState Pointer of the device KHCI state structure.
+ * @param ep The endpoint address, Bit7, 0U - USB_OUT, 1U - USB_IN.
+ *
+ * @return A USB error code or kStatus_USB_Success.
+ */
+static usb_status_t USB_DeviceKhciEndpointDeinit(usb_device_khci_state_struct_t *khciState, uint8_t ep)
+{
+ uint8_t endpoint = (ep & USB_ENDPOINT_NUMBER_MASK);
+ uint8_t direction =
+ (ep & USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_MASK) >> USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_SHIFT;
+ uint8_t index = ((uint8_t)((uint32_t)endpoint << 1U)) | (uint8_t)direction;
+
+ /* Cancel the transfer of the endpoint */
+ USB_DeviceKhciCancel(khciState, ep);
+
+ /* Disable the endpoint */
+ khciState->registerBase->ENDPOINT[endpoint].ENDPT = 0x00U;
+ /* Clear the max packet size */
+ khciState->endpointState[index].stateUnion.stateBitField.maxPacketSize = 0U;
+
+ return kStatus_USB_Success;
+}
+
+/*!
+ * @brief Stall a specified endpoint.
+ *
+ * The function is used to stall a specified endpoint.
+ * Current transfer of the endpoint will be canceled and the specified endpoint will be stalled.
+ *
+ * @param khciState Pointer of the device KHCI state structure.
+ * @param ep The endpoint address, Bit7, 0U - USB_OUT, 1U - USB_IN.
+ *
+ * @return A USB error code or kStatus_USB_Success.
+ */
+static usb_status_t USB_DeviceKhciEndpointStall(usb_device_khci_state_struct_t *khciState, uint8_t ep)
+{
+ uint8_t endpoint = ep & USB_ENDPOINT_NUMBER_MASK;
+ uint8_t direction =
+ (ep & USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_MASK) >> USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_SHIFT;
+ uint8_t index = ((uint8_t)((uint32_t)endpoint << 1U)) | (uint8_t)direction;
+
+ /* Cancel the transfer of the endpoint */
+ USB_DeviceKhciCancel(khciState, ep);
+
+ /* Set endpoint stall flag. */
+ khciState->endpointState[index].stateUnion.stateBitField.stalled = 1U;
+
+ /* Set endpoint stall in BDT. And then if the host send a IN/OUT tanscation, the device will response a STALL state.
+ */
+ USB_KHCI_BDT_SET_CONTROL(
+ (uint32_t)khciState->bdt, endpoint, direction, khciState->endpointState[index].stateUnion.stateBitField.bdtOdd,
+ USB_LONG_TO_LITTLE_ENDIAN(
+ (uint32_t)(USB_KHCI_BDT_BC(khciState->endpointState[index].stateUnion.stateBitField.maxPacketSize) |
+ USB_KHCI_BDT_DTS | USB_KHCI_BDT_STALL | USB_KHCI_BDT_OWN)));
+
+ khciState->registerBase->CTL &= ~USB_CTL_TXSUSPENDTOKENBUSY_MASK;
+
+ return kStatus_USB_Success;
+}
+
+/*!
+ * @brief Un-stall a specified endpoint.
+ *
+ * The function is used to un-stall a specified endpoint.
+ * Current transfer of the endpoint will be canceled and the specified endpoint will be un-stalled.
+ *
+ * @param khciState Pointer of the device KHCI state structure.
+ * @param ep The endpoint address, Bit7, 0U - USB_OUT, 1U - USB_IN.
+ *
+ * @return A USB error code or kStatus_USB_Success.
+ */
+static usb_status_t USB_DeviceKhciEndpointUnstall(usb_device_khci_state_struct_t *khciState, uint8_t ep)
+{
+ uint32_t control;
+ uint8_t endpoint = ep & USB_ENDPOINT_NUMBER_MASK;
+ uint8_t direction =
+ (ep & USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_MASK) >> USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_SHIFT;
+ uint8_t index = ((uint8_t)((uint32_t)endpoint << 1U)) | (uint8_t)direction;
+
+ /* Clear the endpoint stall state */
+ khciState->endpointState[index].stateUnion.stateBitField.stalled = 0U;
+ /* Reset the endpoint data toggle to DATA0 */
+ khciState->endpointState[index].stateUnion.stateBitField.data0 = 0U;
+
+ /* Clear stall state in BDT */
+ for (uint8_t i = 0U; i < 2U; i++)
+ {
+ control = USB_KHCI_BDT_GET_CONTROL((uint32_t)khciState->bdt, endpoint, direction, i);
+ if (control & USB_KHCI_BDT_STALL)
+ {
+ USB_KHCI_BDT_SET_CONTROL(
+ (uint32_t)khciState->bdt, endpoint, direction, i,
+ USB_LONG_TO_LITTLE_ENDIAN(
+ (uint32_t)(USB_KHCI_BDT_BC(khciState->endpointState[index].stateUnion.stateBitField.maxPacketSize) |
+ USB_KHCI_BDT_DTS | USB_KHCI_BDT_DATA01(0U))));
+ }
+ }
+
+ /* Clear stall state in endpoint control register */
+ khciState->registerBase->ENDPOINT[endpoint].ENDPT &= ~USB_ENDPT_EPSTALL_MASK;
+
+ /* Prime a transfer to receive next setup packet when the endpoint is a control out endpoint. */
+ if ((USB_CONTROL_ENDPOINT == endpoint) && (USB_OUT == direction))
+ {
+ USB_DeviceKhciPrimeNextSetup(khciState);
+ }
+
+ khciState->registerBase->CTL &= ~USB_CTL_TXSUSPENDTOKENBUSY_MASK;
+
+ return kStatus_USB_Success;
+}
+
+/*!
+ * @brief Handle the token done interrupt.
+ *
+ * The function is used to handle the token done interrupt.
+ *
+ * @param khciState Pointer of the device KHCI state structure.
+ *
+ */
+static void USB_DeviceKhciInterruptTokenDone(usb_device_khci_state_struct_t *khciState)
+{
+ uint32_t control;
+ uint32_t length;
+ uint32_t remainingLength;
+ usb_device_callback_message_struct_t message;
+ uint8_t endpoint;
+ uint8_t direction;
+ uint8_t bdtOdd;
+ uint8_t isSetup;
+ uint8_t index;
+ uint8_t stateRegister = khciState->registerBase->STAT;
+
+ /* Get the endpoint number to identify which one triggers the token done interrupt. */
+ endpoint = (stateRegister & USB_STAT_ENDP_MASK) >> USB_STAT_ENDP_SHIFT;
+
+ /* Get the direction of the endpoint number. */
+ direction = (stateRegister & USB_STAT_TX_MASK) >> USB_STAT_TX_SHIFT;
+
+ /* Get the finished BDT ODD. */
+ bdtOdd = (stateRegister & USB_STAT_ODD_MASK) >> USB_STAT_ODD_SHIFT;
+
+ /* Clear token done interrupt flag. */
+ khciState->registerBase->ISTAT = kUSB_KhciInterruptTokenDone;
+
+ /* Get the Control field of the BDT element according to the endpoint number, the direction and finished BDT ODD. */
+ control = USB_KHCI_BDT_GET_CONTROL((uint32_t)khciState->bdt, endpoint, direction, bdtOdd);
+
+ /* Get the transferred length. */
+ length = ((USB_LONG_FROM_LITTLE_ENDIAN(control)) >> 16U) & 0x3FFU;
+
+ /* Get the transferred length. */
+ isSetup = (USB_KHCI_BDT_DEVICE_SETUP_TOKEN == ((uint8_t)(((USB_LONG_FROM_LITTLE_ENDIAN(control)) >> 2U) & 0x0FU))) ?
+ 1U :
+ 0U;
+
+ index = ((uint8_t)((uint32_t)endpoint << 1U)) | (uint8_t)direction;
+
+ if (0U == khciState->endpointState[index].stateUnion.stateBitField.transferring)
+ {
+ return;
+ }
+
+ if (isSetup)
+ {
+ khciState->setupBufferIndex = bdtOdd;
+ }
+
+ /* USB_IN, Send completed */
+ if (direction == USB_IN)
+ {
+ /* The transferred length */
+ khciState->endpointState[index].transferDone += length;
+
+ /* Remaining length */
+ remainingLength = khciState->endpointState[index].transferLength - khciState->endpointState[index].transferDone;
+
+ /* Change the data toggle flag */
+ khciState->endpointState[index].stateUnion.stateBitField.data0 ^= 1U;
+ /* Change the BDT odd toggle flag */
+ khciState->endpointState[index].stateUnion.stateBitField.bdtOdd ^= 1U;
+
+ /* Whether the transfer is completed or not. */
+ /*
+ * The transfer is completed when one of the following conditions meet:
+ * 1. The remaining length is zero.
+ * 2. The length of current transcation is less than the max packet size of the current pipe.
+ */
+ if ((0U == remainingLength) ||
+ (khciState->endpointState[index].stateUnion.stateBitField.maxPacketSize > length))
+ {
+ message.length = khciState->endpointState[index].transferDone;
+ message.buffer = khciState->endpointState[index].transferBuffer;
+ khciState->endpointState[index].stateUnion.stateBitField.transferring = 0U;
+
+ /*
+ * Whether need to send ZLT when the pipe is control in pipe and the transferred length of current
+ * transaction equals to max packet size.
+ */
+ if ((length == khciState->endpointState[index].stateUnion.stateBitField.maxPacketSize) &&
+ (USB_CONTROL_ENDPOINT == endpoint))
+ {
+ usb_setup_struct_t *setup_packet =
+ (usb_setup_struct_t
+ *)(&khciState->setupPacketBuffer[(USB_SETUP_PACKET_SIZE * khciState->setupBufferIndex)]);
+ /*
+ * Send the ZLT and terminate the token done interrupt service when the tranferred length in data phase
+ * is less than the host request.
+ */
+ if (USB_SHORT_FROM_LITTLE_ENDIAN(setup_packet->wLength) >
+ khciState->endpointState[index].transferLength)
+ {
+ (void)USB_DeviceSendRequest(khciState->deviceHandle, endpoint, (uint8_t *)NULL, 0U);
+ return;
+ }
+ }
+ }
+ else
+ {
+ /* Send remaining data and terminate the token done interrupt service. */
+ (void)USB_DeviceKhciSend(khciState, endpoint | (USB_IN << 0x07U),
+ khciState->endpointState[index].transferBuffer, remainingLength);
+ return;
+ }
+ }
+ else
+ {
+ if ((USB_CONTROL_ENDPOINT == endpoint) && (0U == length))
+ {
+ message.length = 0U;
+ message.buffer = (uint8_t *)NULL;
+ }
+ else
+ {
+ if (0U == khciState->endpointState[index].stateUnion.stateBitField.dmaAlign)
+ {
+ uint8_t *buffer = (uint8_t *)USB_LONG_FROM_LITTLE_ENDIAN(
+ USB_KHCI_BDT_GET_ADDRESS((uint32_t)khciState->bdt, endpoint, USB_OUT,
+ khciState->endpointState[index].stateUnion.stateBitField.bdtOdd));
+ uint8_t *transferBuffer =
+ khciState->endpointState[index].transferBuffer + khciState->endpointState[index].transferDone;
+ if (buffer != transferBuffer)
+ {
+ for (uint32_t i = 0U; i < length; i++)
+ {
+ transferBuffer[i] = buffer[i];
+ }
+ }
+ khciState->isDmaAlignBufferInusing = 0U;
+ }
+ /* The transferred length */
+ khciState->endpointState[index].transferDone += length;
+ /* Remaining length */
+ remainingLength =
+ khciState->endpointState[index].transferLength - khciState->endpointState[index].transferDone;
+
+ if ((USB_CONTROL_ENDPOINT == endpoint) && isSetup)
+ {
+ USB_DeviceKhciCancel(khciState,
+ (endpoint | (USB_IN << USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_SHIFT)));
+ khciState->endpointState[(USB_CONTROL_ENDPOINT << 1U) | USB_OUT].stateUnion.stateBitField.data0 = 1U;
+ khciState->endpointState[(USB_CONTROL_ENDPOINT << 1U) | USB_IN].stateUnion.stateBitField.data0 = 1U;
+ }
+ else
+ {
+ khciState->endpointState[index].stateUnion.stateBitField.data0 ^= 1U;
+ }
+ khciState->endpointState[index].stateUnion.stateBitField.bdtOdd ^= 1U;
+ if ((!khciState->endpointState[index].transferLength) || (!remainingLength) ||
+ (khciState->endpointState[index].stateUnion.stateBitField.maxPacketSize > length))
+ {
+ message.length = khciState->endpointState[index].transferDone;
+ message.buffer = khciState->endpointState[index].transferBuffer;
+ khciState->endpointState[index].stateUnion.stateBitField.transferring = 0U;
+ }
+ else
+ {
+ /* Receive remaining data and terminate the token done interrupt service. */
+ USB_DeviceKhciRecv(khciState, (endpoint) | (USB_OUT << 0x07U),
+ khciState->endpointState[index].transferBuffer, remainingLength);
+ return;
+ }
+ }
+ }
+
+ message.isSetup = isSetup;
+ message.code = (endpoint) | (uint8_t)(((uint32_t)direction << 0x07U));
+
+ /* Notify the up layer the KHCI status changed. */
+ USB_DeviceNotificationTrigger(khciState->deviceHandle, &message);
+
+ khciState->registerBase->CTL &= ~USB_CTL_TXSUSPENDTOKENBUSY_MASK;
+}
+
+/*!
+ * @brief Handle the USB bus reset interrupt.
+ *
+ * The function is used to handle the USB bus reset interrupt.
+ *
+ * @param khciState Pointer of the device KHCI state structure.
+ *
+ */
+static void USB_DeviceKhciInterruptReset(usb_device_khci_state_struct_t *khciState)
+{
+ usb_device_callback_message_struct_t message;
+
+ /* Set KHCI reset flag */
+ khciState->isResetting = 1U;
+
+ /* Clear the reset interrupt */
+ khciState->registerBase->ISTAT = (kUSB_KhciInterruptReset);
+
+ message.buffer = (uint8_t *)NULL;
+ message.code = kUSB_DeviceNotifyBusReset;
+ message.length = 0U;
+ message.isSetup = 0U;
+ /* Notify up layer the USB bus reset signal detected. */
+ USB_DeviceNotificationTrigger(khciState->deviceHandle, &message);
+}
+
+/* The USB suspend and resume signals need to be detected and handled when the low power or remote wakeup function
+ * enabled. */
+#if ((defined(USB_DEVICE_CONFIG_LOW_POWER_MODE) && (USB_DEVICE_CONFIG_LOW_POWER_MODE > 0U)) || \
+ (defined(USB_DEVICE_CONFIG_REMOTE_WAKEUP) && (USB_DEVICE_CONFIG_REMOTE_WAKEUP > 0U)))
+
+/*!
+ * @brief Handle the suspend interrupt.
+ *
+ * The function is used to handle the suspend interrupt when the suspend signal detected.
+ *
+ * @param khciState Pointer of the device KHCI state structure.
+ *
+ */
+static void USB_DeviceKhciInterruptSleep(usb_device_khci_state_struct_t *khciState)
+{
+ usb_device_callback_message_struct_t message;
+
+ /* Enable the resume interrupt */
+ khciState->registerBase->INTEN |= kUSB_KhciInterruptResume;
+ /* Disable the suspend interrupt */
+ khciState->registerBase->INTEN &= ~kUSB_KhciInterruptSleep;
+
+ /* Clear the suspend interrupt */
+ khciState->registerBase->ISTAT = (kUSB_KhciInterruptSleep);
+ /* Clear the resume interrupt */
+ khciState->registerBase->ISTAT = (kUSB_KhciInterruptResume);
+
+ message.buffer = (uint8_t *)NULL;
+ message.code = kUSB_DeviceNotifySuspend;
+ message.length = 0U;
+ message.isSetup = 0U;
+
+ /* Notify up layer the USB suspend signal detected. */
+ USB_DeviceNotificationTrigger(khciState->deviceHandle, &message);
+}
+
+/*!
+ * @brief Handle the resume interrupt.
+ *
+ * The function is used to handle the resume interrupt when the resume signal detected.
+ *
+ * @param khciState Pointer of the device KHCI state structure.
+ *
+ */
+static void USB_DeviceKhciInterruptResume(usb_device_khci_state_struct_t *khciState)
+{
+ usb_device_callback_message_struct_t message;
+
+ /* Enable the suspend interrupt */
+ khciState->registerBase->INTEN |= kUSB_KhciInterruptSleep;
+ /* Disable the resume interrupt */
+ khciState->registerBase->INTEN &= ~kUSB_KhciInterruptResume;
+
+ /* Clear the resume interrupt */
+ khciState->registerBase->ISTAT = (kUSB_KhciInterruptResume);
+ /* Clear the suspend interrupt */
+ khciState->registerBase->ISTAT = (kUSB_KhciInterruptSleep);
+
+ message.buffer = (uint8_t *)NULL;
+ message.code = kUSB_DeviceNotifyResume;
+ message.length = 0U;
+ message.isSetup = 0U;
+
+ /* Notify up layer the USB resume signal detected. */
+ USB_DeviceNotificationTrigger(khciState->deviceHandle, &message);
+}
+#endif /* USB_DEVICE_CONFIG_LOW_POWER_MODE || USB_DEVICE_CONFIG_REMOTE_WAKEUP */
+
+#if (defined(USB_DEVICE_CONFIG_DETACH_ENABLE) && (USB_DEVICE_CONFIG_DETACH_ENABLE > 0U)) && \
+ (defined(FSL_FEATURE_USB_KHCI_VBUS_DETECT_ENABLED) && (FSL_FEATURE_USB_KHCI_VBUS_DETECT_ENABLED > 0U))
+/*!
+ * @brief Handle the VBUS rising interrupt.
+ *
+ * The function is used to handle the VBUS rising interrupt when the VBUS rising signal detected.
+ *
+ * @param khciState Pointer of the device KHCI state structure.
+ *
+ */
+static void USB_DeviceKhciInterruptVbusRising(usb_device_khci_state_struct_t *khciState)
+{
+ usb_device_callback_message_struct_t message;
+
+ /* Disable the VBUS rising interrupt */
+ khciState->registerBase->MISCCTRL &= ~USB_MISCCTRL_VREDG_EN_MASK;
+ /* Enable the VBUS rising interrupt */
+ khciState->registerBase->MISCCTRL |= USB_MISCCTRL_VREDG_EN_MASK;
+
+ message.buffer = (uint8_t *)NULL;
+ message.code = kUSB_DeviceNotifyAttach;
+ message.length = 0U;
+ message.isSetup = 0U;
+
+ /* Notify up layer the USB VBUS rising signal detected. */
+ USB_DeviceNotificationTrigger(khciState->deviceHandle, &message);
+}
+
+/*!
+ * @brief Handle the VBUS falling interrupt.
+ *
+ * The function is used to handle the VBUS falling interrupt when the VBUS falling signal detected.
+ *
+ * @param khciState Pointer of the device KHCI state structure.
+ *
+ */
+static void USB_DeviceKhciInterruptVbusFalling(usb_device_khci_state_struct_t *khciState)
+{
+ usb_device_callback_message_struct_t message;
+
+ /* Disable the VBUS rising interrupt */
+ khciState->registerBase->MISCCTRL &= ~USB_MISCCTRL_VFEDG_EN_MASK;
+ /* Enable the VBUS rising interrupt */
+ khciState->registerBase->MISCCTRL |= USB_MISCCTRL_VFEDG_EN_MASK;
+
+ message.buffer = (uint8_t *)NULL;
+ message.code = kUSB_DeviceNotifyDetach;
+ message.length = 0U;
+ message.isSetup = 0U;
+
+ /* Notify up layer the USB VBUS falling signal detected. */
+ USB_DeviceNotificationTrigger(khciState->deviceHandle, &message);
+}
+#endif /* USB_DEVICE_CONFIG_DETACH_ENABLE || FSL_FEATURE_USB_KHCI_VBUS_DETECT_ENABLED */
+
+#if 0U
+/*!
+ * @brief Handle the sof interrupt.
+ *
+ * The function is used to handle the sof interrupt.
+ *
+ * @param khciState Pointer of the device KHCI state structure.
+ *
+ */
+void USB_DeviceKhciInterruptSof(usb_device_khci_state_struct_t *khciState)
+{
+ khciState->registerBase->ISTAT = (kUSB_KhciInterruptSofToken);
+
+ khciState->registerBase->ISTAT = (kUSB_KhciInterruptResume);
+}
+#endif
+
+/*!
+ * @brief Handle endpoint stalled interrupt.
+ *
+ * The function is used to handle endpoint stalled interrupt.
+ *
+ * @param khciState Pointer of the device KHCI state structure.
+ *
+ */
+static void USB_DeviceKhciInterruptStall(usb_device_khci_state_struct_t *khciState)
+{
+ /* Clear the endpoint stalled interrupt flag */
+ khciState->registerBase->ISTAT = (kUSB_KhciInterruptStall);
+
+ /* Un-stall the control in and out pipe when the control in or out pipe stalled. */
+ if ((khciState->endpointState[(USB_CONTROL_ENDPOINT << 1U) | USB_IN].stateUnion.stateBitField.stalled) ||
+ (khciState->endpointState[(USB_CONTROL_ENDPOINT << 1U) | USB_OUT].stateUnion.stateBitField.stalled))
+ {
+ USB_DeviceKhciEndpointUnstall(
+ khciState, (USB_CONTROL_ENDPOINT | (USB_IN << USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_SHIFT)));
+ USB_DeviceKhciEndpointUnstall(
+ khciState, (USB_CONTROL_ENDPOINT | (USB_OUT << USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_SHIFT)));
+ }
+}
+
+#if defined(USB_DEVICE_CONFIG_KHCI_ERROR_HANDLING) && (USB_DEVICE_CONFIG_KHCI_ERROR_HANDLING > 0U)
+static void USB_DeviceKhciInterruptError(usb_device_khci_state_struct_t *khciState)
+{
+ usb_device_callback_message_struct_t message;
+
+ khciState->registerBase->ISTAT = (kUSB_KhciInterruptError);
+
+ message.buffer = (uint8_t *)NULL;
+ message.code = kUSB_DeviceNotifyError;
+ message.length = 0U;
+ message.isSetup = 0U;
+
+ /* Notify up layer the USB error detected. */
+ USB_DeviceNotificationTrigger(khciState->deviceHandle, &message);
+}
+#endif /* USB_DEVICE_CONFIG_KHCI_ERROR_HANDLING */
+
+/*!
+ * @brief Initialize the USB device KHCI instance.
+ *
+ * This function initizlizes the USB device KHCI module specified by the controllerId.
+ *
+ * @param controllerId The controller id of the USB IP. Please refer to enumeration type usb_controller_index_t.
+ * @param handle Pointer of the device handle, used to identify the device object is belonged to.
+ * @param khciHandle It is out parameter, is used to return pointer of the device KHCI handle to the caller.
+ *
+ * @return A USB error code or kStatus_USB_Success.
+ */
+usb_status_t USB_DeviceKhciInit(uint8_t controllerId,
+ usb_device_handle handle,
+ usb_device_controller_handle *khciHandle)
+{
+ usb_device_khci_state_struct_t *khciState;
+ uint32_t khci_base[] = USB_BASE_ADDRS;
+
+ if (((controllerId - kUSB_ControllerKhci0) >= (uint8_t)USB_DEVICE_CONFIG_KHCI) ||
+ ((controllerId - kUSB_ControllerKhci0) >= (sizeof(khci_base) / sizeof(uint32_t))))
+ {
+ return kStatus_USB_ControllerNotFound;
+ }
+ khciState = &s_UsbDeviceKhciState[controllerId - kUSB_ControllerKhci0];
+
+ khciState->controllerId = controllerId;
+
+ khciState->registerBase = (USB_Type *)khci_base[controllerId - kUSB_ControllerKhci0];
+
+ khciState->dmaAlignBuffer = (uint8_t *)&s_UsbDeviceKhciDmaAlignBuffer[controllerId - kUSB_ControllerKhci0][0];
+
+ /* Clear all interrupt flags. */
+ khciState->registerBase->ISTAT = 0xFFU;
+
+ /* Disable the device functionality. */
+ USB_DeviceKhciControl(khciState, kUSB_DeviceControlStop, NULL);
+
+ khciState->bdt = s_UsbDeviceKhciBdtBuffer[controllerId - kUSB_ControllerKhci0];
+
+ /* Set BDT buffer address */
+ khciState->registerBase->BDTPAGE1 = (uint8_t)((((uint32_t)khciState->bdt) >> 8U) & 0xFFU);
+ khciState->registerBase->BDTPAGE2 = (uint8_t)((((uint32_t)khciState->bdt) >> 16U) & 0xFFU);
+ khciState->registerBase->BDTPAGE3 = (uint8_t)((((uint32_t)khciState->bdt) >> 24U) & 0xFFU);
+
+#if (defined(USB_DEVICE_CONFIG_DETACH_ENABLE) && (USB_DEVICE_CONFIG_DETACH_ENABLE > 0U)) && \
+ (defined(FSL_FEATURE_USB_KHCI_VBUS_DETECT_ENABLED) && (FSL_FEATURE_USB_KHCI_VBUS_DETECT_ENABLED > 0U))
+ khciState->registerBase->MISCCTRL |= USB_MISCCTRL_VREDG_EN_MASK | USB_MISCCTRL_VFEDG_EN_MASK;
+#endif
+
+#if defined(FSL_FEATURE_USB_KHCI_KEEP_ALIVE_ENABLED) && (FSL_FEATURE_USB_KHCI_KEEP_ALIVE_ENABLED > 0U) \
+&& defined(USB_DEVICE_CONFIG_KEEP_ALIVE_MODE) && \
+ (USB_DEVICE_CONFIG_KEEP_ALIVE_MODE > 0U) && defined(FSL_FEATURE_USB_KHCI_USB_RAM) && \
+ (FSL_FEATURE_USB_KHCI_USB_RAM > 0U)
+ khciState->registerBase->CLK_RECOVER_CTRL |= USB_CLK_RECOVER_CTRL_CLOCK_RECOVER_EN_MASK;
+ khciState->registerBase->KEEP_ALIVE_CTRL =
+ USB_KEEP_ALIVE_CTRL_KEEP_ALIVE_EN_MASK | USB_KEEP_ALIVE_CTRL_OWN_OVERRD_EN_MASK |
+ USB_KEEP_ALIVE_CTRL_WAKE_INT_EN_MASK | FSL_FEATURE_USB_KHCI_KEEP_ALIVE_MODE_CONTROL;
+ /* wake on out and setup transaction */
+ khciState->registerBase->KEEP_ALIVE_WKCTRL = 0x1U;
+ PMC->REGSC |= PMC_REGSC_BGEN_MASK | PMC_REGSC_VLPO_MASK;
+#endif
+ /* Set KHCI device state to default value. */
+ USB_DeviceKhciSetDefaultState(khciState);
+
+ *khciHandle = khciState;
+ khciState->deviceHandle = (usb_device_struct_t *)handle;
+
+ return kStatus_USB_Success;
+}
+
+/*!
+ * @brief De-initialize the USB device KHCI instance.
+ *
+ * This function de-initizlizes the USB device KHCI module.
+ *
+ * @param khciHandle Pointer of the device KHCI handle.
+ *
+ * @return A USB error code or kStatus_USB_Success.
+ */
+usb_status_t USB_DeviceKhciDeinit(usb_device_controller_handle khciHandle)
+{
+ usb_device_khci_state_struct_t *khciState = (usb_device_khci_state_struct_t *)khciHandle;
+
+ if (!khciHandle)
+ {
+ return kStatus_USB_InvalidHandle;
+ }
+ /* Clear all interrupt flags. */
+ khciState->registerBase->ISTAT = 0xFFU;
+ /* Disable all interrupts. */
+ khciState->registerBase->INTEN &= ~(0xFFU);
+ /* Clear device address. */
+ khciState->registerBase->ADDR = (0U);
+
+ /* Clear USB_CTL register */
+ khciState->registerBase->CTL = 0x00U;
+ khciState->registerBase->USBCTRL |= USB_USBCTRL_PDE_MASK | USB_USBCTRL_SUSP_MASK;
+
+ return kStatus_USB_Success;
+}
+
+/*!
+ * @brief Send data through a specified endpoint.
+ *
+ * This function sends data through a specified endpoint.
+ *
+ * @param khciHandle Pointer of the device KHCI handle.
+ * @param endpointAddress Endpoint index.
+ * @param buffer The memory address to hold the data need to be sent.
+ * @param length The data length need to be sent.
+ *
+ * @return A USB error code or kStatus_USB_Success.
+ *
+ * @note The return value just means if the sending request is successful or not; the transfer done is notified by the
+ * corresponding callback function.
+ * Currently, only one transfer request can be supported for one specific endpoint.
+ * If there is a specific requirement to support multiple transfer requests for one specific endpoint, the application
+ * should implement a queue in the application level.
+ * The subsequent transfer could begin only when the previous transfer is done (get notification through the endpoint
+ * callback).
+ */
+usb_status_t USB_DeviceKhciSend(usb_device_controller_handle khciHandle,
+ uint8_t endpointAddress,
+ uint8_t *buffer,
+ uint32_t length)
+{
+ usb_device_khci_state_struct_t *khciState = (usb_device_khci_state_struct_t *)khciHandle;
+ uint32_t index = ((endpointAddress & USB_ENDPOINT_NUMBER_MASK) << 1U) | USB_IN;
+ usb_status_t error = kStatus_USB_Error;
+
+ /* Save the tansfer information */
+ if (0U == khciState->endpointState[index].stateUnion.stateBitField.transferring)
+ {
+ khciState->endpointState[index].transferDone = 0U;
+ khciState->endpointState[index].transferBuffer = buffer;
+ khciState->endpointState[index].transferLength = length;
+ khciState->endpointState[index].stateUnion.stateBitField.dmaAlign = 1U;
+ }
+
+ /* Data length needs to less than max packet size in each call. */
+ if (length > khciState->endpointState[index].stateUnion.stateBitField.maxPacketSize)
+ {
+ length = khciState->endpointState[index].stateUnion.stateBitField.maxPacketSize;
+ }
+
+ /* Send data when the device is not resetting. */
+ if (0U == khciState->isResetting)
+ {
+ error = USB_DeviceKhciEndpointTransfer(khciState, endpointAddress & USB_ENDPOINT_NUMBER_MASK, USB_IN,
+ (uint8_t *)((uint32_t)khciState->endpointState[index].transferBuffer +
+ (uint32_t)khciState->endpointState[index].transferDone),
+ length);
+ }
+
+ /* Prime a transfer to receive next setup packet if the dat length is zero in a control in endpoint. */
+ if ((0U == khciState->endpointState[index].transferDone) && (0U == length) &&
+ (USB_CONTROL_ENDPOINT == (endpointAddress & USB_ENDPOINT_NUMBER_MASK)))
+ {
+ USB_DeviceKhciPrimeNextSetup(khciState);
+ }
+ return error;
+}
+
+/*!
+ * @brief Receive data through a specified endpoint.
+ *
+ * This function Receives data through a specified endpoint.
+ *
+ * @param khciHandle Pointer of the device KHCI handle.
+ * @param endpointAddress Endpoint index.
+ * @param buffer The memory address to save the received data.
+ * @param length The data length want to be received.
+ *
+ * @return A USB error code or kStatus_USB_Success.
+ *
+ * @note The return value just means if the receiving request is successful or not; the transfer done is notified by the
+ * corresponding callback function.
+ * Currently, only one transfer request can be supported for one specific endpoint.
+ * If there is a specific requirement to support multiple transfer requests for one specific endpoint, the application
+ * should implement a queue in the application level.
+ * The subsequent transfer could begin only when the previous transfer is done (get notification through the endpoint
+ * callback).
+ */
+usb_status_t USB_DeviceKhciRecv(usb_device_controller_handle khciHandle,
+ uint8_t endpointAddress,
+ uint8_t *buffer,
+ uint32_t length)
+{
+ usb_device_khci_state_struct_t *khciState = (usb_device_khci_state_struct_t *)khciHandle;
+ uint32_t index = ((endpointAddress & USB_ENDPOINT_NUMBER_MASK) << 1U) | USB_OUT;
+ usb_status_t error = kStatus_USB_Error;
+
+ /* Save the tansfer information */
+ if (0U == khciState->endpointState[index].stateUnion.stateBitField.transferring)
+ {
+ khciState->endpointState[index].transferDone = 0U;
+ khciState->endpointState[index].transferBuffer = buffer;
+ khciState->endpointState[index].transferLength = length;
+ }
+ khciState->endpointState[index].stateUnion.stateBitField.dmaAlign = 1U;
+
+ /* Data length needs to less than max packet size in each call. */
+ if (length > khciState->endpointState[index].stateUnion.stateBitField.maxPacketSize)
+ {
+ length = khciState->endpointState[index].stateUnion.stateBitField.maxPacketSize;
+ }
+
+ buffer = (uint8_t *)((uint32_t)buffer + (uint32_t)khciState->endpointState[index].transferDone);
+
+ if ((khciState->dmaAlignBuffer) && (0U == khciState->isDmaAlignBufferInusing) &&
+ (USB_DEVICE_CONFIG_KHCI_DMA_ALIGN_BUFFER_LENGTH >= length) &&
+ ((length & 0x03U) || (((uint32_t)buffer) & 0x03U)))
+ {
+ khciState->endpointState[index].stateUnion.stateBitField.dmaAlign = 0U;
+ buffer = khciState->dmaAlignBuffer;
+ khciState->isDmaAlignBufferInusing = 1U;
+ }
+
+ /* Receive data when the device is not resetting. */
+ if (0U == khciState->isResetting)
+ {
+ error = USB_DeviceKhciEndpointTransfer(khciState, endpointAddress & USB_ENDPOINT_NUMBER_MASK, USB_OUT, buffer,
+ length);
+ }
+
+ /* Prime a transfer to receive next setup packet if the dat length is zero in a control out endpoint. */
+ if ((0U == length) && (USB_CONTROL_ENDPOINT == (endpointAddress & USB_ENDPOINT_NUMBER_MASK)))
+ {
+ khciState->endpointState[index].stateUnion.stateBitField.bdtOdd ^= 1U;
+ khciState->endpointState[index].stateUnion.stateBitField.transferring = 0U;
+ USB_DeviceKhciPrimeNextSetup(khciState);
+ }
+ return error;
+}
+
+/*!
+ * @brief Cancel the pending transfer in a specified endpoint.
+ *
+ * The function is used to cancel the pending transfer in a specified endpoint.
+ *
+ * @param khciHandle Pointer of the device KHCI handle.
+ * @param ep Endpoint address, bit7 is the direction of endpoint, 1U - IN, abd 0U - OUT.
+ *
+ * @return A USB error code or kStatus_USB_Success.
+ */
+usb_status_t USB_DeviceKhciCancel(usb_device_controller_handle khciHandle, uint8_t ep)
+{
+ usb_device_khci_state_struct_t *khciState = (usb_device_khci_state_struct_t *)khciHandle;
+ usb_device_callback_message_struct_t message;
+ uint8_t index = ((ep & USB_ENDPOINT_NUMBER_MASK) << 1U) | ((ep & USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_MASK) >>
+ USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_SHIFT);
+
+ /* Cancel the transfer and notify the up layer when the endpoint is busy. */
+ if (khciState->endpointState[index].stateUnion.stateBitField.transferring)
+ {
+ message.length = USB_UNINITIALIZED_VAL_32;
+ message.buffer = khciState->endpointState[index].transferBuffer;
+ message.code = ep;
+ message.isSetup = 0U;
+ khciState->endpointState[index].stateUnion.stateBitField.transferring = 0U;
+ USB_DeviceNotificationTrigger(khciState->deviceHandle, &message);
+ }
+ return kStatus_USB_Success;
+}
+
+/*!
+ * @brief Control the status of the selected item.
+ *
+ * The function is used to control the status of the selected item.
+ *
+ * @param khciHandle Pointer of the device KHCI handle.
+ * @param type The selected item. Please refer to enumeration type usb_device_control_type_t.
+ * @param param The param type is determined by the selected item.
+ *
+ * @return A USB error code or kStatus_USB_Success.
+ */
+usb_status_t USB_DeviceKhciControl(usb_device_controller_handle khciHandle, usb_device_control_type_t type, void *param)
+{
+ usb_device_khci_state_struct_t *khciState = (usb_device_khci_state_struct_t *)khciHandle;
+ usb_status_t error = kStatus_USB_Error;
+ uint16_t *temp16;
+ uint8_t *temp8;
+#if defined(USB_DEVICE_CONFIG_REMOTE_WAKEUP) && (USB_DEVICE_CONFIG_REMOTE_WAKEUP > 0U)
+ USB_OSA_SR_ALLOC();
+#endif /* USB_DEVICE_CONFIG_REMOTE_WAKEUP */
+
+ if (!khciHandle)
+ {
+ return kStatus_USB_InvalidHandle;
+ }
+
+ switch (type)
+ {
+ case kUSB_DeviceControlRun:
+ khciState->registerBase->USBCTRL = 0U;
+#if defined(FSL_FEATURE_USB_KHCI_OTG_ENABLED) && (FSL_FEATURE_USB_KHCI_OTG_ENABLED > 0U)
+ if (khciState->registerBase->OTGCTL & USB_OTGCTL_OTGEN_MASK)
+ {
+ khciState->registerBase->OTGCTL |= USB_OTGCTL_DPHIGH_MASK;
+ }
+#endif /* FSL_FEATURE_USB_KHCI_OTG_ENABLED */
+ khciState->registerBase->CONTROL |= USB_CONTROL_DPPULLUPNONOTG_MASK;
+ khciState->registerBase->CTL |= USB_CTL_USBENSOFEN_MASK;
+
+ error = kStatus_USB_Success;
+ break;
+ case kUSB_DeviceControlStop:
+#if defined(FSL_FEATURE_USB_KHCI_OTG_ENABLED) && (FSL_FEATURE_USB_KHCI_OTG_ENABLED > 0U)
+ if (khciState->registerBase->OTGCTL & USB_OTGCTL_OTGEN_MASK)
+ {
+ khciState->registerBase->OTGCTL &= ~USB_OTGCTL_DPHIGH_MASK;
+ }
+#endif /* FSL_FEATURE_USB_KHCI_OTG_ENABLED */
+ khciState->registerBase->CONTROL &= ~USB_CONTROL_DPPULLUPNONOTG_MASK;
+ error = kStatus_USB_Success;
+ break;
+ case kUSB_DeviceControlEndpointInit:
+ if (param)
+ {
+ error = USB_DeviceKhciEndpointInit(khciState, (usb_device_endpoint_init_struct_t *)param);
+ }
+ break;
+ case kUSB_DeviceControlEndpointDeinit:
+ if (param)
+ {
+ temp8 = (uint8_t *)param;
+ error = USB_DeviceKhciEndpointDeinit(khciState, *temp8);
+ }
+ break;
+ case kUSB_DeviceControlEndpointStall:
+ if (param)
+ {
+ temp8 = (uint8_t *)param;
+ error = USB_DeviceKhciEndpointStall(khciState, *temp8);
+ }
+ break;
+ case kUSB_DeviceControlEndpointUnstall:
+ if (param)
+ {
+ temp8 = (uint8_t *)param;
+ error = USB_DeviceKhciEndpointUnstall(khciState, *temp8);
+ }
+ break;
+ case kUSB_DeviceControlGetDeviceStatus:
+ if (param)
+ {
+ temp16 = (uint16_t *)param;
+ *temp16 =
+ (USB_DEVICE_CONFIG_SELF_POWER << (USB_REQUEST_STANDARD_GET_STATUS_DEVICE_SELF_POWERED_SHIFT)) |
+ (USB_DEVICE_CONFIG_REMOTE_WAKEUP << (USB_REQUEST_STANDARD_GET_STATUS_DEVICE_REMOTE_WARKUP_SHIFT));
+ error = kStatus_USB_Success;
+ }
+ break;
+ case kUSB_DeviceControlGetEndpointStatus:
+ if (param)
+ {
+ usb_device_endpoint_status_struct_t *endpointStatus = (usb_device_endpoint_status_struct_t *)param;
+
+ if (((endpointStatus->endpointAddress) & USB_ENDPOINT_NUMBER_MASK) < USB_DEVICE_CONFIG_ENDPOINTS)
+ {
+ endpointStatus->endpointStatus =
+ (uint16_t)(
+ khciState
+ ->endpointState[(((endpointStatus->endpointAddress) & USB_ENDPOINT_NUMBER_MASK) << 1U) |
+ (((endpointStatus->endpointAddress) &
+ USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_MASK) >>
+ USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_SHIFT)]
+ .stateUnion.stateBitField.stalled == 1U) ?
+ kUSB_DeviceEndpointStateStalled :
+ kUSB_DeviceEndpointStateIdle;
+ error = kStatus_USB_Success;
+ }
+ }
+ break;
+ case kUSB_DeviceControlSetDeviceAddress:
+ if (param)
+ {
+ temp8 = (uint8_t *)param;
+ khciState->registerBase->ADDR = (*temp8);
+ error = kStatus_USB_Success;
+ }
+ break;
+ case kUSB_DeviceControlGetSynchFrame:
+ break;
+ case kUSB_DeviceControlResume:
+#if defined(USB_DEVICE_CONFIG_REMOTE_WAKEUP) && (USB_DEVICE_CONFIG_REMOTE_WAKEUP > 0U)
+ USB_OSA_ENTER_CRITICAL();
+ khciState->registerBase->CTL |= USB_CTL_RESUME_MASK;
+ for (uint32_t i = 500U; i > 0U; i--)
+ {
+ __ASM("nop");
+ }
+ khciState->registerBase->CTL &= ~USB_CTL_RESUME_MASK;
+ USB_OSA_EXIT_CRITICAL();
+ error = kStatus_USB_Success;
+#endif /* USB_DEVICE_CONFIG_REMOTE_WAKEUP */
+ break;
+ case kUSB_DeviceControlSetDefaultStatus:
+ for (uint8_t count = 0U; count < USB_DEVICE_CONFIG_ENDPOINTS; count++)
+ {
+ USB_DeviceKhciEndpointDeinit(khciState, (count | (USB_IN << 0x07U)));
+ USB_DeviceKhciEndpointDeinit(khciState, (count | (USB_OUT << 0x07U)));
+ }
+ USB_DeviceKhciSetDefaultState(khciState);
+ error = kStatus_USB_Success;
+ break;
+ case kUSB_DeviceControlGetSpeed:
+ if (param)
+ {
+ temp8 = (uint8_t *)param;
+ *temp8 = USB_SPEED_FULL;
+ error = kStatus_USB_Success;
+ }
+ break;
+ case kUSB_DeviceControlGetOtgStatus:
+ break;
+ case kUSB_DeviceControlSetOtgStatus:
+ break;
+ case kUSB_DeviceControlSetTestMode:
+ break;
+ default:
+ break;
+ }
+
+ return error;
+}
+
+/*!
+ * @brief Handle the KHCI device interrupt.
+ *
+ * The function is used to handle the KHCI device interrupt.
+ *
+ * @param deviceHandle The device handle got from USB_DeviceInit.
+ *
+ */
+void USB_DeviceKhciIsrFunction(void *deviceHandle)
+{
+ usb_device_struct_t *handle = (usb_device_struct_t *)deviceHandle;
+ usb_device_khci_state_struct_t *khciState;
+ uint8_t status;
+
+ if (NULL == deviceHandle)
+ {
+ return;
+ }
+
+ khciState = (usb_device_khci_state_struct_t *)(handle->controllerHandle);
+
+ status = khciState->registerBase->ISTAT;
+#if defined(FSL_FEATURE_USB_KHCI_KEEP_ALIVE_ENABLED) && (FSL_FEATURE_USB_KHCI_KEEP_ALIVE_ENABLED > 0U) \
+&& defined(USB_DEVICE_CONFIG_KEEP_ALIVE_MODE) && \
+ (USB_DEVICE_CONFIG_KEEP_ALIVE_MODE > 0U) && defined(FSL_FEATURE_USB_KHCI_USB_RAM) && \
+ (FSL_FEATURE_USB_KHCI_USB_RAM > 0U)
+ /* Clear EEP_ALIVE_CTRL_WAKE_INT interrupt state */
+ if (khciState->registerBase->KEEP_ALIVE_CTRL & USB_KEEP_ALIVE_CTRL_WAKE_INT_STS_MASK)
+ {
+ khciState->registerBase->KEEP_ALIVE_CTRL |= USB_KEEP_ALIVE_CTRL_WAKE_INT_STS_MASK;
+ }
+ /* Clear SOFTOK interrupt state */
+ if (khciState->registerBase->ISTAT & USB_ISTAT_SOFTOK_MASK)
+ {
+ khciState->registerBase->ISTAT = USB_ISTAT_SOFTOK_MASK;
+ }
+#endif
+#if defined(USB_DEVICE_CONFIG_KHCI_ERROR_HANDLING) && (USB_DEVICE_CONFIG_KHCI_ERROR_HANDLING > 0U)
+ /* Error interrupt */
+ if (status & kUSB_KhciInterruptError)
+ {
+ USB_DeviceKhciInterruptError(khciState);
+ }
+#endif /* USB_DEVICE_CONFIG_KHCI_ERROR_HANDLING */
+ /* Token done interrupt */
+ if (status & kUSB_KhciInterruptTokenDone)
+ {
+ USB_DeviceKhciInterruptTokenDone(khciState);
+ }
+
+ /* Reset interrupt */
+ if (status & kUSB_KhciInterruptReset)
+ {
+ USB_DeviceKhciInterruptReset(khciState);
+ }
+
+#if ((defined(USB_DEVICE_CONFIG_LOW_POWER_MODE) && (USB_DEVICE_CONFIG_LOW_POWER_MODE > 0U)) || \
+ (defined(USB_DEVICE_CONFIG_REMOTE_WAKEUP) && (USB_DEVICE_CONFIG_REMOTE_WAKEUP > 0U)))
+ /* Suspend interrupt */
+ if (status & kUSB_KhciInterruptSleep)
+ {
+ USB_DeviceKhciInterruptSleep(khciState);
+ }
+
+ /* Resume interrupt */
+ if (status & kUSB_KhciInterruptResume)
+ {
+ USB_DeviceKhciInterruptResume(khciState);
+ }
+#endif /* USB_DEVICE_CONFIG_LOW_POWER_MODE || USB_DEVICE_CONFIG_REMOTE_WAKEUP */
+
+ /* Endpoint stalled interrupt */
+ if (status & kUSB_KhciInterruptStall)
+ {
+ USB_DeviceKhciInterruptStall(khciState);
+ }
+
+#if (defined(USB_DEVICE_CONFIG_DETACH_ENABLE) && (USB_DEVICE_CONFIG_DETACH_ENABLE > 0U)) && \
+ (defined(FSL_FEATURE_USB_KHCI_VBUS_DETECT_ENABLED) && (FSL_FEATURE_USB_KHCI_VBUS_DETECT_ENABLED > 0U))
+ if (khciState->registerBase->USBTRC0 & USB_USBTRC0_VREDG_DET_MASK)
+ {
+ USB_DeviceKhciInterruptVbusRising(khciState);
+ }
+
+ if (khciState->registerBase->USBTRC0 & USB_USBTRC0_VFEDG_DET_MASK)
+ {
+ USB_DeviceKhciInterruptVbusFalling(khciState);
+ }
+#endif /* USB_DEVICE_CONFIG_DETACH_ENABLE && FSL_FEATURE_USB_KHCI_VBUS_DETECT_ENABLED */
+
+#if 0U
+ /* Sof token interrupt */
+ if (status & kUSB_KhciInterruptSofToken)
+ {
+ USB_DeviceKhciInterruptSof(khciState);
+ }
+#endif
+
+#if ((defined FSL_FEATURE_USB_KHCI_IRC48M_MODULE_CLOCK_ENABLED) && \
+ (FSL_FEATURE_USB_KHCI_IRC48M_MODULE_CLOCK_ENABLED > 0U))
+ status = khciState->registerBase->CLK_RECOVER_INT_STATUS;
+ if (status)
+ {
+ /* USB RECOVER interrupt is happenned */
+ if (USB_CLK_RECOVER_INT_STATUS_OVF_ERROR_MASK & status)
+ {
+ /* Indicates that the USB clock recovery algorithm has detected that the frequency trim adjustment needed
+ * for the IRC48M output clock is outside the available TRIM_FINE adjustment range for the IRC48M
+ * module.
+ */
+ }
+ khciState->registerBase->CLK_RECOVER_INT_STATUS = status;
+ }
+#endif
+}
+
+#endif /* USB_DEVICE_CONFIG_KHCI */
diff --git a/usb_1.1.0/device/usb_device_khci.h b/usb_1.1.0/device/usb_device_khci.h
new file mode 100644
index 0000000..2b0bf9f
--- /dev/null
+++ b/usb_1.1.0/device/usb_device_khci.h
@@ -0,0 +1,243 @@
+/*
+ * Copyright (c) 2015, Freescale Semiconductor, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * o Redistributions of source code must retain the above copyright notice, this list
+ * of conditions and the following disclaimer.
+ *
+ * o Redistributions in binary form must reproduce the above copyright notice, this
+ * list of conditions and the following disclaimer in the documentation and/or
+ * other materials provided with the distribution.
+ *
+ * o Neither the name of Freescale Semiconductor, Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __USB_DEVICE_KHCI_H__
+#define __USB_DEVICE_KHCI_H__
+
+/*!
+ * @addtogroup usb_device_controller_khci_driver
+ * @{
+ */
+
+/*******************************************************************************
+ * Definitions
+ ******************************************************************************/
+
+/*! @brief The maximum value of ISO maximum packet size for FS in USB specification 2.0 */
+#define USB_DEVICE_MAX_FS_ISO_MAX_PACKET_SIZE (1023U)
+
+/*! @brief The maximum value of non-ISO maximum packet size for FS in USB specification 2.0 */
+#define USB_DEVICE_MAX_FS_NONE_ISO_MAX_PACKET_SIZE (64U)
+
+/*! @brief Set BDT buffer address */
+#define USB_KHCI_BDT_SET_ADDRESS(bdt_base, ep, direction, odd, address) \
+ *((volatile uint32_t *)((bdt_base & 0xfffffe00U) | (((uint32_t)ep & 0x0fU) << 5U) | \
+ (((uint32_t)direction & 1U) << 4U) | (((uint32_t)odd & 1U) << 3U)) + \
+ 1U) = address
+
+/*! @brief Set BDT control fields*/
+#define USB_KHCI_BDT_SET_CONTROL(bdt_base, ep, direction, odd, control) \
+ *(volatile uint32_t *)((bdt_base & 0xfffffe00U) | (((uint32_t)ep & 0x0fU) << 5U) | \
+ (((uint32_t)direction & 1U) << 4U) | (((uint32_t)odd & 1U) << 3U)) = control
+
+/*! @brief Get BDT buffer address*/
+#define USB_KHCI_BDT_GET_ADDRESS(bdt_base, ep, direction, odd) \
+ (*((volatile uint32_t *)((bdt_base & 0xfffffe00U) | (((uint32_t)ep & 0x0fU) << 5U) | \
+ (((uint32_t)direction & 1U) << 4U) | (((uint32_t)odd & 1U) << 3U)) + \
+ 1U))
+
+/*! @brief Get BDT control fields*/
+#define USB_KHCI_BDT_GET_CONTROL(bdt_base, ep, direction, odd) \
+ (*(volatile uint32_t *)((bdt_base & 0xfffffe00U) | (((uint32_t)ep & 0x0fU) << 5U) | \
+ (((uint32_t)direction & 1U) << 4U) | (((uint32_t)odd & 1U) << 3U)))
+
+/*! @brief Endpoint state structure */
+typedef struct _usb_device_khci_endpoint_state_struct
+{
+ uint8_t *transferBuffer; /*!< Address of buffer containing the data to be transmitted */
+ uint32_t transferLength; /*!< Length of data to transmit. */
+ uint32_t transferDone; /*!< The data length has been transferred*/
+ union
+ {
+ uint32_t state; /*!< The state of the endpoint */
+ struct
+ {
+ uint32_t maxPacketSize : 10U; /*!< The maximum packet size of the endpoint */
+ uint32_t stalled : 1U; /*!< The endpoint is stalled or not */
+ uint32_t data0 : 1U; /*!< The data toggle of the transaction */
+ uint32_t bdtOdd : 1U; /*!< The BDT toggle of the endpoint */
+ uint32_t dmaAlign : 1U; /*!< Whether the transferBuffer is DMA aligned or not */
+ uint32_t transferring : 1U; /*!< The endpoint is transferring */
+ uint32_t resersed : 1U; /*!< Reversed */
+ } stateBitField;
+ } stateUnion;
+} usb_device_khci_endpoint_state_struct_t;
+
+/*! @brief KHCI state structure */
+typedef struct _usb_device_khci_state_struct
+{
+ usb_device_struct_t *deviceHandle; /*!< Device handle used to identify the device object belongs to */
+ uint8_t *bdt; /*!< BDT buffer address */
+ USB_Type *registerBase; /*!< The base address of the register */
+ uint8_t setupPacketBuffer[USB_SETUP_PACKET_SIZE * 2]; /*!< The setup request buffer */
+ uint8_t
+ *dmaAlignBuffer; /*!< This buffer is used to fix the transferBuffer or transferLength does
+ not align to 4-bytes when the function USB_DeviceKhciRecv is called.
+ The macro USB_DEVICE_CONFIG_KHCI_DMA_ALIGN is used to enable or disable this feature.
+ If the feature is enabled, when the transferBuffer or transferLength does not align to 4-bytes,
+ the transferLength is not more than USB_DEVICE_CONFIG_KHCI_DMA_ALIGN_BUFFER_LENGTH, and
+ the flag isDmaAlignBufferInusing is zero, the dmaAlignBuffer is used to receive data
+ and the flag isDmaAlignBufferInusing is set to 1.
+ When the transfer is done, the received data, kept in dmaAlignBuffer, is copied
+ to the transferBuffer, and the flag isDmaAlignBufferInusing is cleared.
+ */
+ usb_device_khci_endpoint_state_struct_t
+ endpointState[USB_DEVICE_CONFIG_ENDPOINTS * 2]; /*!< Endpoint state structures */
+ uint8_t isDmaAlignBufferInusing; /*!< The dmaAlignBuffer is used or not */
+ uint8_t isResetting; /*!< Is doing device reset or not */
+ uint8_t controllerId; /*!< Controller ID */
+ uint8_t setupBufferIndex; /*!< A valid setup buffer flag */
+} usb_device_khci_state_struct_t;
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+/*!
+ * @name USB device KHCI functions
+ * @{
+ */
+
+/*******************************************************************************
+ * API
+ ******************************************************************************/
+
+/*!
+ * @brief Initializes the USB device KHCI instance.
+ *
+ * This function initializes the USB device KHCI module specified by the controllerId.
+ *
+ * @param[in] controllerId The controller ID of the USB IP. See the enumeration type usb_controller_index_t.
+ * @param[in] handle Pointer of the device handle used to identify the device object belongs to.
+ * @param[out] khciHandle An out parameter used to return the pointer of the device KHCI handle to the caller.
+ *
+ * @return A USB error code or kStatus_USB_Success.
+ */
+usb_status_t USB_DeviceKhciInit(uint8_t controllerId,
+ usb_device_handle handle,
+ usb_device_controller_handle *khciHandle);
+
+/*!
+ * @brief Deinitializes the USB device KHCI instance.
+ *
+ * This function deinitializes the USB device KHCI module.
+ *
+ * @param[in] khciHandle Pointer of the device KHCI handle.
+ *
+ * @return A USB error code or kStatus_USB_Success.
+ */
+usb_status_t USB_DeviceKhciDeinit(usb_device_controller_handle khciHandle);
+
+/*!
+ * @brief Sends data through a specified endpoint.
+ *
+ * This function sends data through a specified endpoint.
+ *
+ * @param[in] khciHandle Pointer of the device KHCI handle.
+ * @param[in] endpointAddress Endpoint index.
+ * @param[in] buffer The memory address to hold the data need to be sent.
+ * @param[in] length The data length need to be sent.
+ *
+ * @return A USB error code or kStatus_USB_Success.
+ *
+ * @note The return value indicates whether the sending request is successful or not. The transfer completion is notified by the
+ * corresponding callback function.
+ * Currently, only one transfer request can be supported for a specific endpoint.
+ * If there is a specific requirement to support multiple transfer requests for a specific endpoint, the application
+ * should implement a queue in the application level.
+ * The subsequent transfer can begin only when the previous transfer is done (a notification is obtained through the endpoint
+ * callback).
+ */
+usb_status_t USB_DeviceKhciSend(usb_device_controller_handle khciHandle,
+ uint8_t endpointAddress,
+ uint8_t *buffer,
+ uint32_t length);
+
+/*!
+ * @brief Receives data through a specified endpoint.
+ *
+ * This function receives data through a specified endpoint.
+ *
+ * @param[in] khciHandle Pointer of the device KHCI handle.
+ * @param[in] endpointAddress Endpoint index.
+ * @param[in] buffer The memory address to save the received data.
+ * @param[in] length The data length to be received.
+ *
+ * @return A USB error code or kStatus_USB_Success.
+ *
+ * @note The return value indicates whether the receiving request is successful or not. The transfer completion is notified by the
+ * corresponding callback function.
+ * Currently, only one transfer request can be supported for a specific endpoint.
+ * If there is a specific requirement to support multiple transfer requests for a specific endpoint, the application
+ * should implement a queue in the application level.
+ * The subsequent transfer can begin only when the previous transfer is done (a notification is obtained through the endpoint
+ * callback).
+ */
+usb_status_t USB_DeviceKhciRecv(usb_device_controller_handle khciHandle,
+ uint8_t endpointAddress,
+ uint8_t *buffer,
+ uint32_t length);
+
+/*!
+ * @brief Cancels the pending transfer in a specified endpoint.
+ *
+ * The function is used to cancel the pending transfer in a specified endpoint.
+ *
+ * @param[in] khciHandle Pointer of the device KHCI handle.
+ * @param[in] ep Endpoint address, bit7 is the direction of endpoint, 1U - IN, abd 0U - OUT.
+ *
+ * @return A USB error code or kStatus_USB_Success.
+ */
+usb_status_t USB_DeviceKhciCancel(usb_device_controller_handle khciHandle, uint8_t ep);
+
+/*!
+ * @brief Controls the status of the selected item.
+ *
+ * The function is used to control the status of the selected item.
+ *
+ * @param[in] khciHandle Pointer of the device KHCI handle.
+ * @param[in] type The selected item. See enumeration type usb_device_control_type_t.
+ * @param[in,out] param The parameter type is determined by the selected item.
+ *
+ * @return A USB error code or kStatus_USB_Success.
+ */
+usb_status_t USB_DeviceKhciControl(usb_device_controller_handle khciHandle,
+ usb_device_control_type_t type,
+ void *param);
+
+/*! @} */
+
+#if defined(__cplusplus)
+}
+#endif
+
+/*! @} */
+
+#endif /* __USB_DEVICE_KHCI_H__ */
diff --git a/usb_1.1.0/host/class/usb_host_audio.c b/usb_1.1.0/host/class/usb_host_audio.c
new file mode 100644
index 0000000..798d7ef
--- /dev/null
+++ b/usb_1.1.0/host/class/usb_host_audio.c
@@ -0,0 +1,1051 @@
+/*
+ * Copyright (c) 2015 - 2016, Freescale Semiconductor, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * o Redistributions of source code must retain the above copyright notice, this list
+ * of conditions and the following disclaimer.
+ *
+ * o Redistributions in binary form must reproduce the above copyright notice, this
+ * list of conditions and the following disclaimer in the documentation and/or
+ * other materials provided with the distribution.
+ *
+ * o Neither the name of Freescale Semiconductor, Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "usb_host_config.h"
+#if ((defined USB_HOST_CONFIG_AUDIO) && (USB_HOST_CONFIG_AUDIO))
+#include "usb_host.h"
+#include "usb_host_audio.h"
+
+/*******************************************************************************
+ * Variables
+ ******************************************************************************/
+
+/* usb audio feature uint command request declaration */
+static usb_audio_request_t s_usbAudioFuRequests[NUMBER_OF_FEATURE_COMMANDS] = {
+ /* Mute command request */
+ {AUDIO_FU_MUTE_MASK, ITF_REQUEST, CUR_REQUEST, AUDIO_FU_MUTE, 1U},
+ /* Volume command request */
+ {AUDIO_FU_VOLUME_MASK, ITF_REQUEST, CUR_REQUEST, AUDIO_FU_VOLUME, 2U},
+ {AUDIO_FU_VOLUME_MASK, ITF_REQUEST, MIN_REQUEST, AUDIO_FU_VOLUME, 2U},
+ {AUDIO_FU_VOLUME_MASK, ITF_REQUEST, MAX_REQUEST, AUDIO_FU_VOLUME, 2U},
+ {AUDIO_FU_VOLUME_MASK, ITF_REQUEST, RES_REQUEST, AUDIO_FU_VOLUME, 2U},
+};
+/* USB audio endpoint command declaration */
+static usb_audio_request_t s_usbAudioEpRequests[NUMBER_OF_ENDPOINT_COMMANDS] = {
+ /* USB audio Pitch command request */
+ {AUDIO_PITCH_MASK, EP_REQUEST, CUR_REQUEST, AUDIO_PITCH_CONTROL, 1U},
+
+ /* USB audio Sampling frequency command request */
+ {AUDIO_SAMPLING_FREQ_MASK, EP_REQUEST, CUR_REQUEST, AUDIO_SAMPLING_FREQ_CONTROL, 3U},
+ {AUDIO_SAMPLING_FREQ_MASK, EP_REQUEST, MIN_REQUEST, AUDIO_SAMPLING_FREQ_CONTROL, 3U},
+ {AUDIO_SAMPLING_FREQ_MASK, EP_REQUEST, MAX_REQUEST, AUDIO_SAMPLING_FREQ_CONTROL, 3U},
+ {AUDIO_SAMPLING_FREQ_MASK, EP_REQUEST, RES_REQUEST, AUDIO_SAMPLING_FREQ_CONTROL, 3U},
+};
+
+/*******************************************************************************
+ * Code
+ ******************************************************************************/
+/*!
+ * @brief initialize the audio instance.
+ *
+ * This function allocate the resource for audio instance.
+ *
+ * @param deviceHandle The device handle.
+ * @param classHandlePtr return class handle.
+ *
+ * @retval kStatus_USB_Success The device is initialized successfully.
+ * @retval kStatus_USB_AllocFail Allocate memory fail.
+ */
+usb_status_t USB_HostAudioInit(usb_device_handle deviceHandle, usb_host_class_handle *classHandlePtr)
+{
+ audio_instance_t *audioPtr = (audio_instance_t *)USB_OsaMemoryAllocate(sizeof(audio_instance_t));
+ uint32_t info_value;
+
+ if (audioPtr == NULL)
+ {
+ return kStatus_USB_AllocFail;
+ }
+
+ audioPtr->deviceHandle = deviceHandle;
+ audioPtr->controlIntfHandle = NULL;
+ audioPtr->streamIntfHandle = NULL;
+ USB_HostHelperGetPeripheralInformation(deviceHandle, kUSB_HostGetHostHandle, &info_value);
+ audioPtr->hostHandle = (usb_host_handle)info_value;
+ USB_HostHelperGetPeripheralInformation(deviceHandle, kUSB_HostGetDeviceControlPipe, &info_value);
+ audioPtr->controlPipe = (usb_host_pipe_handle)info_value;
+
+ *classHandlePtr = audioPtr;
+ return kStatus_USB_Success;
+}
+
+/*!
+ * @brief de-initialize the audio instance.
+ *
+ * This function release the resource for audio instance.
+ *
+ * @param deviceHandle the device handle.
+ * @param classHandle the class handle.
+ *
+ * @retval kStatus_USB_Success The device is de-initialized successfully.
+ */
+usb_status_t USB_HostAudioDeinit(usb_device_handle deviceHandle, usb_host_class_handle classHandle)
+{
+ usb_status_t status;
+ audio_instance_t *audioPtr = (audio_instance_t *)classHandle;
+
+ if (deviceHandle == NULL)
+ {
+ return kStatus_USB_InvalidHandle;
+ }
+
+ if (classHandle != NULL)
+ {
+ if (audioPtr->isoInPipe != NULL)
+ {
+ status = USB_HostCancelTransfer(audioPtr->hostHandle, audioPtr->isoInPipe, NULL);
+ status = USB_HostClosePipe(audioPtr->hostHandle, audioPtr->isoInPipe);
+
+ if (status != kStatus_USB_Success)
+ {
+#ifdef HOST_ECHO
+ usb_echo("error when close pipe\r\n");
+#endif
+ }
+ audioPtr->isoInPipe = NULL;
+ }
+ if (audioPtr->isoOutPipe != NULL)
+ {
+ status = USB_HostCancelTransfer(audioPtr->hostHandle, audioPtr->isoOutPipe, NULL);
+ status = USB_HostClosePipe(audioPtr->hostHandle, audioPtr->isoOutPipe);
+
+ if (status != kStatus_USB_Success)
+ {
+#ifdef HOST_ECHO
+ usb_echo("error when close pipe\r\n");
+#endif
+ }
+ audioPtr->isoOutPipe = NULL;
+ }
+ USB_HostCloseDeviceInterface(deviceHandle, audioPtr->streamIntfHandle);
+
+ if ((audioPtr->controlPipe != NULL) && (audioPtr->controlTransfer != NULL))
+ {
+ status = USB_HostCancelTransfer(audioPtr->hostHandle, audioPtr->controlPipe, audioPtr->controlTransfer);
+ }
+ USB_HostCloseDeviceInterface(deviceHandle, audioPtr->controlIntfHandle);
+ USB_OsaMemoryFree(audioPtr);
+ }
+ else
+ {
+ USB_HostCloseDeviceInterface(deviceHandle, NULL);
+ }
+
+ return kStatus_USB_Success;
+}
+
+/*!
+ * @brief audiostream iso in pipe transfer callback.
+ *
+ * @param param callback parameter.
+ * @param transfer callback transfer.
+ * @param status transfer status.
+ */
+static void _USB_HostAudioStreamIsoInPipeCallback(void *param, usb_host_transfer_t *transfer, usb_status_t status)
+{
+ audio_instance_t *audioPtr = (audio_instance_t *)param;
+
+ if (audioPtr->inCallbackFn != NULL)
+ {
+ audioPtr->inCallbackFn(audioPtr->inCallbackParam, transfer->transferBuffer, transfer->transferSofar, status);
+ }
+ USB_HostFreeTransfer(audioPtr->hostHandle, transfer);
+}
+
+/*!
+ * @brief audiostream iso out pipe transfer callback.
+ *
+ * @param param callback parameter.
+ * @param transfer callback transfer.
+ * @param status transfer status.
+ */
+static void _USB_HostAudioStreamIsoOutPipeCallback(void *param, usb_host_transfer_t *transfer, usb_status_t status)
+{
+ audio_instance_t *audioPtr = (audio_instance_t *)param;
+
+ if (audioPtr->outCallbackFn != NULL)
+ {
+ audioPtr->outCallbackFn(audioPtr->outCallbackParam, transfer->transferBuffer, transfer->transferSofar, status);
+ }
+ USB_HostFreeTransfer(audioPtr->hostHandle, transfer);
+}
+
+/*!
+ * @brief audiocontrol pipe transfer callback.
+ *
+ * @param param callback parameter.
+ * @param transfer callback transfer.
+ * @param status transfer status.
+ */
+static void _USB_HostAudioControlCallback(void *param, usb_host_transfer_t *transfer, usb_status_t status)
+{
+ audio_instance_t *audioPtr = (audio_instance_t *)param;
+
+ audioPtr->controlTransfer = NULL;
+ if (audioPtr->controlCallbackFn != NULL)
+ {
+ audioPtr->controlCallbackFn(audioPtr->controlCallbackParam, transfer->transferBuffer, transfer->transferSofar,
+ status);
+ }
+ USB_HostFreeTransfer(audioPtr->hostHandle, transfer);
+ audioPtr->isSetup = 0U;
+}
+
+/*!
+ * @brief hid send control transfer common code.
+ *
+ * @param classHandle the class handle.
+ * @param typeRequest setup packet request type.
+ * @param request setup packet request value.
+ * @param wvalue setup packet wvalue value.
+ * @param windex setup packet index value.
+ * @param wlength setup packet wlength value.
+ * @param data data buffer pointer will be transfer.
+ * @param callbackFn this callback is called after this function completes.
+ * @param callbackParam the first parameter in the callback function.
+ *
+ * @return An error code or kStatus_USB_Success.
+ */
+static usb_status_t _USB_HostAudioControl(usb_host_class_handle classHandle,
+ uint8_t typeRequest,
+ uint8_t request,
+ uint16_t wvalue,
+ uint16_t windex,
+ uint16_t wlength,
+ uint8_t *data,
+ transfer_callback_t callbackFn,
+ void *callbackParam)
+{
+ audio_instance_t *audioPtr = (audio_instance_t *)classHandle;
+ usb_host_transfer_t *transfer;
+
+ if (classHandle == NULL)
+ {
+ return kStatus_USB_InvalidHandle;
+ }
+
+ if (USB_HostMallocTransfer(audioPtr->hostHandle, &transfer) != kStatus_USB_Success)
+ {
+#ifdef HOST_ECHO
+ usb_echo("error to get transfer\r\n");
+#endif
+ return kStatus_USB_Error;
+ }
+ audioPtr->controlCallbackFn = callbackFn;
+ audioPtr->controlCallbackParam = callbackParam;
+
+ transfer->transferBuffer = data;
+ transfer->transferLength = wlength;
+ transfer->callbackFn = _USB_HostAudioControlCallback;
+ transfer->callbackParam = audioPtr;
+ transfer->setupPacket.bmRequestType = typeRequest;
+ transfer->setupPacket.bRequest = request;
+ transfer->setupPacket.wValue = USB_SHORT_TO_LITTLE_ENDIAN(wvalue);
+ transfer->setupPacket.wIndex = USB_SHORT_TO_LITTLE_ENDIAN(windex);
+
+ transfer->setupPacket.wLength = USB_SHORT_TO_LITTLE_ENDIAN(wlength);
+ audioPtr->isSetup = 1;
+
+ if (USB_HostSendSetup(audioPtr->hostHandle, audioPtr->controlPipe, transfer) != kStatus_USB_Success)
+ {
+#ifdef HOST_ECHO
+ usb_echo("failt for USB_HostSendSetup\r\n");
+#endif
+ USB_HostFreeTransfer(audioPtr->hostHandle, transfer);
+ return kStatus_USB_Error;
+ }
+ audioPtr->controlTransfer = transfer;
+
+ return kStatus_USB_Success;
+}
+
+/*!
+ * @brief audio open interface.
+ *
+ * @param audioPtr audio instance pointer.
+ *
+ * @return kStatus_USB_Success or error codes.
+ */
+static usb_status_t _USB_HostAudioOpenInterface(audio_instance_t *audioPtr)
+{
+ usb_status_t status;
+ uint8_t ep_index = 0U;
+ usb_host_pipe_init_t pipe_init;
+ usb_descriptor_endpoint_t *ep_desc = NULL;
+ usb_host_interface_t *interface_ptr;
+
+ if (audioPtr->isoInPipe != NULL)
+ {
+ status = USB_HostClosePipe(audioPtr->hostHandle, audioPtr->isoInPipe);
+
+ if (status != kStatus_USB_Success)
+ {
+#ifdef HOST_ECHO
+ usb_echo("error when close pipe\r\n");
+#endif
+ }
+ audioPtr->isoInPipe = NULL;
+ }
+ if (audioPtr->isoOutPipe != NULL)
+ {
+ status = USB_HostClosePipe(audioPtr->hostHandle, audioPtr->isoOutPipe);
+
+ if (status != kStatus_USB_Success)
+ {
+#ifdef HOST_ECHO
+ usb_echo("error when close pipe\r\n");
+#endif
+ }
+ audioPtr->isoOutPipe = NULL;
+ }
+
+ /* open interface pipes */
+ interface_ptr = (usb_host_interface_t *)audioPtr->streamIntfHandle;
+ for (ep_index = 0U; ep_index < interface_ptr->epCount; ++ep_index)
+ {
+ ep_desc = interface_ptr->epList[ep_index].epDesc;
+ if (((ep_desc->bEndpointAddress & USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_MASK) ==
+ USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_IN) &&
+ ((ep_desc->bmAttributes & USB_DESCRIPTOR_ENDPOINT_ATTRIBUTE_TYPE_MASK) == USB_ENDPOINT_ISOCHRONOUS))
+ {
+ pipe_init.devInstance = audioPtr->deviceHandle;
+ pipe_init.pipeType = USB_ENDPOINT_ISOCHRONOUS;
+ pipe_init.direction = USB_IN;
+ pipe_init.endpointAddress = (ep_desc->bEndpointAddress & USB_DESCRIPTOR_ENDPOINT_ADDRESS_NUMBER_MASK);
+ pipe_init.interval = ep_desc->bInterval;
+ pipe_init.maxPacketSize = (uint16_t)(USB_SHORT_FROM_LITTLE_ENDIAN_ADDRESS(ep_desc->wMaxPacketSize) &
+ USB_DESCRIPTOR_ENDPOINT_MAXPACKETSIZE_SIZE_MASK);
+ pipe_init.numberPerUframe = (USB_SHORT_FROM_LITTLE_ENDIAN_ADDRESS(ep_desc->wMaxPacketSize) &
+ USB_DESCRIPTOR_ENDPOINT_MAXPACKETSIZE_MULT_TRANSACTIONS_MASK);
+ pipe_init.nakCount = USB_HOST_CONFIG_MAX_NAK;
+
+ audioPtr->inPacketSize = pipe_init.maxPacketSize;
+ audioPtr->isoEpNum = pipe_init.endpointAddress;
+ status = USB_HostOpenPipe(audioPtr->hostHandle, &audioPtr->isoInPipe, &pipe_init);
+ if (status != kStatus_USB_Success)
+ {
+#ifdef HOST_ECHO
+ usb_echo("usb_host_audio_stream_set_interface fail to open pipe\r\n");
+#endif
+ return kStatus_USB_Error;
+ }
+ }
+ else if (((ep_desc->bEndpointAddress & USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_MASK) ==
+ USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_OUT) &&
+ ((ep_desc->bmAttributes & USB_DESCRIPTOR_ENDPOINT_ATTRIBUTE_TYPE_MASK) == USB_ENDPOINT_ISOCHRONOUS))
+ {
+ pipe_init.devInstance = audioPtr->deviceHandle;
+ pipe_init.pipeType = USB_ENDPOINT_ISOCHRONOUS;
+ pipe_init.direction = USB_OUT;
+ pipe_init.endpointAddress = (ep_desc->bEndpointAddress & USB_DESCRIPTOR_ENDPOINT_ADDRESS_NUMBER_MASK);
+ pipe_init.interval = ep_desc->bInterval;
+ pipe_init.maxPacketSize = (uint16_t)(USB_SHORT_FROM_LITTLE_ENDIAN_ADDRESS(ep_desc->wMaxPacketSize) &
+ USB_DESCRIPTOR_ENDPOINT_MAXPACKETSIZE_SIZE_MASK);
+ pipe_init.numberPerUframe = (USB_SHORT_FROM_LITTLE_ENDIAN_ADDRESS(ep_desc->wMaxPacketSize) &
+ USB_DESCRIPTOR_ENDPOINT_MAXPACKETSIZE_MULT_TRANSACTIONS_MASK);
+ pipe_init.nakCount = USB_HOST_CONFIG_MAX_NAK;
+
+ audioPtr->outPacketSize = pipe_init.maxPacketSize;
+ audioPtr->isoEpNum = pipe_init.endpointAddress;
+ status = USB_HostOpenPipe(audioPtr->hostHandle, &audioPtr->isoOutPipe, &pipe_init);
+ if (status != kStatus_USB_Success)
+ {
+#ifdef HOST_ECHO
+ usb_echo("usb_host_audio_stream_set_interface fail to open pipe\r\n");
+#endif
+ return kStatus_USB_Error;
+ }
+ }
+ else
+ {
+ return kStatus_USB_Error;
+ }
+ }
+
+ return kStatus_USB_Success;
+}
+
+/*!
+ * @brief audio set interface callback, open pipes.
+ *
+ * @param param callback parameter.
+ * @param transfer callback transfer.
+ * @param status transfer status.
+ */
+static void _USB_HostAudioSetInterfaceCallback(void *param, usb_host_transfer_t *transfer, usb_status_t status)
+{
+ audio_instance_t *audioPtr = (audio_instance_t *)param;
+
+ audioPtr->controlTransfer = NULL;
+ if (status == kStatus_USB_Success)
+ {
+ status = _USB_HostAudioOpenInterface(audioPtr);
+ }
+
+ if (audioPtr->controlCallbackFn != NULL)
+ {
+ audioPtr->controlCallbackFn(audioPtr->controlCallbackParam, NULL, 0U, status);
+ }
+ USB_HostFreeTransfer(audioPtr->hostHandle, transfer);
+}
+
+/*!
+ * @brief set audioclass stream interface.
+ *
+ * This function bind the interface with the audio instance.
+ *
+ * @param classHandle The class handle.
+ * @param interfaceHandle The interface handle.
+ * @param alternateSetting The alternate setting value.
+ * @param callbackFn This callback is called after this function completes.
+ * @param callbackParam The first parameter in the callback function.
+ *
+ * @retval kStatus_USB_Success The device is initialized successfully.
+ * @retval kStatus_USB_InvalidHandle The classHandle is NULL pointer.
+ * @retval kStatus_USB_Busy There is no idle transfer.
+ * @retval kStatus_USB_Error send transfer fail, please reference to USB_HostSendSetup.
+ * @retval kStatus_USB_Busy callback return status, there is no idle pipe.
+ * @retval kStatus_USB_TransferStall callback return status, the transfer is stall by device.
+ * @retval kStatus_USB_Error callback return status, open pipe fail, please reference to USB_HostOpenPipe.
+ */
+usb_status_t USB_HostAudioStreamSetInterface(usb_host_class_handle classHandle,
+ usb_host_interface_handle interfaceHandle,
+ uint8_t alternateSetting,
+ transfer_callback_t callbackFn,
+ void *callbackParam)
+{
+ usb_status_t status;
+ audio_instance_t *audioPtr = (audio_instance_t *)classHandle;
+ usb_host_interface_t *interface_ptr;
+ usb_host_transfer_t *transfer;
+ audio_descriptor_union_t ptr1;
+ uint32_t length = 0U, ep = 0U;
+
+ if (classHandle == NULL)
+ {
+ return kStatus_USB_InvalidParameter;
+ }
+
+ audioPtr->streamIntfHandle = interfaceHandle;
+
+ status = USB_HostOpenDeviceInterface(audioPtr->deviceHandle, interfaceHandle);
+ if (status != kStatus_USB_Success)
+ {
+ return status;
+ }
+
+ if (audioPtr->isoInPipe != NULL)
+ {
+ status = USB_HostCancelTransfer(audioPtr->hostHandle, audioPtr->isoInPipe, NULL);
+
+ if (status != kStatus_USB_Success)
+ {
+#ifdef HOST_ECHO
+ usb_echo("error when cancel pipe\r\n");
+#endif
+ }
+ }
+
+ if (audioPtr->isoOutPipe != NULL)
+ {
+ status = USB_HostCancelTransfer(audioPtr->hostHandle, audioPtr->isoOutPipe, NULL);
+
+ if (status != kStatus_USB_Success)
+ {
+#ifdef HOST_ECHO
+ usb_echo("error when cancel pipe\r\n");
+#endif
+ }
+ }
+ /* open interface pipes */
+ interface_ptr = (usb_host_interface_t *)interfaceHandle;
+ ptr1.bufr = interface_ptr->interfaceExtension;
+
+ length = 0U;
+ while (length < interface_ptr->interfaceExtensionLength)
+ {
+ if ((ptr1.common->bDescriptorType == 0x04U) && (ptr1.interface->bAlternateSetting == alternateSetting))
+ {
+ interface_ptr->epCount = ptr1.interface->bNumEndpoints;
+ break;
+ }
+ ptr1.bufr += ptr1.common->bLength;
+ length += ptr1.common->bLength;
+ }
+ while (ep < interface_ptr->epCount)
+ {
+ if (ptr1.common->bDescriptorType == 0x24U)
+ {
+ if (ptr1.common->bData[0] == USB_DESC_SUBTYPE_AS_CS_GENERAL)
+ {
+ audioPtr->asIntfDesc = (usb_audio_stream_spepific_as_intf_desc_t *)ptr1.bufr;
+ }
+ else if (ptr1.common->bData[0] == USB_DESC_SUBTYPE_AS_CS_FORMAT_TYPE)
+ {
+ audioPtr->formatTypeDesc = (usb_audio_stream_format_type_desc_t *)ptr1.bufr;
+ }
+ else
+ {
+ }
+ }
+ if (ptr1.common->bDescriptorType == 0x05U)
+ {
+ interface_ptr->epList[ep].epDesc = (usb_descriptor_endpoint_t *)ptr1.bufr;
+ audioPtr->isoEndpDesc = (usb_audio_stream_specific_iso_endp_desc_t *)ptr1.bufr;
+ ep++;
+ ptr1.bufr += ptr1.common->bLength;
+ interface_ptr->epList[ep].epExtension = ptr1.bufr;
+ interface_ptr->epList[ep].epExtensionLength = ptr1.common->bLength;
+ break;
+ }
+ ptr1.bufr += ptr1.common->bLength;
+ }
+
+ if (alternateSetting == 0U)
+ {
+ if (callbackFn != NULL)
+ {
+ status = _USB_HostAudioOpenInterface(audioPtr);
+ callbackFn(callbackParam, NULL, 0U, kStatus_USB_Success);
+ }
+ }
+ else
+ {
+ if (USB_HostMallocTransfer(audioPtr->hostHandle, &transfer) != kStatus_USB_Success)
+ {
+#ifdef HOST_ECHO
+ usb_echo("error to get transfer\r\n");
+#endif
+ return kStatus_USB_Error;
+ }
+ audioPtr->controlCallbackFn = callbackFn;
+ audioPtr->controlCallbackParam = callbackParam;
+ /* initialize transfer */
+ transfer->callbackFn = _USB_HostAudioSetInterfaceCallback;
+ transfer->callbackParam = audioPtr;
+ transfer->setupPacket.bRequest = USB_REQUEST_STANDARD_SET_INTERFACE;
+ transfer->setupPacket.bmRequestType = USB_REQUEST_TYPE_RECIPIENT_INTERFACE;
+ transfer->setupPacket.wIndex = USB_SHORT_TO_LITTLE_ENDIAN(
+ ((usb_host_interface_t *)audioPtr->streamIntfHandle)->interfaceDesc->bInterfaceNumber);
+ transfer->setupPacket.wValue = USB_SHORT_TO_LITTLE_ENDIAN(alternateSetting);
+ transfer->setupPacket.wLength = 0;
+ transfer->transferBuffer = NULL;
+ transfer->transferLength = 0;
+ status = USB_HostSendSetup(audioPtr->hostHandle, audioPtr->controlPipe, transfer);
+
+ if (status == kStatus_USB_Success)
+ {
+ audioPtr->controlTransfer = transfer;
+ }
+ else
+ {
+ USB_HostFreeTransfer(audioPtr->hostHandle, transfer);
+ }
+ }
+
+ return status;
+}
+
+/*!
+ * @brief set audioclass control interface.
+ *
+ * This function bind the interface with the audio instance.
+ *
+ * @param classHandle The class handle.
+ * @param interfaceHandle The interface handle.
+ * @param alternateSetting The alternate setting value.
+ * @param callbackFn This callback is called after this function completes.
+ * @param callbackParam The first parameter in the callback function.
+ *
+ * @retval kStatus_USB_Success The device is initialized successfully.
+ * @retval kStatus_USB_InvalidHandle The classHandle is NULL pointer.
+ * @retval kStatus_USB_Busy There is no idle transfer.
+ * @retval kStatus_USB_Error send transfer fail, please reference to USB_HostSendSetup.
+ * @retval kStatus_USB_Busy callback return status, there is no idle pipe.
+ * @retval kStatus_USB_TransferStall callback return status, the transfer is stall by device.
+ * @retval kStatus_USB_Error callback return status, open pipe fail, please reference to USB_HostOpenPipe.
+ */
+usb_status_t USB_HostAudioControlSetInterface(usb_host_class_handle classHandle,
+ usb_host_interface_handle interfaceHandle,
+ uint8_t alternateSetting,
+ transfer_callback_t callbackFn,
+ void *callbackParam)
+{
+ usb_status_t status;
+ audio_instance_t *audioPtr = (audio_instance_t *)classHandle;
+ usb_host_interface_t *interface_ptr;
+ usb_host_transfer_t *transfer;
+ audio_descriptor_union_t ptr1;
+ uint32_t length = 0U;
+
+ if (classHandle == NULL)
+ {
+ return kStatus_USB_InvalidParameter;
+ }
+ audioPtr->controlIntfHandle = interfaceHandle;
+ interface_ptr = (usb_host_interface_t *)interfaceHandle;
+
+ status = USB_HostOpenDeviceInterface(audioPtr->deviceHandle, interfaceHandle);
+ if (status != kStatus_USB_Success)
+ {
+ return status;
+ }
+ ptr1.bufr = interface_ptr->interfaceExtension;
+
+ length = 0U;
+
+ while (length < interface_ptr->interfaceExtensionLength)
+ {
+ if (((interface_ptr->interfaceDesc->bDescriptorType == 0x04U) &&
+ (interface_ptr->interfaceDesc->bAlternateSetting == alternateSetting)) ||
+ ((ptr1.common->bDescriptorType == 0x04U) && (ptr1.interface->bAlternateSetting == alternateSetting)))
+ {
+ break;
+ }
+
+ ptr1.bufr += ptr1.common->bLength;
+ length += ptr1.common->bLength;
+ }
+ while (length < interface_ptr->interfaceExtensionLength)
+ {
+ if (ptr1.common->bDescriptorType == 0x24U)
+ {
+ if (ptr1.common->bData[0] == USB_DESC_SUBTYPE_AUDIO_CS_HEADER)
+ {
+ audioPtr->headerDesc = (usb_audio_ctrl_header_desc_t *)ptr1.bufr;
+ }
+ else if (ptr1.common->bData[0] == USB_DESC_SUBTYPE_AUDIO_CS_IT)
+ {
+ audioPtr->itDesc = (usb_audio_ctrl_it_desc_t *)ptr1.bufr;
+ }
+ else if (ptr1.common->bData[0] == USB_DESC_SUBTYPE_AUDIO_CS_OT)
+ {
+ audioPtr->otDesc = (usb_audio_ctrl_ot_desc_t *)ptr1.bufr;
+ }
+ else if (ptr1.common->bData[0] == USB_DESC_SUBTYPE_AUDIO_CS_FU)
+ {
+ audioPtr->fuDesc = (usb_audio_ctrl_fu_desc_t *)ptr1.bufr;
+ }
+ else
+ {
+ }
+ }
+ ptr1.bufr += ptr1.common->bLength;
+ length += ptr1.common->bLength;
+ }
+
+ if (alternateSetting == 0U)
+ {
+ if (callbackFn != NULL)
+ {
+ callbackFn(callbackParam, NULL, 0U, kStatus_USB_Success);
+ }
+ }
+ else
+ {
+ if (USB_HostMallocTransfer(audioPtr->hostHandle, &transfer) != kStatus_USB_Success)
+ {
+#ifdef HOST_ECHO
+ usb_echo("error to get transfer\r\n");
+#endif
+ return kStatus_USB_Error;
+ }
+ audioPtr->controlCallbackFn = callbackFn;
+ audioPtr->controlCallbackParam = callbackParam;
+ /* initialize transfer */
+ transfer->callbackFn = _USB_HostAudioControlCallback;
+ transfer->callbackParam = audioPtr;
+ transfer->setupPacket.bRequest = USB_REQUEST_STANDARD_SET_INTERFACE;
+ transfer->setupPacket.bmRequestType = USB_REQUEST_TYPE_RECIPIENT_INTERFACE;
+ transfer->setupPacket.wIndex = USB_SHORT_TO_LITTLE_ENDIAN(
+ ((usb_host_interface_t *)audioPtr->controlIntfHandle)->interfaceDesc->bInterfaceNumber);
+ transfer->setupPacket.wValue = USB_SHORT_TO_LITTLE_ENDIAN(alternateSetting);
+ transfer->setupPacket.wLength = 0;
+ transfer->transferBuffer = NULL;
+ transfer->transferLength = 0;
+ status = USB_HostSendSetup(audioPtr->hostHandle, audioPtr->controlPipe, transfer);
+
+ if (status == kStatus_USB_Success)
+ {
+ audioPtr->controlTransfer = transfer;
+ }
+ else
+ {
+ USB_HostFreeTransfer(audioPtr->hostHandle, transfer);
+ }
+ }
+
+ return status;
+}
+
+/*!
+ * @brief get pipe max packet size.
+ *
+ * @param classHandle the class handle.
+ * @param pipeType It's value is USB_ENDPOINT_CONTROL, USB_ENDPOINT_ISOCHRONOUS, USB_ENDPOINT_BULK or
+ * USB_ENDPOINT_INTERRUPT.
+ * Please reference to usb_spec.h
+ * @param direction pipe direction.
+ *
+ * @retval 0 The classHandle is NULL.
+ * @retval max packet size.
+ */
+uint16_t USB_HostAudioPacketSize(usb_host_class_handle classHandle, uint8_t pipeType, uint8_t direction)
+{
+ audio_instance_t *audioPtr = (audio_instance_t *)classHandle;
+ if (classHandle == NULL)
+ {
+ return kStatus_USB_InvalidHandle;
+ }
+
+ if (pipeType == USB_ENDPOINT_ISOCHRONOUS)
+ {
+ if (direction == USB_IN)
+ {
+ return audioPtr->inPacketSize;
+ }
+ else
+ {
+ return audioPtr->outPacketSize;
+ }
+ }
+ return 0U;
+}
+
+/*!
+ * @brief audio stream receive data.
+ *
+ * This function implements audioreceiving data.
+ *
+ * @param classHandle The class handle.
+ * @param buffer The buffer pointer.
+ * @param bufferLen The buffer length.
+ * @param callbackFn This callback is called after this function completes.
+ * @param callbackParam The first parameter in the callback function.
+ *
+ * @retval kStatus_USB_Success Receive request successfully.
+ * @retval kStatus_USB_InvalidHandle The classHandle is NULL pointer.
+ * @retval kStatus_USB_Busy There is no idle transfer.
+ * @retval kStatus_USB_Error pipe is not initialized.
+ * Or, send transfer fail, please reference to USB_HostRecv.
+ */
+usb_status_t USB_HostAudioStreamRecv(usb_host_class_handle classHandle,
+ uint8_t *buffer,
+ uint32_t bufferLen,
+ transfer_callback_t callbackFn,
+ void *callbackParam)
+{
+ audio_instance_t *audioPtr = (audio_instance_t *)classHandle;
+ usb_host_transfer_t *transfer;
+
+ if (classHandle == NULL)
+ {
+ return kStatus_USB_InvalidHandle;
+ }
+
+ if (audioPtr->isoInPipe == NULL)
+ {
+ return kStatus_USB_Error;
+ }
+
+ if (USB_HostMallocTransfer(audioPtr->hostHandle, &transfer) != kStatus_USB_Success)
+ {
+#ifdef HOST_ECHO
+ usb_echo("error to get transfer\r\n");
+#endif
+ return kStatus_USB_Error;
+ }
+ audioPtr->inCallbackFn = callbackFn;
+ audioPtr->inCallbackParam = callbackParam;
+ transfer->transferBuffer = buffer;
+ transfer->transferLength = bufferLen;
+ transfer->callbackFn = _USB_HostAudioStreamIsoInPipeCallback;
+ transfer->callbackParam = audioPtr;
+
+ if (USB_HostRecv(audioPtr->hostHandle, audioPtr->isoInPipe, transfer) != kStatus_USB_Success)
+ {
+#ifdef HOST_ECHO
+ usb_echo("failt to USB_HostRecv\r\n");
+#endif
+ USB_HostFreeTransfer(audioPtr->hostHandle, transfer);
+ return kStatus_USB_Error;
+ }
+
+ return kStatus_USB_Success;
+}
+
+/*!
+ * @brief audio stream send data.
+ *
+ * This function implements audio sending data.
+ *
+ * @param classHandle The class handle.
+ * @param buffer The buffer pointer.
+ * @param bufferLen The buffer length.
+ * @param callbackFn This callback is called after this function completes.
+ * @param callbackParam The first parameter in the callback function.
+ *
+ * @retval kStatus_USB_Success Receive request successfully.
+ * @retval kStatus_USB_InvalidHandle The classHandle is NULL pointer.
+ * @retval kStatus_USB_Busy There is no idle transfer.
+ * @retval kStatus_USB_Error pipe is not initialized.
+ * Or, send transfer fail, please reference to USB_HostSend.
+ */
+usb_status_t USB_HostAudioStreamSend(usb_host_class_handle classHandle,
+ uint8_t *buffer,
+ uint32_t bufferLen,
+ transfer_callback_t callbackFn,
+ void *callbackParam)
+{
+ audio_instance_t *audioPtr = (audio_instance_t *)classHandle;
+ usb_host_transfer_t *transfer;
+
+ if (classHandle == NULL)
+ {
+ return kStatus_USB_InvalidHandle;
+ }
+
+ if (audioPtr->isoOutPipe == NULL)
+ {
+ return kStatus_USB_Error;
+ }
+
+ if (USB_HostMallocTransfer(audioPtr->hostHandle, &transfer) != kStatus_USB_Success)
+ {
+#ifdef HOST_ECHO
+ usb_echo("error to get transfer\r\n");
+#endif
+ return kStatus_USB_Error;
+ }
+ audioPtr->outCallbackFn = callbackFn;
+ audioPtr->outCallbackParam = callbackParam;
+ transfer->transferBuffer = buffer;
+ transfer->transferLength = bufferLen;
+ transfer->callbackFn = _USB_HostAudioStreamIsoOutPipeCallback;
+ transfer->callbackParam = audioPtr;
+
+ if (USB_HostSend(audioPtr->hostHandle, audioPtr->isoOutPipe, transfer) != kStatus_USB_Success)
+ {
+#ifdef HOST_ECHO
+ usb_echo("failt to USB_HostSend\r\n");
+#endif
+ USB_HostFreeTransfer(audioPtr->hostHandle, transfer);
+ return kStatus_USB_Error;
+ }
+
+ return kStatus_USB_Success;
+}
+
+/*!
+ * @brief get audio stream current altsetting descriptor.
+ *
+ * This function implements get audio stream current altsetting descriptor.
+ *
+ * @param classHandle The class handle.
+ * @param asIntfDesc The pointer of class specific AS interface descriptor.
+ * @param formatTypeDesc The pointer of format type descriptor.
+ * @param isoEndpDesc The pointer of specific iso endp descriptor.
+ *
+ * @retval kStatus_USB_Success Get audio stream current altsetting descriptor request successfully.
+ * @retval kStatus_USB_InvalidHandle The classHandle is NULL pointer.
+ *
+ */
+usb_status_t USB_HostAudioStreamGetCurrentAltsettingDescriptors(
+
+ usb_host_class_handle classHandle,
+ usb_audio_stream_spepific_as_intf_desc_t **asIntfDesc,
+ usb_audio_stream_format_type_desc_t **formatTypeDesc,
+ usb_audio_stream_specific_iso_endp_desc_t **isoEndpDesc)
+{
+ audio_instance_t *audioPtr = (audio_instance_t *)classHandle;
+
+ if (classHandle == NULL)
+ {
+ return kStatus_USB_InvalidHandle;
+ }
+ *asIntfDesc = audioPtr->asIntfDesc;
+ *formatTypeDesc = audioPtr->formatTypeDesc;
+ *isoEndpDesc = audioPtr->isoEndpDesc;
+
+ return kStatus_USB_Success;
+}
+
+/*!
+ * @brief usb audio feature unit request.
+ *
+ * This function implements usb audio feature unit request.
+ *
+ * @param classHandle The class handle.
+ * @param channelNo The channel number of audio feature unit.
+ * @param buf The feature unit request buffer pointer.
+ * @param cmdCode The feature unit command code, for example USB_AUDIO_GET_CUR_MUTE etc.
+ * @param callbackFn This callback is called after this function completes.
+ * @param callbackParam The first parameter in the callback function.
+ *
+ * @retval kStatus_USB_Success Feature unit request successfully.
+ * @retval kStatus_USB_InvalidHandle The classHandle is NULL pointer.
+ * @retval kStatus_USB_Busy There is no idle transfer.
+ * @retval kStatus_USB_Error Send transfer fail, please reference to USB_HostSendSetup.
+ *
+ */
+usb_status_t USB_HostAudioFeatureUnitRequest(usb_host_class_handle classHandle,
+ uint8_t channelNo,
+ void *buf,
+ uint32_t cmdCode,
+ transfer_callback_t callbackFn,
+ void *callbackParam)
+{ /* Body */
+ uint16_t windex;
+ uint16_t request_value;
+ audio_instance_t *if_ptr;
+ usb_audio_request_t *p_feature_request;
+ uint8_t *bmacontrols = NULL;
+ uint8_t atribute_index;
+ usb_status_t status = kStatus_USB_Error;
+
+ if (classHandle == NULL)
+ {
+ return kStatus_USB_InvalidHandle;
+ }
+
+ if_ptr = (audio_instance_t *)classHandle;
+
+ /* pointer to command */
+ p_feature_request = &(s_usbAudioFuRequests[cmdCode & 0xfU]);
+ /* get request value */
+ request_value = (uint16_t)((uint16_t)((uint16_t)p_feature_request->requestValue << 8U) | channelNo);
+
+ /* Check whether this attribute valid or not */
+ if (if_ptr->fuDesc == NULL)
+ {
+ return kStatus_USB_Error;
+ }
+ windex = (uint16_t)((uint16_t)((uint16_t)(if_ptr->fuDesc->bunitid) << 8U) | (if_ptr->streamIfnum));
+ atribute_index = if_ptr->fuDesc->bcontrolsize * channelNo;
+
+ if (atribute_index < (if_ptr->fuDesc->blength - 7))
+ {
+ bmacontrols = &(if_ptr->fuDesc->bcontrolsize);
+ }
+
+ if (bmacontrols == NULL)
+ {
+ return kStatus_USB_Error;
+ }
+
+ bmacontrols++;
+ if (bmacontrols[atribute_index] & p_feature_request->controlMask)
+ {
+ status = kStatus_USB_Success;
+ }
+
+ if (kStatus_USB_Success == status)
+ {
+ status = _USB_HostAudioControl(classHandle, (p_feature_request->typeRequest | (cmdCode & 0x80U)),
+ (p_feature_request->codeRequest | (cmdCode & 0x80U)), request_value, windex,
+ p_feature_request->length, (uint8_t *)buf, callbackFn, callbackParam);
+ }
+ return status;
+}
+
+/*!
+ * @brief usb audio endpoint request.
+ *
+ * This function implements usb audio endpoint request.
+ *
+ * @param classHandle The class handle.
+ * @param buf The feature unit buffer pointer.
+ * @param cmdCode The feature unit command code, for example USB_AUDIO_GET_CUR_PITCH etc .
+ * @param callbackFn This callback is called after this function completes.
+ * @param callbackParam The first parameter in the callback function.
+ *
+ * @retval kStatus_USB_Success Endpoint request successfully.
+ * @retval kStatus_USB_InvalidHandle The classHandle is NULL pointer.
+ * @retval kStatus_USB_Busy There is no idle transfer.
+ * @retval kStatus_USB_Error Send transfer fail, please reference to USB_HostSendSetup.
+ *
+ */
+usb_status_t USB_HostAudioEndpointRequest(
+ usb_host_class_handle classHandle, void *buf, uint32_t cmdCode, transfer_callback_t callbackFn, void *callbackParam)
+{
+ uint8_t endp_num;
+ usb_status_t status = kStatus_USB_Error;
+ uint16_t request_value;
+ usb_audio_request_t *p_endpoint_request;
+ audio_instance_t *audioPtr;
+
+ if (classHandle == NULL)
+ {
+ return kStatus_USB_InvalidHandle;
+ }
+ audioPtr = (audio_instance_t *)classHandle;
+
+ /* pointer to command */
+ p_endpoint_request = &(s_usbAudioEpRequests[cmdCode & 0xfU]);
+ /* get request value */
+ request_value = (uint16_t)((uint16_t)((uint16_t)p_endpoint_request->requestValue << 8U));
+
+ /* Check whether this attribute valid or not */
+ if (audioPtr->isoEndpDesc == NULL)
+ {
+ return kStatus_USB_Error;
+ }
+ if ((audioPtr->isoEndpDesc->bmattributes) && (p_endpoint_request->controlMask))
+ {
+ status = kStatus_USB_Success;
+ }
+ else
+ {
+ status = kStatus_USB_InvalidRequest;
+ }
+
+ if (kStatus_USB_Success == status)
+ {
+ /* Any isochronous pipe is supported? */
+ if ((NULL == audioPtr->isoInPipe) && (NULL == audioPtr->isoOutPipe))
+ {
+ return kStatus_USB_InvalidParameter;
+ }
+ else if (NULL != audioPtr->isoInPipe)
+ {
+ endp_num = (audioPtr->isoEpNum | 0x80U);
+ }
+ else
+ {
+ endp_num = audioPtr->isoEpNum;
+ } /* Endif */
+
+ status = _USB_HostAudioControl(classHandle, (p_endpoint_request->typeRequest | (cmdCode & 0x80U)),
+ (p_endpoint_request->codeRequest | (cmdCode & 0x80U)), request_value, endp_num,
+ p_endpoint_request->length, (uint8_t *)buf, callbackFn, callbackParam);
+ }
+
+ return status;
+}
+#endif /* USB_HOST_CONFIG_AUDIO */
diff --git a/usb_1.1.0/host/class/usb_host_audio.h b/usb_1.1.0/host/class/usb_host_audio.h
new file mode 100644
index 0000000..e6728fd
--- /dev/null
+++ b/usb_1.1.0/host/class/usb_host_audio.h
@@ -0,0 +1,549 @@
+/*
+ * Copyright (c) 2015, Freescale Semiconductor, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * o Redistributions of source code must retain the above copyright notice, this list
+ * of conditions and the following disclaimer.
+ *
+ * o Redistributions in binary form must reproduce the above copyright notice, this
+ * list of conditions and the following disclaimer in the documentation and/or
+ * other materials provided with the distribution.
+ *
+ * o Neither the name of Freescale Semiconductor, Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __USB_HOST_AUDIO_H__
+#define __USB_HOST_AUDIO_H__
+
+/*******************************************************************************
+ * Audio class private structure, enumerations, macros
+ ******************************************************************************/
+/*******************************************************************************
+ * Definitions
+ ******************************************************************************/
+/* Structure for an AUDIO class descriptor according to the 6.2.1 in Audio specification*/
+#define AUDIO_FU_MUTE 0x01
+#define AUDIO_FU_VOLUME 0x02
+#define AUDIO_FU_BASS 0x03
+#define AUDIO_FU_MID 0x04
+#define AUDIO_FU_TREBLE 0x05
+#define AUDIO_FU_GRAPHIC_EQ 0x06
+#define AUDIO_FU_AGC 0x07
+#define AUDIO_FU_DELAY 0x08
+#define AUDIO_FU_BASS_BOOST 0x09
+
+/* Audio class codes */
+#define SET_COMMAND (0x00)
+#define GET_COMMAND (0x80)
+#define CUR_REQUEST (0x01)
+#define MIN_REQUEST (0x02)
+#define MAX_REQUEST (0x03)
+#define RES_REQUEST (0x04)
+#define MEM_REQUEST (0x05)
+#define GET_STATUS (0xFF)
+
+#define ITF_REQUEST (0x21)
+#define EP_REQUEST (0x22)
+
+#define AUDIO_FU_MUTE_MASK 0x01
+#define AUDIO_FU_VOLUME_MASK 0x02
+#define AUDIO_FU_BASS_MASK 0x04
+#define AUDIO_FU_MID_MASK 0x08
+#define AUDIO_FU_TREBLE_MASK 0x10
+#define AUDIO_FU_GRAPHIC_EQ_MASK 0x20
+#define AUDIO_FU_AGC_MASK 0x40
+#define AUDIO_FU_DELAY_MASK 0x80
+#define AUDIO_FU_BASS_BOOST_MASK 0x01
+
+/* USB audio Endpoint Control Selectors */
+#define AUDIO_EP_CONTROL_UNDEFINED (0x00)
+#define AUDIO_SAMPLING_FREQ_CONTROL (0x01)
+#define AUDIO_PITCH_CONTROL (0x02)
+
+#define AUDIO_SAMPLING_FREQ_MASK (0x01)
+#define AUDIO_PITCH_MASK (0x02)
+typedef enum _fu_request_code
+{
+ kUSB_AudioCurMute = 0,
+ kUSB_AudioCurVolume,
+ kUSB_AudioMinVolume,
+ kUSB_AudioMaxVolume,
+ kUSB_AudioResVolume,
+ NUMBER_OF_FEATURE_COMMANDS,
+} fu_request_code_t;
+
+typedef enum _ep_request_code
+{
+ kUSB_AudioCurPitch = 0,
+ kUSB_AudioCurSamplingFreq,
+ kUSB_AudioMinSamplingFreq,
+ kUSB_AudioMaxSamplingFreq,
+ kUSB_AudioResSamplingFreq,
+ NUMBER_OF_ENDPOINT_COMMANDS,
+} ep_request_code_t;
+
+typedef union _audio_descriptor_union
+{
+ uint8_t *bufr;
+ usb_descriptor_common_t *common;
+ usb_descriptor_device_t *device;
+ usb_descriptor_configuration_t *configuration;
+ usb_descriptor_interface_t *interface;
+ usb_descriptor_endpoint_t *endpoint;
+} audio_descriptor_union_t;
+
+/* Audio command structure */
+typedef struct _usb_audio_request
+{
+ uint8_t controlMask;
+ uint8_t typeRequest;
+ uint8_t codeRequest;
+ uint8_t requestValue;
+ uint8_t length;
+} usb_audio_request_t;
+
+#define USB_DESC_SUBTYPE_AUDIO_CS_HEADER 0x01
+#define USB_DESC_SUBTYPE_AUDIO_CS_IT 0x02
+#define USB_DESC_SUBTYPE_AUDIO_CS_OT 0x03
+#define USB_DESC_SUBTYPE_AUDIO_CS_FU 0x06
+#define USB_DESC_CLASS_ENDPOINT_GENERAL 0x01
+#define USB_DESC_SUBTYPE_AS_CS_GENERAL 0X01
+#define USB_DESC_SUBTYPE_AS_CS_FORMAT_TYPE 0X02
+
+/*******************************************************************************
+ * Audio class public structure, enumeration, macros, functions
+ ******************************************************************************/
+/*!
+ * @addtogroup usb_host_audio_drv
+ * @{
+ */
+/*! @brief Audio class code */
+#define USB_AUDIO_CLASS_CODE 1
+/*! @brief Audio class control interface code*/
+#define USB_AUDIO_SUBCLASS_CODE_CONTROL 1
+/*! @brief Audio class stream interface code*/
+#define USB_AUDIO_SUBCLASS_CODE_AUDIOSTREAMING 2
+
+/*! @brief AUDIO class-specific feature unit get current mute command*/
+#define USB_AUDIO_GET_CUR_MUTE 0x80
+/*! @brief AUDIO class-specific feature unit set current mute command*/
+#define USB_AUDIO_SET_CUR_MUTE 0x00
+/*! @brief AUDIO class-specific feature unit get current volume command*/
+#define USB_AUDIO_GET_CUR_VOLUME 0x81
+/*! @brief AUDIO class-specific feature unit set current volume command*/
+#define USB_AUDIO_SET_CUR_VOLUME 0x01
+/*! @brief AUDIO class-specific feature unit get minimum volume command*/
+#define USB_AUDIO_GET_MIN_VOLUME 0x82
+/*! @brief AUDIO class-specific feature unit set minimum volume command*/
+#define USB_AUDIO_SET_MIN_VOLUME 0x02
+/*! @brief AUDIO class-specific feature unit get maximum volume command*/
+#define USB_AUDIO_GET_MAX_VOLUME 0x83
+/*! @brief AUDIO class-specific feature unit set maximum volume command*/
+#define USB_AUDIO_SET_MAX_VOLUME 0x03
+/*! @brief AUDIO class-specific feature unit get resolution volume command*/
+#define USB_AUDIO_GET_RES_VOLUME 0x84
+/*! @brief AUDIO class-specific feature unit set resolution volume command*/
+#define USB_AUDIO_SET_RES_VOLUME 0x04
+
+/*! @brief AUDIO class-specific endpoint get current pitch control command*/
+#define USB_AUDIO_GET_CUR_PITCH 0x80
+/*! @brief AUDIO class-specific endpoint set current pitch control command*/
+#define USB_AUDIO_SET_CUR_PITCH 0x00
+/*! @brief AUDIO class-specific endpoint get current sampling frequency command*/
+#define USB_AUDIO_GET_CUR_SAMPLING_FREQ 0x81
+/*! @brief AUDIO class-specific endpoint set current sampling frequency command*/
+#define USB_AUDIO_SET_CUR_SAMPLING_FREQ 0x01
+/*! @brief AUDIO class-specific endpoint get minimum sampling frequency command*/
+#define USB_AUDIO_GET_MIN_SAMPLING_FREQ 0x82
+/*! @brief AUDIO class-specific endpoint set minimum sampling frequency command*/
+#define USB_AUDIO_SET_MIN_SAMPLING_FREQ 0x02
+/*! @brief AUDIO class-specific endpoint get maximum sampling frequency command*/
+#define USB_AUDIO_GET_MAX_SAMPLING_FREQ 0x83
+/*! @brief AUDIO class-specific endpoint set maximum sampling frequency command*/
+#define USB_AUDIO_SET_MAX_SAMPLING_FREQ 0x03
+/*! @brief AUDIO class-specific endpoint get resolution sampling frequency command*/
+#define USB_AUDIO_GET_RES_SAMPLING_FREQ 0x84
+/*! @brief AUDIO class-specific endpoint set resolution sampling frequency command*/
+#define USB_AUDIO_SET_RES_SAMPLING_FREQ 0x04
+
+/*! @brief Audio control interface header descriptor structure */
+typedef struct _usb_audio_ctrl_header_desc
+{
+ uint8_t blength; /*!< Total size of the header descriptor*/
+ uint8_t bdescriptortype; /*!< Descriptor type of audio header descriptor*/
+ uint8_t bdescriptorsubtype; /*!< Subtype of an audio header descriptor*/
+ uint8_t bcdcdc[2]; /*!< Audio Device Class Specification Release Number in Binary-Coded Decimal*/
+ uint8_t wtotallength[2]; /*!< Total number of bytes returned for the class-specific AudioControl interface
+ descriptor. Includes the combined length of this descriptor header and all unit and
+ terminal descriptors.*/
+ uint8_t bincollection; /*!< The number of AudioStreaming and MIDIStreaming interfaces in the Audio Interface
+ Collection to which this AudioControl interface belongs to*/
+} usb_audio_ctrl_header_desc_t;
+
+/*! @brief Audio control interface input terminal descriptor structure */
+typedef struct _usb_audio_ctrl_it_desc
+{
+ uint8_t blength; /*!< Total size of the input terminal descriptor*/
+ uint8_t bdescriptortype; /*!< Descriptor type of audio input terminal descriptor*/
+ uint8_t bdescriptorsubtype; /*!< Subtype of audio input terminal descriptor*/
+ uint8_t bterminalid; /*!< Constant uniquely identifying the Terminal within the audio function. This value is used
+ in all requests to address this Terminal*/
+ uint8_t wterminaltype[2]; /*!< Constant characterizing the type of Terminal*/
+ uint8_t bassocterminal; /*!< ID of the Output Terminal to which this Input Terminal is associated*/
+ uint8_t bnrchannels; /*!< Number of logical output channels in the Terminal's output audio channel cluster*/
+ uint8_t wchannelconfig[2]; /*!< Describes the spatial location of the logical channels.*/
+ uint8_t ichannelnames; /*!< Index of a string descriptor, describing the name of the first logical channel*/
+ uint8_t iterminal; /*!<Index of a string descriptor, describing the Input Terminal*/
+} usb_audio_ctrl_it_desc_t;
+
+/*! @brief Audio control interface output terminal descriptor structure */
+typedef struct _usb_audio_ctrl_ot_desc
+{
+ uint8_t blength; /*!< Total size of the output terminal descriptor*/
+ uint8_t bdescriptortype; /*!< Descriptor type of audio output terminal descriptor*/
+ uint8_t bdescriptorsubtype; /*!< Subtype of audio output terminal descriptor*/
+ uint8_t bterminalid; /*!< Constant uniquely identifying the Terminal within the audio function. This value is used
+ in all requests to address this Terminal*/
+ uint8_t wterminaltype[2]; /*!< Constant characterizing the type of Terminal*/
+ uint8_t bassocterminal; /*!< Constant, identifying the Input Terminal to which this Output Terminal is associated*/
+ uint8_t bsourceid; /*!< ID of the Unit or Terminal to which this Terminal is connected*/
+ uint8_t iterminal; /*!< Index of a string descriptor, describing the Output Terminal*/
+} usb_audio_ctrl_ot_desc_t;
+
+/*! @brief Audio control interface feature unit descriptor structure */
+typedef struct _usb_audio_ctrl_fu_desc
+{
+ uint8_t blength; /*!< Total size of the output terminal descriptor*/
+ uint8_t bdescriptortype; /*!< Descriptor type of audio output terminal descriptor*/
+ uint8_t bdescriptorsubtype; /*!< Subtype of audio output terminal descriptor*/
+ uint8_t bunitid; /*!< Constant uniquely identifying the unit within the audio function. This value is used in all
+ requests to address this unit*/
+ uint8_t bsourceid; /*!< ID of the Unit or Terminal to which this Feature Unit is connected*/
+ uint8_t bcontrolsize; /*!< Size in bytes of an element of the bmaControls*/
+} usb_audio_ctrl_fu_desc_t;
+
+/*! @brief Audio as isochronous audio data endpoint descriptor structure */
+typedef struct _usb_audio_stream_specific_iso_endp_desc
+{
+ uint8_t blength; /*!< Total size of the descriptor*/
+ uint8_t bdescriptortype; /*!< Descriptor type of the descriptor*/
+ uint8_t bdescriptorsubtype; /*!< Subtype of the descriptor*/
+ uint8_t bmattributes; /*!< A bit in the range D6..0 set to 1 indicates that the mentioned Control is supported by
+ this endpoint*/
+ uint8_t blockdlayunits; /*!< Indicates the units used for the wLockDelay field*/
+ uint8_t wlockdelay[2]; /*!< Indicates the time it takes this endpoint to reliably lock its internal clock recovery
+ circuitry. Units used depend on the value of the bLockDelayUnits field.*/
+} usb_audio_stream_specific_iso_endp_desc_t;
+
+/*! @brief Audio standard as isochronous synch endpoint descriptor structure */
+typedef struct _usb_audio_stream_synch_endp_desc
+{
+ uint8_t blength; /*!< Total size of the descriptor*/
+ uint8_t bdescriptortype; /*!< Descriptor type of the endpoint descriptor*/
+ uint8_t bendpointaddress; /*!< The address of the endpoint on the USB device described by this descriptor*/
+ uint8_t bmattributes; /*!< D3..2: Synchronization type, D1..0: Transfer type*/
+ uint8_t wmaxpacketsize[2]; /*!< Maximum packet size this endpoint is capable of sending or receiving when this
+ configuration is selected*/
+ uint8_t binterval; /*!< Interval for polling endpoint for data transfers expressed in milliseconds*/
+ uint8_t brefresh; /*!< This field indicates the rate at which an isochronous synchronization pipe provides new
+ synchronization feedback data*/
+ uint8_t bsynchaddress; /*!< Must be reset to zero*/
+} usb_audio_stream_synch_endp_desc_t;
+
+/*! @brief Audio class-specific as interface descriptor structure */
+typedef struct _usb_audio_stream_spepific_as_intf_desc
+{
+ uint8_t blength; /*!< Total size of the descriptor*/
+ uint8_t bdescriptortype; /*!< Descriptor type of the descriptor*/
+ uint8_t bdescriptorsubtype; /*!< Subtype of the descriptor*/
+ uint8_t bterminallink; /*!< The Terminal ID of the Terminal to which the endpoint of this interface is connected*/
+ uint8_t bdelay; /*!< Expressed in number of frames*/
+ uint8_t wformattag[2]; /*!< The Audio Data Format that has to be used to communicate with this interface*/
+} usb_audio_stream_spepific_as_intf_desc_t;
+
+/* Format type descriptor */
+/*! @brief audio Format type descriptor structure */
+typedef struct _usb_audio_stream_format_type_desc
+{
+ uint8_t blength; /*!< Total size of the descriptor*/
+ uint8_t bdescriptortype; /*!< Descriptor type of the descriptor*/
+ uint8_t bdescriptorsubtype; /*!< Subtype of the descriptor*/
+ uint8_t bformattype; /*!< Constant identifying the Format Type the AudioStreaming interface is using*/
+ uint8_t bnrchannels; /*!< Number of channels of device*/
+ uint8_t bsubframesize; /*!< Bytes per audio subframe*/
+ uint8_t bbitresolution; /*!< Bits per sample*/
+ uint8_t bsamfreqtype; /*!< Frequency supported*/
+ uint8_t tsamfreq[1][3]; /*!< Sample frequency*/
+} usb_audio_stream_format_type_desc_t;
+
+/*! @brief Audio instance structure and audio usb_host_class_handle pointer to this structure */
+typedef struct _audio_instance
+{
+ usb_host_handle hostHandle; /*!< This instance's related host handle*/
+ usb_device_handle deviceHandle; /*!< This instance's related device handle*/
+ usb_host_interface_handle streamIntfHandle; /*!< This instance's audio stream interface handle*/
+ usb_host_interface_handle controlIntfHandle; /*!< This instance's control stream interface handle*/
+ usb_audio_stream_spepific_as_intf_desc_t
+ *asIntfDesc; /*!< Audio class class-specific as interface descriptor pointer*/
+ usb_audio_stream_format_type_desc_t
+ *formatTypeDesc; /*!< Audio class class-specific format type descriptor pointer*/
+ usb_audio_stream_specific_iso_endp_desc_t
+ *isoEndpDesc; /*!< Audio class class-specific ISO audio data endpoint descriptor pointer*/
+ usb_host_pipe_handle isoInPipe; /*!< Audio class ISO in pipe*/
+ usb_host_pipe_handle isoOutPipe; /*!< Audio class ISO out pipe*/
+ transfer_callback_t inCallbackFn; /*!< Audio class ISO in transfer callback function*/
+ void *inCallbackParam; /*!< Audio class ISO in transfer callback parameter*/
+ transfer_callback_t outCallbackFn; /*!< Audio class ISO out transfer callback function*/
+ void *outCallbackParam; /*!< Audio class ISO out transfer callback function*/
+ usb_audio_ctrl_header_desc_t *headerDesc; /*!< Audio class header descriptor pointer*/
+ usb_audio_ctrl_it_desc_t *itDesc; /*!< Audio class input terminal descriptor pointer*/
+ usb_audio_ctrl_ot_desc_t *otDesc; /*!< Audio class output terminal descriptor pointer*/
+ usb_audio_ctrl_fu_desc_t *fuDesc; /*!< Audio class feature unit descriptor pointer*/
+ usb_host_pipe_handle controlPipe; /*!< Audio class device control pipe*/
+ transfer_callback_t controlCallbackFn; /*!< Audio control transfer callback function*/
+ void *controlCallbackParam; /*!< Audio control transfer callback function*/
+ usb_host_transfer_t *controlTransfer; /*!< On-going control transfer*/
+ uint16_t inPacketSize; /*!< Audio ISO in maximum packet size*/
+ uint16_t outPacketSize; /*!< Audio ISO out maximum packet size*/
+ uint8_t isSetup; /*!< Whether the audio setup transfer is transmitting*/
+ uint8_t isoEpNum; /*!< Audio stream ISO endpoint number*/
+ uint8_t streamIfnum; /*!< Audio stream ISO interface number*/
+} audio_instance_t;
+
+/*******************************************************************************
+ * API
+ ******************************************************************************/
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*!
+ * @name USB host audio class APIs
+ * @{
+ */
+
+/*!
+ * @brief Initializes the audio instance.
+ *
+ * This function allocates the resource for the audio instance.
+ *
+ * @param deviceHandle The device handle.
+ * @param classHandlePtr Return class handle.
+ *
+ * @retval kStatus_USB_Success The device is initialized successfully.
+ * @retval kStatus_USB_AllocFail Allocate memory fail.
+ */
+extern usb_status_t USB_HostAudioInit(usb_device_handle deviceHandle, usb_host_class_handle *classHandlePtr);
+
+/*!
+ * @brief Deinitializes the Audio instance.
+ *
+ * This function release the resource for audio instance.
+ *
+ * @param deviceHandle The device handle.
+ * @param classHandle The class handle.
+ *
+ * @retval kStatus_USB_Success The device is deinitialized successfully.
+ */
+extern usb_status_t USB_HostAudioDeinit(usb_device_handle deviceHandle, usb_host_class_handle classHandle);
+
+/*!
+ * @brief Sets the audio class stream interface.
+ *
+ * This function binds the interface with the audio instance.
+ *
+ * @param classHandle The class handle.
+ * @param interfaceHandle The interface handle.
+ * @param alternateSetting The alternate setting value.
+ * @param callbackFn This callback is called after this function completes.
+ * @param callbackParam The first parameter in the callback function.
+ *
+ * @retval kStatus_USB_Success The device is initialized successfully.
+ * @retval kStatus_USB_InvalidHandle The classHandle is NULL pointer.
+ * @retval kStatus_USB_Busy There is no idle transfer.
+ * @retval kStatus_USB_Error Send transfer fail. See the USB_HostSendSetup.
+ * @retval kStatus_USB_Busy Callback return status, there is no idle pipe.
+ * @retval kStatus_USB_TransferStall Callback return status, the transfer is stalled by the device.
+ * @retval kStatus_USB_Error Callback return status, open pipe fail. See the USB_HostOpenPipe.
+ */
+extern usb_status_t USB_HostAudioStreamSetInterface(usb_host_class_handle classHandle,
+ usb_host_interface_handle interfaceHandle,
+ uint8_t alternateSetting,
+ transfer_callback_t callbackFn,
+ void *callbackParam);
+
+/*!
+ * @brief Sets the audio class control interface.
+ *
+ * This function binds the interface with the audio instance.
+ *
+ * @param classHandle The class handle.
+ * @param interfaceHandle The interface handle.
+ * @param alternateSetting The alternate setting value.
+ * @param callbackFn This callback is called after this function completes.
+ * @param callbackParam The first parameter in the callback function.
+ *
+ * @retval kStatus_USB_Success The device is initialized successfully.
+ * @retval kStatus_USB_InvalidHandle The classHandle is NULL pointer.
+ * @retval kStatus_USB_Busy There is no idle transfer.
+ * @retval kStatus_USB_Error Send transfer fail. See the USB_HostSendSetup.
+ * @retval kStatus_USB_Busy Callback return status, there is no idle pipe.
+ * @retval kStatus_USB_TransferStall Callback return status, the transfer is stalled by the device.
+ * @retval kStatus_USB_Error Callback return status, open pipe fail. See USB_HostOpenPipe.
+ */
+extern usb_status_t USB_HostAudioControlSetInterface(usb_host_class_handle classHandle,
+ usb_host_interface_handle interfaceHandle,
+ uint8_t alternateSetting,
+ transfer_callback_t callbackFn,
+ void *callbackParam);
+
+/*!
+ * @brief Gets the pipe maximum packet size.
+ *
+ * @param classHandle The class handle.
+ * @param pipeType Its value is USB_ENDPOINT_CONTROL, USB_ENDPOINT_ISOCHRONOUS, USB_ENDPOINT_BULK or
+ * USB_ENDPOINT_INTERRUPT.
+ * See the usb_spec.h
+ * @param direction Pipe direction.
+ *
+ * @retval 0 The classHandle is NULL.
+ * @retval max Packet size.
+ */
+extern uint16_t USB_HostAudioPacketSize(usb_host_class_handle classHandle, uint8_t pipeType, uint8_t direction);
+
+/*!
+ * @brief Audio stream receive data.
+ *
+ * This function implements the audio receiving data.
+ *
+ * @param classHandle The class handle.
+ * @param buffer The buffer pointer.
+ * @param bufferLen The buffer length.
+ * @param callbackFn This callback is called after this function completes.
+ * @param callbackParam The first parameter in the callback function.
+ *
+ * @retval kStatus_USB_Success Receive request successfully.
+ * @retval kStatus_USB_InvalidHandle The classHandle is NULL pointer.
+ * @retval kStatus_USB_Busy There is no idle transfer.
+ * @retval kStatus_USB_Error Pipe is not initialized.
+ * Or, send transfer fail. See the USB_HostRecv.
+ */
+extern usb_status_t USB_HostAudioStreamRecv(usb_host_class_handle classHandle,
+ uint8_t *buffer,
+ uint32_t bufferLen,
+ transfer_callback_t callbackFn,
+ void *callbackParam);
+
+/*!
+ * @brief Audio stream send data.
+ *
+ * This function implements the audio sending data.
+ *
+ * @param classHandle The class handle.
+ * @param buffer The buffer pointer.
+ * @param bufferLen The buffer length.
+ * @param callbackFn This callback is called after this function completes.
+ * @param callbackParam The first parameter in the callback function.
+ *
+ * @retval kStatus_USB_Success Receive request successfully.
+ * @retval kStatus_USB_InvalidHandle The classHandle is NULL pointer.
+ * @retval kStatus_USB_Busy There is no idle transfer.
+ * @retval kStatus_USB_Error pipe is not initialized.
+ * Or, send transfer fail. See the USB_HostSend.
+ */
+extern usb_status_t USB_HostAudioStreamSend(usb_host_class_handle classHandle,
+ uint8_t *buffer,
+ uint32_t bufferLen,
+ transfer_callback_t callbackFn,
+ void *callbackParam);
+
+/*!
+ * @brief Gets the audio stream current altsetting descriptor.
+ *
+ * This function implements the get audio stream current altsetting descriptor.
+ *
+ * @param classHandle The class handle.
+ * @param asIntfDesc The pointer of class-specific AS interface descriptor.
+ * @param formatTypeDesc The pointer of format type descriptor.
+ * @param isoEndpDesc The pointer of specific ISO endp descriptor.
+ *
+ * @retval kStatus_USB_Success Get the audio stream current altsetting descriptor request successfully.
+ * @retval kStatus_USB_InvalidHandle The classHandle is NULL pointer.
+ *
+ */
+extern usb_status_t USB_HostAudioStreamGetCurrentAltsettingDescriptors(
+ usb_host_class_handle classHandle,
+ usb_audio_stream_spepific_as_intf_desc_t **asIntfDesc,
+ usb_audio_stream_format_type_desc_t **formatTypeDesc,
+ usb_audio_stream_specific_iso_endp_desc_t **isoEndpDesc);
+
+/*!
+ * @brief The USB audio feature unit request.
+ *
+ * This function implements the USB audio feature unit request.
+ *
+ * @param classHandle The class handle.
+ * @param channelNo The channel number of audio feature unit.
+ * @param buf The feature unit request buffer pointer.
+ * @param cmdCode The feature unit command code, for example USB_AUDIO_GET_CUR_MUTE, and so on.
+ * @param callbackFn This callback is called after this function completes.
+ * @param callbackParam The first parameter in the callback function.
+ *
+ * @retval kStatus_USB_Success Feature unit request successfully.
+ * @retval kStatus_USB_InvalidHandle The classHandle is NULL pointer.
+ * @retval kStatus_USB_Busy There is no idle transfer.
+ * @retval kStatus_USB_Error Send transfer fail. See the USB_HostSendSetup.
+ *
+ */
+extern usb_status_t USB_HostAudioFeatureUnitRequest(usb_host_class_handle classHandle,
+ uint8_t channelNo,
+ void *buf,
+ uint32_t cmdCode,
+ transfer_callback_t callbackFn,
+ void *callbackParam);
+
+/*!
+ * @brief The USB audio endpoint request.
+ *
+ * This function implements the USB audio endpoint request.
+ *
+ * @param classHandle The class handle.
+ * @param buf The feature unit buffer pointer.
+ * @param cmdCode The feature unit command code, for example USB_AUDIO_GET_CUR_PITCH, and so on.
+ * @param callbackFn This callback is called after this function completes.
+ * @param callbackParam The first parameter in the callback function.
+ *
+ * @retval kStatus_USB_Success Endpoint request successfully.
+ * @retval kStatus_USB_InvalidHandle The classHandle is NULL pointer.
+ * @retval kStatus_USB_Busy There is no idle transfer.
+ * @retval kStatus_USB_Error Send transfer fail. See the USB_HostSendSetup.
+ *
+ */
+extern usb_status_t USB_HostAudioEndpointRequest(usb_host_class_handle classHandle,
+ void *buf,
+ uint32_t cmdCode,
+ transfer_callback_t callbackFn,
+ void *callbackParam);
+
+/*! @}*/
+#ifdef __cplusplus
+}
+#endif
+/*! @}*/
+#endif /* __USB_HOST_AUDIO_H__ */
diff --git a/usb_1.1.0/host/class/usb_host_cdc.c b/usb_1.1.0/host/class/usb_host_cdc.c
new file mode 100644
index 0000000..378e07f
--- /dev/null
+++ b/usb_1.1.0/host/class/usb_host_cdc.c
@@ -0,0 +1,1200 @@
+/*
+ * Copyright (c) 2015 - 2016, Freescale Semiconductor, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * o Redistributions of source code must retain the above copyright notice, this list
+ * of conditions and the following disclaimer.
+ *
+ * o Redistributions in binary form must reproduce the above copyright notice, this
+ * list of conditions and the following disclaimer in the documentation and/or
+ * other materials provided with the distribution.
+ *
+ * o Neither the name of Freescale Semiconductor, Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "usb_host_config.h"
+#if ((defined USB_HOST_CONFIG_CDC) && (USB_HOST_CONFIG_CDC))
+#include "usb_host.h"
+#include "usb_host_cdc.h"
+#include "usb_host_devices.h"
+
+#if ((defined USB_HOST_CONFIG_CLASS_AUTO_CLEAR_STALL) && USB_HOST_CONFIG_CLASS_AUTO_CLEAR_STALL)
+
+static void USB_HostCdcClearInHaltCallback(void *param, usb_host_transfer_t *transfer, usb_status_t status)
+{
+ usb_host_cdc_instance_struct_t *cdcInstance = (usb_host_cdc_instance_struct_t *)param;
+
+ cdcInstance->controlTransfer = NULL;
+ if (cdcInstance->inCallbackFn != NULL)
+ {
+ /* callback to application */
+ cdcInstance->inCallbackFn(cdcInstance->inCallbackParam, cdcInstance->stallDataBuffer,
+ cdcInstance->stallDataLength, kStatus_USB_TransferStall);
+ }
+ USB_HostFreeTransfer(cdcInstance->hostHandle, transfer);
+}
+
+static void USB_HostCdcClearOutHaltCallback(void *param, usb_host_transfer_t *transfer, usb_status_t status)
+{
+ usb_host_cdc_instance_struct_t *cdcInstance = (usb_host_cdc_instance_struct_t *)param;
+
+ cdcInstance->controlTransfer = NULL;
+ if (cdcInstance->outCallbackFn != NULL)
+ {
+ /* callback to application */
+ cdcInstance->outCallbackFn(cdcInstance->outCallbackParam, cdcInstance->stallDataBuffer,
+ cdcInstance->stallDataLength, kStatus_USB_TransferStall);
+ }
+ USB_HostFreeTransfer(cdcInstance->hostHandle, transfer);
+}
+static void USB_HostCdcClearInterruptHaltCallback(void *param, usb_host_transfer_t *transfer, usb_status_t status)
+{
+ usb_host_cdc_instance_struct_t *cdcInstance = (usb_host_cdc_instance_struct_t *)param;
+
+ cdcInstance->controlTransfer = NULL;
+ if (cdcInstance->interruptCallbackFn != NULL)
+ {
+ /* callback to application */
+ cdcInstance->interruptCallbackFn(cdcInstance->interruptCallbackParam, cdcInstance->stallDataBuffer,
+ cdcInstance->stallDataLength, kStatus_USB_TransferStall);
+ }
+ USB_HostFreeTransfer(cdcInstance->hostHandle, transfer);
+}
+
+static usb_status_t USB_HostCdcClearHalt(usb_host_cdc_instance_struct_t *cdcInstance,
+ usb_host_transfer_t *stallTransfer,
+ host_inner_transfer_callback_t callbackFn,
+ uint8_t endpoint)
+{
+ usb_status_t status;
+ usb_host_transfer_t *transfer;
+
+ /* malloc one transfer */
+ status = USB_HostMallocTransfer(cdcInstance->hostHandle, &transfer);
+ if (status != kStatus_USB_Success)
+ {
+#ifdef HOST_ECHO
+ usb_echo("allocate transfer error\r\n");
+#endif
+ return status;
+ }
+ cdcInstance->stallDataBuffer = stallTransfer->transferBuffer;
+ cdcInstance->stallDataLength = stallTransfer->transferSofar;
+ /* save the application callback function */
+ cdcInstance->controlCallbackFn = NULL;
+ cdcInstance->controlCallbackParam = NULL;
+ /* initialize transfer */
+ transfer->callbackFn = callbackFn;
+ transfer->callbackParam = cdcInstance;
+ transfer->transferBuffer = NULL;
+ transfer->transferLength = 0;
+ transfer->setupPacket.bRequest = USB_REQUEST_STANDARD_CLEAR_FEATURE;
+ transfer->setupPacket.bmRequestType = USB_REQUEST_TYPE_RECIPIENT_ENDPOINT;
+ transfer->setupPacket.wValue = USB_SHORT_TO_LITTLE_ENDIAN(USB_REQUEST_STANDARD_FEATURE_SELECTOR_ENDPOINT_HALT);
+ transfer->setupPacket.wIndex = USB_SHORT_TO_LITTLE_ENDIAN(endpoint);
+ transfer->setupPacket.wLength = 0;
+ status = USB_HostSendSetup(cdcInstance->hostHandle, cdcInstance->controlPipe, transfer);
+
+ if (status != kStatus_USB_Success)
+ {
+ USB_HostFreeTransfer(cdcInstance->hostHandle, transfer);
+ }
+ cdcInstance->controlTransfer = transfer;
+
+ return status;
+}
+#endif
+
+/*!
+ * @brief cdc data in pipe transfer callback.
+ *
+ * @param param callback parameter.
+ * @param transfer callback transfer.
+ * @param status transfer status.
+ */
+void USB_HostCdcDataInPipeCallback(void *param, usb_host_transfer_t *transfer, usb_status_t status)
+{
+ usb_host_cdc_instance_struct_t *cdcInstance = (usb_host_cdc_instance_struct_t *)param;
+#if ((defined USB_HOST_CONFIG_CLASS_AUTO_CLEAR_STALL) && USB_HOST_CONFIG_CLASS_AUTO_CLEAR_STALL)
+ if (status == kStatus_USB_TransferStall)
+ {
+ if (USB_HostCdcClearHalt(cdcInstance, transfer, USB_HostCdcClearInHaltCallback,
+ (USB_REQUEST_TYPE_DIR_IN |
+ ((usb_host_pipe_t *)cdcInstance->inPipe)->endpointAddress)) == kStatus_USB_Success)
+ {
+ USB_HostFreeTransfer(cdcInstance->hostHandle, transfer);
+ return;
+ }
+ }
+#endif
+
+ if (cdcInstance->inCallbackFn != NULL)
+ {
+ cdcInstance->inCallbackFn(cdcInstance->inCallbackParam, transfer->transferBuffer, transfer->transferSofar,
+ status);
+ }
+ USB_HostFreeTransfer(cdcInstance->hostHandle, transfer);
+}
+
+/*!
+ * @brief cdc data out pipe transfer callback.
+ *
+ * @param param callback parameter.
+ * @param transfer callback transfer.
+ * @param status transfer status.
+ */
+void USB_HostCdcDataOutPipeCallback(void *param, usb_host_transfer_t *transfer, usb_status_t status)
+{
+ usb_host_cdc_instance_struct_t *cdcInstance = (usb_host_cdc_instance_struct_t *)param;
+#if ((defined USB_HOST_CONFIG_CLASS_AUTO_CLEAR_STALL) && USB_HOST_CONFIG_CLASS_AUTO_CLEAR_STALL)
+ if (status == kStatus_USB_TransferStall)
+ {
+ if (USB_HostCdcClearHalt(cdcInstance, transfer, USB_HostCdcClearOutHaltCallback,
+ (USB_REQUEST_TYPE_DIR_OUT |
+ ((usb_host_pipe_t *)cdcInstance->outPipe)->endpointAddress)) == kStatus_USB_Success)
+ {
+ USB_HostFreeTransfer(cdcInstance->hostHandle, transfer);
+ return;
+ }
+ }
+#endif
+ if (cdcInstance->outCallbackFn != NULL)
+ {
+ cdcInstance->outCallbackFn(cdcInstance->outCallbackParam, transfer->transferBuffer, transfer->transferSofar,
+ status);
+ }
+
+ USB_HostFreeTransfer(cdcInstance->hostHandle, transfer);
+}
+
+/*!
+ * @brief cdc data out pipe transfer callback.
+ *
+ * @param param callback parameter.
+ * @param transfer callback transfer.
+ * @param status transfer status.
+ */
+void USB_HostCdcInterruptPipeCallback(void *param, usb_host_transfer_t *transfer, usb_status_t status)
+{
+ usb_host_cdc_instance_struct_t *cdcInstance = (usb_host_cdc_instance_struct_t *)param;
+
+#if ((defined USB_HOST_CONFIG_CLASS_AUTO_CLEAR_STALL) && USB_HOST_CONFIG_CLASS_AUTO_CLEAR_STALL)
+ if (status == kStatus_USB_TransferStall)
+ {
+ if (USB_HostCdcClearHalt(
+ cdcInstance, transfer, USB_HostCdcClearInterruptHaltCallback,
+ (USB_REQUEST_TYPE_DIR_OUT | ((usb_host_pipe_t *)cdcInstance->interruptPipe)->endpointAddress)) ==
+ kStatus_USB_Success)
+ {
+ USB_HostFreeTransfer(cdcInstance->hostHandle, transfer);
+ return;
+ }
+ }
+#endif
+
+ if (cdcInstance->interruptCallbackFn != NULL)
+ {
+ cdcInstance->interruptCallbackFn(cdcInstance->interruptCallbackParam, transfer->transferBuffer,
+ transfer->transferSofar, status);
+ }
+ USB_HostFreeTransfer(cdcInstance->hostHandle, transfer);
+}
+
+/*!
+ * @brief cdc data out pipe transfer callback.
+ *
+ * @param param callback parameter.
+ * @param transfer callback transfer.
+ * @param status transfer status.
+ */
+void USB_HostCdcControlPipeCallback(void *param, usb_host_transfer_t *transfer, usb_status_t status)
+{
+ usb_host_cdc_instance_struct_t *cdcInstance = (usb_host_cdc_instance_struct_t *)param;
+
+ if (cdcInstance->controlCallbackFn != NULL)
+ {
+ cdcInstance->controlCallbackFn(cdcInstance->controlCallbackParam, transfer->transferBuffer,
+ transfer->transferSofar, status);
+ }
+ USB_HostFreeTransfer(cdcInstance->hostHandle, transfer);
+}
+
+/*!
+ * @brief cdc open data interface.
+ *
+ * @param cdcInstance cdc instance pointer.
+ *
+ * @return kStatus_USB_Success or error codes.
+ */
+static usb_status_t USB_HostCdcOpenDataInterface(usb_host_cdc_instance_struct_t *cdcInstance)
+{
+ usb_status_t status;
+ uint8_t ep_index = 0;
+ usb_host_pipe_init_t pipeInit;
+ usb_descriptor_endpoint_t *ep_desc = NULL;
+ usb_host_interface_t *interfaceHandle;
+
+ if (cdcInstance->inPipe != NULL)
+ {
+ status = USB_HostClosePipe(cdcInstance->hostHandle, cdcInstance->inPipe);
+
+ if (status != kStatus_USB_Success)
+ {
+#ifdef HOST_ECHO
+ usb_echo("error when close pipe\r\n");
+#endif
+ }
+ cdcInstance->inPipe = NULL;
+ }
+
+ if (cdcInstance->outPipe != NULL)
+ {
+ status = USB_HostClosePipe(cdcInstance->hostHandle, cdcInstance->outPipe);
+
+ if (status != kStatus_USB_Success)
+ {
+#ifdef HOST_ECHO
+ usb_echo("error when close pipe\r\n");
+#endif
+ }
+ cdcInstance->outPipe = NULL;
+ }
+ status = USB_HostOpenDeviceInterface(cdcInstance->deviceHandle, cdcInstance->dataInterfaceHandle);
+ if (status != kStatus_USB_Success)
+ {
+ return status;
+ }
+ /* open interface pipes */
+ interfaceHandle = (usb_host_interface_t *)cdcInstance->dataInterfaceHandle;
+
+ for (ep_index = 0; ep_index < interfaceHandle->epCount; ++ep_index)
+ {
+ ep_desc = interfaceHandle->epList[ep_index].epDesc;
+ if (((ep_desc->bEndpointAddress & USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_MASK) ==
+ USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_IN) &&
+ ((ep_desc->bmAttributes & USB_DESCRIPTOR_ENDPOINT_ATTRIBUTE_TYPE_MASK) == USB_ENDPOINT_BULK))
+ {
+ pipeInit.devInstance = cdcInstance->deviceHandle;
+ pipeInit.pipeType = USB_ENDPOINT_BULK;
+ pipeInit.direction = USB_IN;
+ pipeInit.endpointAddress = (ep_desc->bEndpointAddress & USB_DESCRIPTOR_ENDPOINT_ADDRESS_NUMBER_MASK);
+ pipeInit.interval = ep_desc->bInterval;
+ pipeInit.maxPacketSize = (uint16_t)(USB_SHORT_FROM_LITTLE_ENDIAN_ADDRESS(ep_desc->wMaxPacketSize) &
+ USB_DESCRIPTOR_ENDPOINT_MAXPACKETSIZE_SIZE_MASK);
+ pipeInit.numberPerUframe = (USB_SHORT_FROM_LITTLE_ENDIAN_ADDRESS(ep_desc->wMaxPacketSize) &
+ USB_DESCRIPTOR_ENDPOINT_MAXPACKETSIZE_MULT_TRANSACTIONS_MASK);
+ pipeInit.nakCount = USB_HOST_CONFIG_MAX_NAK;
+
+ cdcInstance->bulkInPacketSize = pipeInit.maxPacketSize;
+ status = USB_HostOpenPipe(cdcInstance->hostHandle, &cdcInstance->inPipe, &pipeInit);
+ if (status != kStatus_USB_Success)
+ {
+#ifdef HOST_ECHO
+ usb_echo("usb_host_audio_set_interface fail to open pipe\r\n");
+#endif
+ return kStatus_USB_Error;
+ }
+ }
+ else if (((ep_desc->bEndpointAddress & USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_MASK) ==
+ USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_OUT) &&
+ ((ep_desc->bmAttributes & USB_DESCRIPTOR_ENDPOINT_ATTRIBUTE_TYPE_MASK) == USB_ENDPOINT_BULK))
+ {
+ pipeInit.devInstance = cdcInstance->deviceHandle;
+ pipeInit.pipeType = USB_ENDPOINT_BULK;
+ pipeInit.direction = USB_OUT;
+ pipeInit.endpointAddress = (ep_desc->bEndpointAddress & USB_DESCRIPTOR_ENDPOINT_ADDRESS_NUMBER_MASK);
+ pipeInit.interval = ep_desc->bInterval;
+ pipeInit.maxPacketSize = (uint16_t)(USB_SHORT_FROM_LITTLE_ENDIAN_ADDRESS(ep_desc->wMaxPacketSize) &
+ USB_DESCRIPTOR_ENDPOINT_MAXPACKETSIZE_SIZE_MASK);
+ pipeInit.numberPerUframe = (USB_SHORT_FROM_LITTLE_ENDIAN_ADDRESS(ep_desc->wMaxPacketSize) &
+ USB_DESCRIPTOR_ENDPOINT_MAXPACKETSIZE_MULT_TRANSACTIONS_MASK);
+ pipeInit.nakCount = USB_HOST_CONFIG_MAX_NAK;
+
+ cdcInstance->bulkOutPacketSize = pipeInit.maxPacketSize;
+ status = USB_HostOpenPipe(cdcInstance->hostHandle, &cdcInstance->outPipe, &pipeInit);
+ if (status != kStatus_USB_Success)
+ {
+#ifdef HOST_ECHO
+ usb_echo("usb_host_cdc_set_dat_interface fail to open pipe\r\n");
+#endif
+ return kStatus_USB_Error;
+ }
+ }
+ else
+ {
+ }
+ }
+ return kStatus_USB_Success;
+}
+
+/*!
+ * @brief cdc set data interface callback, open pipes.
+ *
+ * @param param callback parameter.
+ * @param transfer callback transfer.
+ * @param status transfer status.
+ */
+static void USB_HostCdcSetDataInterfaceCallback(void *param, usb_host_transfer_t *transfer, usb_status_t status)
+{
+ usb_host_cdc_instance_struct_t *cdcInstance = (usb_host_cdc_instance_struct_t *)param;
+
+ cdcInstance->controlTransfer = NULL;
+ if (status == kStatus_USB_Success)
+ {
+ status = USB_HostCdcOpenDataInterface(cdcInstance);
+ }
+
+ if (cdcInstance->controlCallbackFn != NULL)
+ {
+ cdcInstance->controlCallbackFn(cdcInstance->controlCallbackParam, NULL, 0, status);
+ }
+ USB_HostFreeTransfer(cdcInstance->hostHandle, transfer);
+}
+
+/*!
+ * @brief cdc open control interface.
+ *
+ * @param cdcInstance cdc instance pointer.
+ *
+ * @return kStatus_USB_Success or error codes.
+ */
+static usb_status_t USB_HostCdcOpenControlInterface(usb_host_cdc_instance_struct_t *cdcInstance)
+{
+ usb_status_t status;
+ uint8_t ep_index = 0;
+ usb_host_pipe_init_t pipeInit;
+ usb_descriptor_endpoint_t *ep_desc = NULL;
+ usb_host_interface_t *interfaceHandle;
+
+ if (cdcInstance->interruptPipe != NULL)
+ {
+ status = USB_HostCancelTransfer(cdcInstance->hostHandle, cdcInstance->interruptPipe, NULL);
+ status = USB_HostClosePipe(cdcInstance->hostHandle, cdcInstance->interruptPipe);
+
+ if (status != kStatus_USB_Success)
+ {
+#ifdef HOST_ECHO
+ usb_echo("error when close pipe\r\n");
+#endif
+ }
+ cdcInstance->interruptPipe = NULL;
+ }
+
+ status = USB_HostOpenDeviceInterface(cdcInstance->deviceHandle, cdcInstance->controlInterfaceHandle);
+ if (status != kStatus_USB_Success)
+ {
+ return status;
+ }
+ /* open interface pipes */
+ interfaceHandle = (usb_host_interface_t *)cdcInstance->controlInterfaceHandle;
+
+ for (ep_index = 0; ep_index < interfaceHandle->epCount; ++ep_index)
+ {
+ ep_desc = interfaceHandle->epList[ep_index].epDesc;
+ if (((ep_desc->bEndpointAddress & USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_MASK) ==
+ USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_IN) &&
+ ((ep_desc->bmAttributes & USB_DESCRIPTOR_ENDPOINT_ATTRIBUTE_TYPE_MASK) == USB_ENDPOINT_INTERRUPT))
+ {
+ pipeInit.devInstance = cdcInstance->deviceHandle;
+ pipeInit.pipeType = USB_ENDPOINT_INTERRUPT;
+ pipeInit.direction = USB_IN;
+ pipeInit.endpointAddress = (ep_desc->bEndpointAddress & USB_DESCRIPTOR_ENDPOINT_ADDRESS_NUMBER_MASK);
+ pipeInit.interval = ep_desc->bInterval;
+ pipeInit.maxPacketSize = (uint16_t)(USB_SHORT_FROM_LITTLE_ENDIAN_ADDRESS(ep_desc->wMaxPacketSize) &
+ USB_DESCRIPTOR_ENDPOINT_MAXPACKETSIZE_SIZE_MASK);
+ pipeInit.numberPerUframe = (USB_SHORT_FROM_LITTLE_ENDIAN_ADDRESS(ep_desc->wMaxPacketSize) &
+ USB_DESCRIPTOR_ENDPOINT_MAXPACKETSIZE_MULT_TRANSACTIONS_MASK);
+ pipeInit.nakCount = USB_HOST_CONFIG_MAX_NAK;
+
+ cdcInstance->packetSize = pipeInit.maxPacketSize;
+
+ status = USB_HostOpenPipe(cdcInstance->hostHandle, &cdcInstance->interruptPipe, &pipeInit);
+ if (status != kStatus_USB_Success)
+ {
+#ifdef HOST_ECHO
+ usb_echo("USB_HostCdcSetControlInterface fail to open pipe\r\n");
+#endif
+ return kStatus_USB_Error;
+ }
+ }
+ }
+ return kStatus_USB_Success;
+}
+
+/*!
+ * @brief cdc set control interface callback, open pipes.
+ *
+ * @param param callback parameter.
+ * @param transfer callback transfer.
+ * @param status transfer status.
+ */
+static void USB_HostCdcSetContorlInterfaceCallback(void *param, usb_host_transfer_t *transfer, usb_status_t status)
+{
+ usb_host_cdc_instance_struct_t *cdcInstance = (usb_host_cdc_instance_struct_t *)param;
+
+ cdcInstance->controlTransfer = NULL;
+ if (status == kStatus_USB_Success)
+ {
+ status = USB_HostCdcOpenControlInterface(cdcInstance);
+ }
+
+ if (cdcInstance->controlCallbackFn != NULL)
+ {
+ cdcInstance->controlCallbackFn(cdcInstance->controlCallbackParam, NULL, 0, status);
+ }
+ USB_HostFreeTransfer(cdcInstance->hostHandle, transfer);
+}
+
+/*!
+ * @brief initialize the cdc instance.
+ *
+ * This function allocate the resource for cdc instance.
+ *
+ * @param deviceHandle the device handle.
+ * @param classHandle return class handle.
+ *
+ * @retval kStatus_USB_Success The device is initialized successfully.
+ * @retval kStatus_USB_AllocFail Allocate memory fail.
+ */
+usb_status_t USB_HostCdcInit(usb_device_handle deviceHandle, usb_host_class_handle *classHandle)
+{
+ usb_host_cdc_instance_struct_t *control_ptr =
+ (usb_host_cdc_instance_struct_t *)USB_OsaMemoryAllocate(sizeof(usb_host_cdc_instance_struct_t));
+ uint32_t info_value;
+
+ if (control_ptr == NULL)
+ {
+ return kStatus_USB_AllocFail;
+ }
+
+ control_ptr->deviceHandle = deviceHandle;
+ control_ptr->controlInterfaceHandle = NULL;
+ control_ptr->dataInterfaceHandle = NULL;
+ USB_HostHelperGetPeripheralInformation(deviceHandle, kUSB_HostGetHostHandle, &info_value);
+ control_ptr->hostHandle = (usb_host_handle)info_value;
+ USB_HostHelperGetPeripheralInformation(deviceHandle, kUSB_HostGetDeviceControlPipe, &info_value);
+ control_ptr->controlPipe = (usb_host_pipe_handle)info_value;
+
+ *classHandle = control_ptr;
+ return kStatus_USB_Success;
+}
+
+/*!
+ * @brief set control interface.
+ *
+ * This function bind the control interface with the cdc instance.
+ *
+ * @param classHandle the class handle.
+ * @param interfaceHandle the control interface handle.
+ * @param alternateSetting the alternate setting value.
+ * @param callbackFn this callback is called after this function completes.
+ * @param callbackParam the first parameter in the callback function.
+ *
+ * @retval kStatus_USB_Success The device is initialized successfully.
+ * @retval kStatus_USB_InvalidHandle The classHandle is NULL pointer.
+ * @retval kStatus_USB_Busy There is no idle transfer.
+ * @retval kStatus_USB_Error send transfer fail, please reference to USB_HostSendSetup.
+ * @retval kStatus_USB_Busy callback return status, there is no idle pipe.
+ * @retval kStatus_USB_TransferStall callback return status, the transfer is stall by device.
+ * @retval kStatus_USB_Error callback return status, open pipe fail, please reference to USB_HostOpenPipe.
+ */
+usb_status_t USB_HostCdcSetControlInterface(usb_host_class_handle classHandle,
+ usb_host_interface_handle interfaceHandle,
+ uint8_t alternateSetting,
+ transfer_callback_t callbackFn,
+ void *callbackParam)
+{
+ usb_status_t status;
+ usb_host_cdc_instance_struct_t *cdcInstance = (usb_host_cdc_instance_struct_t *)classHandle;
+ usb_host_transfer_t *transfer;
+
+ status = kStatus_USB_Success;
+ if (classHandle == NULL)
+ {
+ return kStatus_USB_InvalidParameter;
+ }
+
+ cdcInstance->controlInterfaceHandle = interfaceHandle;
+
+ /* cancel transfers */
+ if (cdcInstance->interruptPipe != NULL)
+ {
+ status = USB_HostCancelTransfer(cdcInstance->hostHandle, cdcInstance->interruptPipe, NULL);
+
+ if (status != kStatus_USB_Success)
+ {
+#ifdef HOST_ECHO
+ usb_echo("error when cancel pipe\r\n");
+#endif
+ }
+ }
+
+ if (alternateSetting == 0)
+ {
+ if (callbackFn != NULL)
+ {
+ status = USB_HostCdcOpenControlInterface(cdcInstance);
+ callbackFn(callbackParam, NULL, 0, status);
+ }
+ }
+ else
+ {
+ if (USB_HostMallocTransfer(cdcInstance->hostHandle, &transfer) != kStatus_USB_Success)
+ {
+#ifdef HOST_ECHO
+ usb_echo("error to get transfer\r\n");
+#endif
+ return kStatus_USB_Error;
+ }
+ cdcInstance->controlCallbackFn = callbackFn;
+ cdcInstance->controlCallbackParam = callbackParam;
+ /* initialize transfer */
+ transfer->callbackFn = USB_HostCdcSetContorlInterfaceCallback;
+ transfer->callbackParam = cdcInstance;
+ transfer->setupPacket.bRequest = USB_REQUEST_STANDARD_SET_INTERFACE;
+ transfer->setupPacket.bmRequestType = USB_REQUEST_TYPE_RECIPIENT_INTERFACE;
+ transfer->setupPacket.wIndex = USB_SHORT_TO_LITTLE_ENDIAN(
+ ((usb_host_interface_t *)cdcInstance->controlInterfaceHandle)->interfaceDesc->bInterfaceNumber);
+ transfer->setupPacket.wValue = USB_SHORT_TO_LITTLE_ENDIAN(alternateSetting);
+ transfer->setupPacket.wLength = 0;
+ transfer->transferBuffer = NULL;
+ transfer->transferLength = 0;
+ status = USB_HostSendSetup(cdcInstance->hostHandle, cdcInstance->controlPipe, transfer);
+
+ if (status == kStatus_USB_Success)
+ {
+ cdcInstance->controlTransfer = transfer;
+ }
+ else
+ {
+ USB_HostFreeTransfer(cdcInstance->hostHandle, transfer);
+ }
+ }
+
+ return status;
+}
+
+/*!
+ * @brief set data interface.
+ *
+ * This function bind the control interface with the cdc instance.
+ *
+ * @param classHandle the class handle.
+ * @param interfaceHandle the data interface handle.
+ * @param alternateSetting the alternate setting value.
+ * @param callbackFn this callback is called after this function completes.
+ * @param callbackParam the first parameter in the callback function.
+ *
+ * @retval kStatus_USB_Success The device is initialized successfully.
+ * @retval kStatus_USB_InvalidHandle The classHandle is NULL pointer.
+ * @retval kStatus_USB_Busy There is no idle transfer.
+ * @retval kStatus_USB_Error send transfer fail, please reference to USB_HostSendSetup.
+ * @retval kStatus_USB_Busy callback return status, there is no idle pipe.
+ * @retval kStatus_USB_TransferStall callback return status, the transfer is stall by device.
+ * @retval kStatus_USB_Error callback return status, open pipe fail, please reference to USB_HostOpenPipe.
+ */
+usb_status_t USB_HostCdcSetDataInterface(usb_host_class_handle classHandle,
+ usb_host_interface_handle interfaceHandle,
+ uint8_t alternateSetting,
+ transfer_callback_t callbackFn,
+ void *callbackParam)
+{
+ usb_status_t status;
+ usb_host_cdc_instance_struct_t *cdcInstance = (usb_host_cdc_instance_struct_t *)classHandle;
+ usb_host_transfer_t *transfer;
+
+ status = kStatus_USB_Success;
+ if (classHandle == NULL)
+ {
+ return kStatus_USB_InvalidParameter;
+ }
+
+ cdcInstance->dataInterfaceHandle = interfaceHandle;
+
+ /* cancel transfers */
+ if (cdcInstance->inPipe != NULL)
+ {
+ status = USB_HostCancelTransfer(cdcInstance->hostHandle, cdcInstance->inPipe, NULL);
+
+ if (status != kStatus_USB_Success)
+ {
+#ifdef HOST_ECHO
+ usb_echo("error when cancel pipe\r\n");
+#endif
+ }
+ }
+
+ if (cdcInstance->outPipe != NULL)
+ {
+ status = USB_HostCancelTransfer(cdcInstance->hostHandle, cdcInstance->outPipe, NULL);
+
+ if (status != kStatus_USB_Success)
+ {
+#ifdef HOST_ECHO
+ usb_echo("error when cancel pipe\r\n");
+#endif
+ }
+ }
+
+ if (alternateSetting == 0)
+ {
+ if (callbackFn != NULL)
+ {
+ status = USB_HostCdcOpenDataInterface(cdcInstance);
+ callbackFn(callbackParam, NULL, 0, status);
+ }
+ }
+ else
+ {
+ if (USB_HostMallocTransfer(cdcInstance->hostHandle, &transfer) != kStatus_USB_Success)
+ {
+#ifdef HOST_ECHO
+ usb_echo("error to get transfer\r\n");
+#endif
+ return kStatus_USB_Error;
+ }
+ cdcInstance->controlCallbackFn = callbackFn;
+ cdcInstance->controlCallbackParam = callbackParam;
+ /* initialize transfer */
+ transfer->callbackFn = USB_HostCdcSetDataInterfaceCallback;
+ transfer->callbackParam = cdcInstance;
+ transfer->setupPacket.bRequest = USB_REQUEST_STANDARD_SET_INTERFACE;
+ transfer->setupPacket.bmRequestType = USB_REQUEST_TYPE_RECIPIENT_INTERFACE;
+ transfer->setupPacket.wIndex = USB_SHORT_TO_LITTLE_ENDIAN(
+ ((usb_host_interface_t *)cdcInstance->dataInterfaceHandle)->interfaceDesc->bInterfaceNumber);
+ transfer->setupPacket.wValue = USB_SHORT_TO_LITTLE_ENDIAN(alternateSetting);
+ transfer->setupPacket.wLength = 0;
+ transfer->transferBuffer = NULL;
+ transfer->transferLength = 0;
+ status = USB_HostSendSetup(cdcInstance->hostHandle, cdcInstance->controlPipe, transfer);
+
+ if (status == kStatus_USB_Success)
+ {
+ cdcInstance->controlTransfer = transfer;
+ }
+ else
+ {
+ USB_HostFreeTransfer(cdcInstance->hostHandle, transfer);
+ }
+ }
+
+ return status;
+}
+
+/*!
+ * @brief de-initialize the cdc instance.
+ *
+ * This function release the resource for cdc instance.
+ *
+ * @param deviceHandle the device handle.
+ * @param classHandle the class handle.
+ *
+ * @retval kStatus_USB_Success The device is de-initialized successfully.
+ */
+usb_status_t USB_HostCdcDeinit(usb_device_handle deviceHandle, usb_host_class_handle classHandle)
+{
+ usb_status_t status;
+ usb_host_cdc_instance_struct_t *cdcInstance = (usb_host_cdc_instance_struct_t *)classHandle;
+
+ if (deviceHandle == NULL)
+ {
+ return kStatus_USB_InvalidHandle;
+ }
+
+ if (classHandle != NULL)
+ {
+ if (cdcInstance->interruptPipe != NULL)
+ {
+ status = USB_HostCancelTransfer(cdcInstance->hostHandle, cdcInstance->interruptPipe, NULL);
+ status = USB_HostClosePipe(cdcInstance->hostHandle, cdcInstance->interruptPipe);
+
+ if (status != kStatus_USB_Success)
+ {
+#ifdef HOST_ECHO
+ usb_echo("error when close pipe\r\n");
+#endif
+ }
+ cdcInstance->interruptPipe = NULL;
+ }
+
+ USB_HostCloseDeviceInterface(deviceHandle, cdcInstance->controlInterfaceHandle);
+
+ if (cdcInstance->inPipe != NULL)
+ {
+ status = USB_HostCancelTransfer(cdcInstance->hostHandle, cdcInstance->inPipe, NULL);
+ status = USB_HostClosePipe(cdcInstance->hostHandle, cdcInstance->inPipe);
+
+ if (status != kStatus_USB_Success)
+ {
+#ifdef HOST_ECHO
+ usb_echo("error when close pipe\r\n");
+#endif
+ }
+ cdcInstance->inPipe = NULL;
+ }
+ if (cdcInstance->outPipe != NULL)
+ {
+ status = USB_HostCancelTransfer(cdcInstance->hostHandle, cdcInstance->outPipe, NULL);
+ status = USB_HostClosePipe(cdcInstance->hostHandle, cdcInstance->outPipe);
+
+ if (status != kStatus_USB_Success)
+ {
+#ifdef HOST_ECHO
+ usb_echo("error when close pipe\r\n");
+#endif
+ }
+ cdcInstance->outPipe = NULL;
+ }
+ if ((cdcInstance->controlPipe != NULL) && (cdcInstance->controlTransfer != NULL))
+ {
+ status =
+ USB_HostCancelTransfer(cdcInstance->hostHandle, cdcInstance->controlPipe, cdcInstance->controlTransfer);
+ }
+ USB_HostCloseDeviceInterface(deviceHandle, cdcInstance->dataInterfaceHandle);
+
+ USB_OsaMemoryFree(cdcInstance);
+ }
+ else
+ {
+ USB_HostCloseDeviceInterface(deviceHandle, NULL);
+ }
+
+ return kStatus_USB_Success;
+}
+
+/*!
+ * @brief receive data.
+ *
+ * This function implements cdc receiving data.
+ *
+ * @param classHandle the class handle.
+ * @param buffer the buffer pointer.
+ * @param bufferLength the buffer length.
+ * @param callbackFn this callback is called after this function completes.
+ * @param callbackParam the first parameter in the callback function.
+ *
+ * @retval kStatus_USB_Success receive request successfully.
+ * @retval kStatus_USB_InvalidHandle The classHandle is NULL pointer.
+ * @retval kStatus_USB_Busy There is no idle transfer.
+ * @retval kStatus_USB_Error pipe is not initialized.
+ * Or, send transfer fail, please reference to USB_HostRecv.
+ */
+usb_status_t USB_HostCdcDataRecv(usb_host_class_handle classHandle,
+ uint8_t *buffer,
+ uint32_t bufferLength,
+ transfer_callback_t callbackFn,
+ void *callbackParam)
+{
+ usb_host_cdc_instance_struct_t *cdcInstance = (usb_host_cdc_instance_struct_t *)classHandle;
+ usb_host_transfer_t *transfer;
+
+ if (classHandle == NULL)
+ {
+ return kStatus_USB_InvalidHandle;
+ }
+
+ if (cdcInstance->inPipe == NULL)
+ {
+ return kStatus_USB_Error;
+ }
+
+ if (USB_HostMallocTransfer(cdcInstance->hostHandle, &transfer) != kStatus_USB_Success)
+ {
+#ifdef HOST_ECHO
+ usb_echo("error to get transfer\r\n");
+#endif
+ return kStatus_USB_Error;
+ }
+ cdcInstance->inCallbackFn = callbackFn;
+ cdcInstance->inCallbackParam = callbackParam;
+ transfer->transferBuffer = buffer;
+ transfer->transferLength = bufferLength;
+ transfer->callbackFn = USB_HostCdcDataInPipeCallback;
+ transfer->callbackParam = cdcInstance;
+
+ if (USB_HostRecv(cdcInstance->hostHandle, cdcInstance->inPipe, transfer) != kStatus_USB_Success)
+ {
+#ifdef HOST_ECHO
+ usb_echo("failt to USB_HostRecv\r\n");
+#endif
+ USB_HostFreeTransfer(cdcInstance->hostHandle, transfer);
+ return kStatus_USB_Error;
+ }
+
+ return kStatus_USB_Success;
+}
+
+/*!
+ * @brief send data.
+ *
+ * This function implements cdc sending data.
+ *
+ * @param classHandle the class handle.
+ * @param buffer the buffer pointer.
+ * @param bufferLength the buffer length.
+ * @param callbackFn this callback is called after this function completes.
+ * @param callbackParam the first parameter in the callback function.
+ *
+ * @retval kStatus_USB_Success receive request successfully.
+ * @retval kStatus_USB_InvalidHandle The classHandle is NULL pointer.
+ * @retval kStatus_USB_Busy There is no idle transfer.
+ * @retval kStatus_USB_Error pipe is not initialized.
+ * Or, send transfer fail, please reference to USB_HostSend.
+ */
+usb_status_t USB_HostCdcDataSend(usb_host_class_handle classHandle,
+ uint8_t *buffer,
+ uint32_t bufferLength,
+ transfer_callback_t callbackFn,
+ void *callbackParam)
+{
+ usb_host_cdc_instance_struct_t *cdcInstance = (usb_host_cdc_instance_struct_t *)classHandle;
+ usb_host_transfer_t *transfer;
+
+ if (classHandle == NULL)
+ {
+ return kStatus_USB_InvalidHandle;
+ }
+
+ if (cdcInstance->outPipe == NULL)
+ {
+ return kStatus_USB_Error;
+ }
+
+ if (USB_HostMallocTransfer(cdcInstance->hostHandle, &transfer) != kStatus_USB_Success)
+ {
+#ifdef HOST_ECHO
+ usb_echo("error to get transfer\r\n");
+#endif
+ return kStatus_USB_Error;
+ }
+ cdcInstance->outCallbackFn = callbackFn;
+ cdcInstance->outCallbackParam = callbackParam;
+ transfer->transferBuffer = buffer;
+ transfer->transferLength = bufferLength;
+ transfer->callbackFn = USB_HostCdcDataOutPipeCallback;
+ transfer->callbackParam = cdcInstance;
+
+ if (USB_HostSend(cdcInstance->hostHandle, cdcInstance->outPipe, transfer) != kStatus_USB_Success)
+ {
+#ifdef HOST_ECHO
+ usb_echo("failt to USB_HostSend\r\n");
+#endif
+ USB_HostFreeTransfer(cdcInstance->hostHandle, transfer);
+ return kStatus_USB_Error;
+ }
+ return kStatus_USB_Success;
+}
+
+/*!
+ * @brief interrupt receive data.
+ *
+ * This function implements interrupt receiving data.
+ *
+ * @param classHandle the class handle.
+ * @param buffer the buffer pointer.
+ * @param bufferLength the buffer length.
+ * @param callbackFn this callback is called after this function completes.
+ * @param callbackParam the first parameter in the callback function.
+ *
+ * @retval kStatus_USB_Success receive request successfully.
+ * @retval kStatus_USB_InvalidHandle The classHandle is NULL pointer.
+ * @retval kStatus_USB_Busy There is no idle transfer.
+ * @retval kStatus_USB_Error pipe is not initialized.
+ * Or, send transfer fail, please reference to USB_HostRecv.
+ */
+usb_status_t USB_HostCdcInterruptRecv(usb_host_class_handle classHandle,
+ uint8_t *buffer,
+ uint32_t bufferLength,
+ transfer_callback_t callbackFn,
+ void *callbackParam)
+{
+ usb_host_cdc_instance_struct_t *cdcInstance = (usb_host_cdc_instance_struct_t *)classHandle;
+ usb_host_transfer_t *transfer;
+
+ if (classHandle == NULL)
+ {
+ return kStatus_USB_InvalidHandle;
+ }
+
+ if (cdcInstance->interruptPipe == NULL)
+ {
+ return kStatus_USB_Error;
+ }
+
+ if (USB_HostMallocTransfer(cdcInstance->hostHandle, &transfer) != kStatus_USB_Success)
+ {
+#ifdef HOST_ECHO
+ usb_echo("error to get transfer\r\n");
+#endif
+ return kStatus_USB_Error;
+ }
+ cdcInstance->interruptCallbackFn = callbackFn;
+ cdcInstance->interruptCallbackParam = callbackParam;
+ transfer->transferBuffer = buffer;
+ transfer->transferLength = bufferLength;
+ transfer->callbackFn = USB_HostCdcInterruptPipeCallback;
+ transfer->callbackParam = cdcInstance;
+
+ if (USB_HostRecv(cdcInstance->hostHandle, cdcInstance->interruptPipe, transfer) != kStatus_USB_Success)
+ {
+#ifdef HOST_ECHO
+ usb_echo("failt to usb_interrupt_recv\r\n");
+#endif
+ USB_HostFreeTransfer(cdcInstance->hostHandle, transfer);
+ return kStatus_USB_Error;
+ }
+ return kStatus_USB_Success;
+}
+/*!
+ * @brief get pipe max packet size.
+ *
+ * @param[in] classHandle the class handle.
+ * @param[in] pipeType It's value is USB_ENDPOINT_CONTROL, USB_ENDPOINT_ISOCHRONOUS, USB_ENDPOINT_BULK or
+ * USB_ENDPOINT_INTERRUPT.
+ * Please reference to usb_spec.h
+ * @param[in] direction pipe direction.
+ *
+ * @retval 0 The classHandle is NULL.
+ * @retval max packet size.
+ */
+uint16_t USB_HostCdcGetPacketsize(usb_host_class_handle classHandle, uint8_t pipeType, uint8_t direction)
+{
+ usb_host_cdc_instance_struct_t *cdcInstance = (usb_host_cdc_instance_struct_t *)classHandle;
+ if (classHandle == NULL)
+ {
+ return 0;
+ }
+
+ if (pipeType == USB_ENDPOINT_BULK)
+ {
+ if (direction == USB_IN)
+ {
+ return cdcInstance->bulkInPacketSize;
+ }
+ else
+ {
+ return cdcInstance->bulkOutPacketSize;
+ }
+ }
+
+ return 0;
+}
+
+/*!
+ * @brief cdc send control transfer common code.
+ *
+ * @param classHandle the class handle.
+ * @param request_type setup packet request type.
+ * @param request setup packet request value.
+ * @param wvalue_l setup packet wvalue low byte.
+ * @param wvalue_h setup packet wvalue high byte.
+ * @param wlength setup packet wlength value.
+ * @param data data buffer pointer
+ * @param callbackFn this callback is called after this function completes.
+ * @param callbackParam the first parameter in the callback function.
+ *
+ * @return An error code or kStatus_USB_Success.
+ */
+usb_status_t USB_HostCdcControl(usb_host_class_handle classHandle,
+ uint8_t request_type,
+ uint8_t request,
+ uint8_t wvalue_l,
+ uint8_t wvalue_h,
+ uint16_t wlength,
+ uint8_t *data,
+ transfer_callback_t callbackFn,
+ void *callbackParam)
+{
+ usb_host_cdc_instance_struct_t *cdcInstance = (usb_host_cdc_instance_struct_t *)classHandle;
+ usb_host_transfer_t *transfer;
+
+ if (classHandle == NULL)
+ {
+ return kStatus_USB_InvalidHandle;
+ }
+
+ if (USB_HostMallocTransfer(cdcInstance->hostHandle, &transfer) != kStatus_USB_Success)
+ {
+#ifdef HOST_ECHO
+ usb_echo("error to get transfer\r\n");
+#endif
+ return kStatus_USB_Error;
+ }
+ cdcInstance->controlCallbackFn = callbackFn;
+ cdcInstance->controlCallbackParam = callbackParam;
+
+ transfer->transferBuffer = data;
+ transfer->transferLength = wlength;
+ transfer->callbackFn = USB_HostCdcControlPipeCallback;
+ transfer->callbackParam = cdcInstance;
+ transfer->setupPacket.bmRequestType = request_type;
+ transfer->setupPacket.bRequest = request;
+ transfer->setupPacket.wValue = (wvalue_l | (uint16_t)((uint16_t)wvalue_h << 8));
+ transfer->setupPacket.wIndex = USB_SHORT_TO_LITTLE_ENDIAN(
+ ((usb_host_interface_t *)cdcInstance->controlInterfaceHandle)->interfaceDesc->bInterfaceNumber);
+ transfer->setupPacket.wLength = USB_SHORT_TO_LITTLE_ENDIAN(wlength);
+
+ if (USB_HostSendSetup(cdcInstance->hostHandle, cdcInstance->controlPipe, transfer) != kStatus_USB_Success)
+ {
+#ifdef HOST_ECHO
+ usb_echo("failt for USB_HostSendSetup\r\n");
+#endif
+ USB_HostFreeTransfer(cdcInstance->hostHandle, transfer);
+ return kStatus_USB_Error;
+ }
+ cdcInstance->controlTransfer = transfer;
+
+ return kStatus_USB_Success;
+}
+
+/*!
+ * @brief cdc get line coding.
+ *
+ * This function implements cdc GetLineCoding request.refer to pstn spec.
+ *
+ * @param classHandle the class handle.
+ * @param buffer the buffer pointer.
+ * @param bufferLength the buffer length.
+ * @param callbackFn this callback is called after this function completes.
+ * @param callbackParam the first parameter in the callback function.
+ *
+ * @retval kStatus_USB_Success request successfully.
+ * @retval kStatus_USB_InvalidHandle The classHandle is NULL pointer.
+ * @retval kStatus_USB_Busy There is no idle transfer.
+ * @retval kStatus_USB_Error send transfer fail, please reference to USB_HostSendSetup.
+ */
+usb_status_t USB_HostCdcGetAcmLineCoding(usb_host_class_handle classHandle,
+ usb_host_cdc_line_coding_struct_t *uartLineCoding,
+ transfer_callback_t callbackFn,
+ void *callbackParam)
+{
+ return USB_HostCdcControl(
+ classHandle, USB_REQUEST_TYPE_DIR_IN | USB_REQUEST_TYPE_TYPE_CLASS | USB_REQUEST_TYPE_RECIPIENT_INTERFACE,
+ USB_HOST_CDC_GET_LINE_CODING, 0, 0, 7, (uint8_t *)uartLineCoding, callbackFn, callbackParam);
+}
+
+/*!
+ * @brief cdc setControlLineState.
+ *
+ * This function implements cdc etControlLineState request.refer to pstn spec.
+ *
+ * @param classHandle the class handle.
+ * @param buffer the buffer pointer.
+ * @param bufferLength the buffer length.
+ * @param callbackFn this callback is called after this function completes.
+ * @param callbackParam the first parameter in the callback function.
+ *
+ * @retval kStatus_USB_Success request successfully.
+ * @retval kStatus_USB_InvalidHandle The classHandle is NULL pointer.
+ * @retval kStatus_USB_Busy There is no idle transfer.
+ * @retval kStatus_USB_Error send transfer fail, please reference to USB_HostSendSetup.
+ */
+usb_status_t USB_HostCdcSetAcmCtrlState(
+ usb_host_class_handle classHandle, uint8_t dtr, uint8_t rts, transfer_callback_t callbackFn, void *callbackParam)
+{
+ uint16_t lineState = 0;
+
+ usb_host_cdc_instance_struct_t *cdcInstance = (usb_host_cdc_instance_struct_t *)classHandle;
+
+ lineState = dtr ? USB_HOST_CDC_CONTROL_LINE_STATE_DTR : 0;
+ lineState |= rts ? USB_HOST_CDC_CONTROL_LINE_STATE_RTS : 0;
+ return USB_HostCdcControl(
+ cdcInstance, USB_REQUEST_TYPE_DIR_OUT | USB_REQUEST_TYPE_TYPE_CLASS | USB_REQUEST_TYPE_RECIPIENT_INTERFACE,
+ USB_HOST_CDC_SET_CONTROL_LINE_STATE, USB_SHORT_GET_LOW(lineState), USB_SHORT_GET_HIGH(lineState), 0, NULL,
+ callbackFn, callbackParam);
+}
+
+/*!
+ * @brief cdc get acm descriptor.
+ *
+ * This function is hunting for class specific acm decriptor in the configuration ,get the corresponding
+ * descriptor .
+ *
+ * @param classHandle the class handle.
+ * @param headDesc the head function descriptor pointer.
+ * @param callManageDesc the call management functional descriptor pointer.
+ * @param abstractControlDesc the abstract control management functional pointer.
+ * @param unionInterfaceDesc the union functional descriptor pointer.
+ *
+ * @retval kStatus_USB_Error analyse descriptor error.
+ */
+usb_status_t USB_HostCdcGetAcmDescriptor(usb_host_class_handle classHandle,
+ usb_host_cdc_head_function_desc_struct_t **headDesc,
+ usb_host_cdc_call_manage_desc_struct_t **callManageDesc,
+ usb_host_cdc_abstract_control_desc_struct_t **abstractControlDesc,
+ usb_host_cdc_union_interface_desc_struct_t **unionInterfaceDesc)
+{
+ usb_status_t status;
+ usb_descriptor_union_t *ptr1;
+ uint32_t end_address;
+ usb_host_cdc_instance_struct_t *cdcInstance = (usb_host_cdc_instance_struct_t *)classHandle;
+ usb_cdc_func_desc_struct_t *cdc_common_ptr;
+ usb_host_interface_t *interface_handle;
+
+ status = kStatus_USB_Success;
+ interface_handle = (usb_host_interface_t *)cdcInstance->controlInterfaceHandle;
+ ptr1 = (usb_descriptor_union_t *)interface_handle->interfaceExtension;
+ end_address = (uint32_t)(interface_handle->interfaceExtension + interface_handle->interfaceExtensionLength);
+
+ while ((uint32_t)ptr1 < end_address)
+ {
+ cdc_common_ptr = (usb_cdc_func_desc_struct_t *)&ptr1->common;
+ switch (cdc_common_ptr->common.bDescriptorSubtype)
+ {
+ case USB_HOST_DESC_SUBTYPE_HEADER:
+ *headDesc = &cdc_common_ptr->head;
+ if ((((uint32_t)((*headDesc)->bcdCDC[1]) << 8) + (*headDesc)->bcdCDC[0]) > 0x0110)
+ {
+ status = kStatus_USB_Error;
+ }
+ break;
+ case USB_HOST_DESC_SUBTYPE_UNION:
+ if (cdc_common_ptr->unionDesc.bControlInterface == interface_handle->interfaceDesc->bInterfaceNumber)
+ {
+ *unionInterfaceDesc = &cdc_common_ptr->unionDesc;
+ }
+ else
+ {
+ status = kStatus_USB_Error;
+ }
+ break;
+ case USB_HOST_DESC_SUBTYPE_CM:
+ *callManageDesc = &cdc_common_ptr->callManage;
+ break;
+ case USB_HOST_DESC_SUBTYPE_ACM:
+ *abstractControlDesc = &cdc_common_ptr->acm;
+ break;
+ default:
+ break;
+ }
+
+ if (kStatus_USB_Success != status)
+ {
+ break;
+ }
+ ptr1 = (usb_descriptor_union_t *)((uint8_t *)ptr1 + ptr1->common.bLength);
+ }
+ cdcInstance->headDesc = *headDesc;
+ cdcInstance->callManageDesc = *callManageDesc;
+ cdcInstance->abstractControlDesc = *abstractControlDesc;
+ cdcInstance->unionInterfaceDesc = *unionInterfaceDesc;
+ return status;
+}
+
+#endif
diff --git a/usb_1.1.0/host/class/usb_host_cdc.h b/usb_1.1.0/host/class/usb_host_cdc.h
new file mode 100644
index 0000000..0acc181
--- /dev/null
+++ b/usb_1.1.0/host/class/usb_host_cdc.h
@@ -0,0 +1,518 @@
+/*
+ * Copyright (c) 2015 - 2016, Freescale Semiconductor, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * o Redistributions of source code must retain the above copyright notice, this list
+ * of conditions and the following disclaimer.
+ *
+ * o Redistributions in binary form must reproduce the above copyright notice, this
+ * list of conditions and the following disclaimer in the documentation and/or
+ * other materials provided with the distribution.
+ *
+ * o Neither the name of Freescale Semiconductor, Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __USB_HOST_CDC_H__
+#define __USB_HOST_CDC_H__
+
+/*!
+ * @addtogroup usb_host_cdc_drv
+ * @{
+ */
+
+/*******************************************************************************
+ * Definitions
+ ******************************************************************************/
+
+/* Class-specific request PSTN*/
+/*! @brief CDC class-specific request (SET_LINE_CODING) */
+#define USB_HOST_CDC_SET_LINE_CODING 0x20U
+/*! @brief CDC class-specific request (GET_LINE_CODING) */
+#define USB_HOST_CDC_GET_LINE_CODING 0x21U
+/*! @brief CDC class-specific request (SET_CONTROL_LINE_STATE) */
+#define USB_HOST_CDC_SET_CONTROL_LINE_STATE 0x22U
+
+/*! @brief CDC class-specific notifications(SerialState) bitmap*/
+#define USB_HOST_ACM_UART_STATE_BITMAP_BTXCARRITER 0x01U
+/*! @brief CDC class-specific notifications(SerialState) bitmap*/
+#define USB_HOST_ACM_UART_STATE_BITMAP_BRXCARRITER 0x02U
+/*! @brief CDC class-specific notifications(SerialState) bitmap*/
+#define USB_HOST_ACM_UART_STATE_BITMAP_BBREAK 0x04U
+/*! @brief CDC class-specific notifications(SerialState) bitmap*/
+#define USB_HOST_ACM_UART_STATE_BITMAP_BBRINGSIGNAL 0x10U
+
+/*! @brief CDC class-specific request (SET_CONTROL_LINE_STATE) bitmap*/
+#define USB_HOST_CDC_CONTROL_LINE_STATE_DTR 0x01U
+/*! @brief CDC class-specific request (SET_CONTROL_LINE_STATE) bitmap*/
+#define USB_HOST_CDC_CONTROL_LINE_STATE_RTS 0x02U
+
+/*CDC SPEC*/
+/*! @brief CDC class-specific bDescriptor SubType in functional descriptors*/
+#define USB_HOST_DESC_SUBTYPE_HEADER 0x00U
+/*! @brief CDC class-specific bDescriptor SubType in functional descriptors*/
+#define USB_HOST_DESC_SUBTYPE_CM 0x01U
+/*! @brief CDC class-specific bDescriptor SubType in functional descriptors*/
+#define USB_HOST_DESC_SUBTYPE_ACM 0x02U
+/*! @brief CDC class-specific bDescriptor SubType in functional descriptors*/
+#define USB_HOST_DESC_SUBTYPE_DLM 0x03U
+/*! @brief CDC class-specific bDescriptor SubType in functional descriptors*/
+#define USB_HOST_DESC_SUBTYPE_TR 0x04U
+/*! @brief CDC class-specific bDescriptor SubType in functional descriptors*/
+#define USB_HOST_DESC_SUBTYPE_TC_LSR 0x05U
+/*! @brief CDC class-specific bDescriptor SubType in functional descriptors*/
+#define USB_HOST_DESC_SUBTYPE_UNION 0x06U
+/*! @brief CDC class-specific bDescriptor SubType in functional descriptors*/
+#define USB_HOST_DESC_SUBTYPE_CS 0x07U
+/*! @brief CDC class-specific bDescriptor SubType in functional descriptors*/
+#define USB_HOST_DESC_SUBTYPE_TOM 0x08U
+
+/*See the CDC specification page20*/
+/*! @brief CDC class-specific code, Communications Interface Class Code*/
+#define USB_HOST_CDC_COMMUNICATIONS_CLASS_CODE 0x02U
+/*! @brief CDC class-specific code,Communications Class Subclass Codes*/
+#define USB_HOST_CDC_SUBCLASS_ACM_CODE 0x02U
+/*No class specific protocol required. See the CDC specification page22*/
+#define USB_HOST_CDC_PROTOCOL_CODE 0x00U
+/*! @brief CDC class-specific code,Data Class Interface Codes*/
+#define USB_HOST_CDC_DATA_CLASS_CODE 0x0AU
+/* This field is unused for Data Class interfaces and should have a value of 00h.*/
+#define USB_HOST_CDC_DATA_SUBCLASS_CODE 0x00U
+/*No class-specific protocol required. See the CDC specification page22*/
+#define USB_HOST_CDC_DATA_PROTOCOL_CODE 0x00U
+
+/*! @brief CDC GetLineCoding structure according to the 6.3 in PSTN specification */
+typedef struct _usb_host_cdc_line_coding_struct
+{
+ uint32_t dwDTERate; /*!< Data terminal rate, in bits per second*/
+ uint8_t bCharFormat; /*!< Stop bits*/
+ uint8_t bParityType; /*!< Parity*/
+ uint8_t bDataBits; /*!< Data bits (5, 6, 7, 8 or 16).*/
+} usb_host_cdc_line_coding_struct_t;
+
+/*! @brief CDC GetLineCoding structure according to the 6.3 in PSTN specification */
+typedef struct _usb_host_cdc_control_line_state_struct
+{
+ uint16_t line_state; /*!< D1, This signal corresponds to V.24 signal 105 and RS-232 signal RTS*/
+ /*!< D0, This signal corresponds to V.24 signal 108/2 and RS-232 signal DTR*/
+} usb_host_cdc_control_line_state_struct_t;
+
+/*! @brief CDC SerialState structure according to the 6.5.4 in PSTN specification */
+typedef struct _usb_host_cdc_acm_state_struct
+{
+ uint8_t reserved[8]; /*!< Notify response by the device, this is used as notification header, which is returned by the
+ device */
+ uint8_t bmstate; /*!< UART State Bitmap Values*/
+ uint8_t reserved1[1]; /*!< Fix 4B align issue*/
+ uint8_t reserved2[2]; /*!< Fix 4B align issue*/
+} usb_host_cdc_acm_state_struct_t;
+
+/*! @brief CDC Header Functional Descriptor structure according to the 5.2.3 in CDC specification */
+typedef struct _usb_host_cdc_head_function_desc_struct
+{
+ uint8_t bFunctionLength; /*!<Size of this descriptor in bytes.*/
+ uint8_t bDescriptorType; /*!<CS_INTERFACE descriptor type.*/
+ uint8_t bDescriptorSubtype; /*!<Header functional descriptor subtype.*/
+ uint8_t bcdCDC[2]; /*!<USB Class Definitions for Communications Devices Specification release number in binary-coded
+ decimal.*/
+} usb_host_cdc_head_function_desc_struct_t;
+
+/*! @brief CDC Call Management Functional Descriptor structure according to the 5.3.1 in PSTN specification */
+typedef struct _usb_host_cdc_call_manage_desc_struct
+{
+ uint8_t bFunctionLength; /*!<Size of this descriptor in bytes.*/
+ uint8_t bDescriptorType; /*!<CS_INTERFACE.*/
+ uint8_t bDescriptorSubtype; /*!<Call Management functional descriptor subtype.*/
+ uint8_t bmCapabilities; /*!<The capabilities that this configuration supports.*/
+ uint8_t bDataInterface; /*!<Interface number of Data Class interface optionally used for call management.*/
+} usb_host_cdc_call_manage_desc_struct_t;
+
+/*! @brief CDC Abstract Control Management Functional Descriptor structure according to the 5.3.2 in PSTN specification
+ */
+typedef struct _usb_host_cdc_abstract_control_desc_struct
+{
+ uint8_t bFunctionLength; /*!<Size of this descriptor in bytes.*/
+ uint8_t bDescriptorType; /*!<CS_INTERFACE.*/
+ uint8_t bDescriptorSubtype; /*!<Abstract Control Management functional descriptor subtype.*/
+ uint8_t bmCapabilities; /*!<The capabilities that this configuration supports.*/
+} usb_host_cdc_abstract_control_desc_struct_t;
+
+/*! @brief CDC Direct Line Management Functional Descriptor structure according to the 5.3.3 in PSTN specification */
+typedef struct _usb_host_cdc_direct_line_desc_struct
+{
+ uint8_t bFunctionLength; /*!<Size of this descriptor in bytes.*/
+ uint8_t bDescriptorType; /*!<CS_INTERFACE.*/
+ uint8_t bDescriptorSubtype; /*!<Direct Line Management functional descriptor subtype,.*/
+ uint8_t bmCapabilities; /*!<The capabilities that this configuration supports.*/
+} usb_host_cdc_direct_line_desc_struct_t;
+
+/*! @brief CDC Telephone Ringer Functional Descriptor structure according to the 5.3.4 in PSTN specification */
+typedef struct _usb_host_cdc_telephone_ringer_desc_struct
+{
+ uint8_t bFunctionLength; /*!<Size of this descriptor in bytes.*/
+ uint8_t bDescriptorType; /*!<CS_INTERFACE.*/
+ uint8_t bDescriptorSubtype; /*!<Telephone Ringer functional descriptor subtype*/
+ uint8_t bRingerVolSteps; /*!<Number of discrete steps in volume supported by the ringer,.*/
+ uint8_t bNumRingerPatterns; /*!<Number of ringer patterns supported.*/
+} usb_host_cdc_telephone_ringer_desc_struct_t;
+
+/*! @brief CDC Telephone Call and Line State Reporting Capabilities Descriptor structure according to the 5.3.6 in PSTN
+ * specification */
+typedef struct _usb_host_cdc_tcLsr_desc_struct
+{
+ uint8_t bFunctionLength; /*!<Size of this descriptor in bytes.*/
+ uint8_t bDescriptorType; /*!<CS_INTERFACE.*/
+ uint8_t bDescriptorSubtype; /*!<Telephone Call State Reporting Capabilities descriptor subtype.*/
+ uint8_t bmCapabilities[4]; /*!<Call and line state reporting capabilities of the device.*/
+} usb_host_cdc_tcLsr_desc_struct_t;
+
+/*! @brief CDC Header Functional Descriptor structure according to the 5.2.3 in CDC specification */
+typedef struct _usb_host_cdc_union_interface_desc_struct
+{
+ uint8_t bFunctionLength; /*!<Size of this descriptor in bytes.*/
+ uint8_t bDescriptorType; /*!<CS_INTERFACE descriptor type.*/
+ uint8_t bDescriptorSubtype; /*!<Union Functional Descriptor SubType.*/
+ uint8_t bControlInterface; /*!<USB Class Definitions for Communications Devices Specification release number in
+ binary-coded decimal.*/
+} usb_host_cdc_union_interface_desc_struct_t;
+
+/*! @brief CDC Telephone Operational Modes Functional Descriptor structure according to the 5.3.5 in PSTN specification
+ */
+typedef struct _usb_host_cdc_tom_desc_struct
+{
+ uint8_t bFunctionLength; /*!<Size of this descriptor in bytes.*/
+ uint8_t bDescriptorType; /*!<CS_INTERFACE.*/
+ uint8_t bDescriptorSubtype; /*!<Telephone Operational Modes functional descriptor subtype.*/
+ uint8_t bmCapabilities; /*!<Operational modes:.*/
+} usb_host_cdc_tom_desc_struct_t;
+
+/*! @brief CDC common Functional Descriptor structure */
+typedef struct _usb_host_cdc_common_desc_struct
+{
+ uint8_t bFunctionLength; /*!<Size of this descriptor in bytes.*/
+ uint8_t bDescriptorType; /*!<CS_INTERFACE descriptor type.*/
+ uint8_t bDescriptorSubtype; /*!<Header functional descriptor subtype.*/
+} usb_host_cdc_common_desc_struct_t;
+
+/*! @brief CDC union Functional Descriptor structure for analyze a class-specific descriptor */
+typedef union _usb_cdc_func_desc_struct
+{
+ usb_host_cdc_common_desc_struct_t common;
+ usb_host_cdc_head_function_desc_struct_t head;
+ usb_host_cdc_union_interface_desc_struct_t unionDesc;
+ usb_host_cdc_call_manage_desc_struct_t callManage;
+ usb_host_cdc_abstract_control_desc_struct_t acm;
+ usb_host_cdc_direct_line_desc_struct_t dl;
+ usb_host_cdc_telephone_ringer_desc_struct_t tr;
+ usb_host_cdc_tom_desc_struct_t tom;
+ usb_host_cdc_tcLsr_desc_struct_t tcLsr;
+} usb_cdc_func_desc_struct_t;
+
+typedef struct _usb_host_cdc_instance_struct
+{
+ usb_host_handle hostHandle; /*!< The handle of the USB host. */
+ usb_device_handle deviceHandle; /*!< The handle of the USB device structure. */
+ usb_host_interface_handle controlInterfaceHandle; /*!< The handle of the CDC device control interface. */
+ usb_host_interface_handle dataInterfaceHandle; /*!< The handle of the CDC device data interface. */
+ usb_host_pipe_handle interruptPipe; /*!< Interrupt pipe for the CDC device data interface. */
+ usb_host_pipe_handle controlPipe; /*!< Control pipe*/
+ usb_host_pipe_handle inPipe; /*!< CDC bulk in pipe*/
+ usb_host_pipe_handle outPipe; /*!< CDC bulk out pipe*/
+ usb_host_cdc_head_function_desc_struct_t *headDesc; /*!< CDC class-specific head function descriptor*/
+ usb_host_cdc_call_manage_desc_struct_t *callManageDesc; /*!< cdCDCc class-specific call manage descriptor*/
+ usb_host_cdc_abstract_control_desc_struct_t
+ *abstractControlDesc; /*!< CDC class-specific abstract control descriptor*/
+ usb_host_cdc_union_interface_desc_struct_t *unionInterfaceDesc; /*!< CDC class-specific union function descriptor*/
+ void *interruptCallbackParam; /*!< CDC interrupt in transfer callback parameter*/
+ void *controlCallbackParam; /*!< CDC control transfer callback parameter*/
+ void *inCallbackParam; /*!< CDC bulk in transfer callback parameter*/
+ void *outCallbackParam; /*!< CDC bulk out transfer callback parameter*/
+ usb_host_transfer_t *controlTransfer; /*!< Ongoing control transfer*/
+ transfer_callback_t controlCallbackFn; /*!< CDC control transfer callback function pointer*/
+ transfer_callback_t interruptCallbackFn; /*!< CDC interrupt transfer callback function pointer*/
+ transfer_callback_t outCallbackFn; /*!< CDC bulk out transfer callback function pointer*/
+ transfer_callback_t inCallbackFn; /*!< CDC bulk in transfer callback function pointer*/
+#if ((defined USB_HOST_CONFIG_CLASS_AUTO_CLEAR_STALL) && USB_HOST_CONFIG_CLASS_AUTO_CLEAR_STALL)
+ uint8_t *stallDataBuffer; /*!< Keep the data buffer for stall transfer's data*/
+ uint32_t stallDataLength; /*!< Keep the data length for stall transfer's data*/
+#endif
+ uint16_t packetSize; /*!< CDC control pipe maximum packet size*/
+ uint16_t bulkOutPacketSize; /*!< CDC bulk out maximum packet size*/
+ uint16_t bulkInPacketSize; /*!< CDC bulk in maximum packet size*/
+} usb_host_cdc_instance_struct_t;
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*******************************************************************************
+ * API
+ ******************************************************************************/
+
+/*!
+ * @name USB CDC host class driver
+ * @{
+ */
+
+/*!
+ * @brief Initializes the CDC instance.
+ *
+ * This function allocates the resource for the CDC instance.
+ *
+ * @param deviceHandle The device handle.
+ * @param classHandle Returns class handle.
+ *
+ * @retval kStatus_USB_Success The device is initialized successfully.
+ * @retval kStatus_USB_AllocFail Allocate memory fail.
+ */
+extern usb_status_t USB_HostCdcInit(usb_device_handle deviceHandle, usb_host_class_handle *classHandle);
+
+/*!
+ * @brief CDC set data interface callback and opens pipes.
+ *
+ * @param[in] classHandle The class handle.
+ * @param[in] interfaceHandle The interface handle.
+ * @param[in] alternateSetting The alternate setting value.
+ * @param[in] callbackFn This callback is called after this function completes.
+ * @param[in] callbackParam The first parameter in the callback function.
+ *
+ * @retval kStatus_USB_Success The device is initialized successfully.
+ * @retval kStatus_USB_InvalidHandle The classHandle is NULL pointer.
+ * @retval kStatus_USB_Busy There is no idle transfer.
+ * @retval kStatus_USB_Error Send transfer fail. See the USB_HostSendSetup.
+ * @retval kStatus_USB_Busy Callback return status, there is no idle pipe.
+ * @retval kStatus_USB_TransferStall Callback return status, the transfer is stalled by the device.
+ * @retval kStatus_USB_Error Callback return status, open pipe fail. See the USB_HostOpenPipe.
+ */
+
+extern usb_status_t USB_HostCdcSetDataInterface(usb_host_class_handle classHandle,
+ usb_host_interface_handle interfaceHandle,
+ uint8_t alternateSetting,
+ transfer_callback_t callbackFn,
+ void *callbackParam);
+
+/*!
+ * @brief CDC set control interface callback and opens pipes.
+ *
+ * @param[in] classHandle The class handle.
+ * @param[in] interfaceHandle The interface handle.
+ * @param[in] alternateSetting The alternate setting value.
+ * @param[in] callbackFn This callback is called after this function completes.
+ * @param[in] callbackParam The first parameter in the callback function.
+ *
+ * @retval kStatus_USB_Success The device is initialized successfully.
+ * @retval kStatus_USB_InvalidHandle The classHandle is NULL pointer.
+ * @retval kStatus_USB_Busy There is no idle transfer.
+ * @retval kStatus_USB_Error Send transfer fail. See the USB_HostSendSetup.
+ * @retval kStatus_USB_Busy Callback return status, there is no idle pipe.
+ * @retval kStatus_USB_TransferStall Callback return status, the transfer is stalled by the device.
+ * @retval kStatus_USB_Error Callback return status, open pipe fail. See the USB_HostOpenPipe.
+ */
+
+extern usb_status_t USB_HostCdcSetControlInterface(usb_host_class_handle classHandle,
+ usb_host_interface_handle interfaceHandle,
+ uint8_t alternateSetting,
+ transfer_callback_t callbackFn,
+ void *callbackParam);
+
+/*!
+ * @brief Deinitializes the CDC instance.
+ *
+ * This function frees the resource for the CDC instance.
+ *
+ * @param deviceHandle The device handle.
+ * @param classHandle The class handle.
+ *
+ * @retval kStatus_USB_Success The device is de-initialized successfully.
+ */
+extern usb_status_t USB_HostCdcDeinit(usb_device_handle deviceHandle, usb_host_class_handle classHandle);
+
+/*!
+ * @brief Gets the pipe maximum packet size.
+ *
+ * @param[in] classHandle The class handle.
+ * @param[in] pipeType Its value is USB_ENDPOINT_CONTROL, USB_ENDPOINT_ISOCHRONOUS, USB_ENDPOINT_BULK or
+ * USB_ENDPOINT_INTERRUPT.
+ * See the usb_spec.h
+ * @param[in] direction Pipe direction.
+ *
+ * @retval 0 The classHandle is NULL.
+ * @retval max Packet size.
+ */
+extern uint16_t USB_HostCdcGetPacketsize(usb_host_class_handle classHandle, uint8_t pipeType, uint8_t direction);
+
+/*!
+ * @brief Receives data.
+ *
+ * This function implements the CDC receiving data.
+ *
+ * @param classHandle The class handle.
+ * @param buffer The buffer pointer.
+ * @param bufferLength The buffer length.
+ * @param callbackFn This callback is called after this function completes.
+ * @param callbackParam The first parameter in the callback function.
+ *
+ * @retval kStatus_USB_Success Receive request successfully.
+ * @retval kStatus_USB_InvalidHandle The classHandle is NULL pointer.
+ * @retval kStatus_USB_Busy There is no idle transfer.
+ * @retval kStatus_USB_Error Pipe is not initialized.
+ * Or, send transfer fail. See the USB_HostRecv.
+ */
+extern usb_status_t USB_HostCdcDataRecv(usb_host_class_handle classHandle,
+ uint8_t *buffer,
+ uint32_t bufferLength,
+ transfer_callback_t callbackFn,
+ void *callbackParam);
+
+/*!
+ * @brief Sends data.
+ *
+ * This function implements the CDC sending data.
+ *
+ * @param classHandle The class handle.
+ * @param buffer The buffer pointer.
+ * @param bufferLength The buffer length.
+ * @param callbackFn This callback is called after this function completes.
+ * @param callbackParam The first parameter in the callback function.
+ *
+ * @retval kStatus_USB_Success Receive request successfully.
+ * @retval kStatus_USB_InvalidHandle The classHandle is NULL pointer.
+ * @retval kStatus_USB_Busy There is no idle transfer.
+ * @retval kStatus_USB_Error Pipe is not initialized.
+ * Or, send transfer fail. See the USB_HostSend.
+ */
+extern usb_status_t USB_HostCdcDataSend(usb_host_class_handle classHandle,
+ uint8_t *buffer,
+ uint32_t bufferLength,
+ transfer_callback_t callbackFn,
+ void *callbackParam);
+
+/*!
+ * @brief Interrupts the receive data.
+ *
+ * This function implements the interrupt receiving data.
+ *
+ * @param classHandle The class handle.
+ * @param buffer The buffer pointer.
+ * @param bufferLength The buffer length.
+ * @param callbackFn This callback is called after this function completes.
+ * @param callbackParam The first parameter in the callback function.
+ *
+ * @retval kStatus_USB_Success Receive request successfully.
+ * @retval kStatus_USB_InvalidHandle The classHandle is NULL pointer.
+ * @retval kStatus_USB_Busy There is no idle transfer.
+ * @retval kStatus_USB_Error Pipe is not initialized.
+ * Or, send transfer fail. See the USB_HostRecv.
+ */
+extern usb_status_t USB_HostCdcInterruptRecv(usb_host_class_handle classHandle,
+ uint8_t *buffer,
+ uint32_t bufferLength,
+ transfer_callback_t callbackFn,
+ void *callbackParam);
+
+/*!
+ * @brief CDC get line coding.
+ *
+ * This function implements the CDC GetLineCoding request. See the PSTN specification.
+ *
+ * @param classHandle The class handle.
+ * @param uartLineCoding The line coding pointer.
+ * @param callbackFn This callback is called after this function completes.
+ * @param callbackParam The first parameter in the callback function.
+ *
+ * @retval kStatus_USB_Success Request successful.
+ * @retval kStatus_USB_InvalidHandle The classHandle is NULL pointer.
+ * @retval kStatus_USB_Busy There is no idle transfer.
+ * @retval kStatus_USB_Error Send transfer fail. See the USB_HostSendSetup.
+ */
+extern usb_status_t USB_HostCdcGetAcmLineCoding(usb_host_class_handle classHandle,
+ usb_host_cdc_line_coding_struct_t *uartLineCoding,
+ transfer_callback_t callbackFn,
+ void *callbackParam);
+
+/*!
+ * @brief CDC setControlLineState.
+ *
+ * This function implements the CDC etControlLineState request. See PSTN specification.
+ *
+ * @param classHandle The class handle.
+ * @param dtr The DRS value.
+ * @param rts The RTS value.
+ * @param callbackFn This callback is called after this function completes.
+ * @param callbackParam The first parameter in the callback function.
+ *
+ * @retval kStatus_USB_Success Request successful.
+ * @retval kStatus_USB_InvalidHandle The classHandle is NULL pointer.
+ * @retval kStatus_USB_Busy There is no idle transfer.
+ * @retval kStatus_USB_Error Send transfer fail. See the USB_HostSendSetup.
+ */
+extern usb_status_t USB_HostCdcSetAcmCtrlState(
+ usb_host_class_handle classHandle, uint8_t dtr, uint8_t rts, transfer_callback_t callbackFn, void *callbackParam);
+
+/*!
+ * @brief CDC gets the ACM descriptor.
+ *
+ * This function is hunting for the class-specific ACM descriptor in the configuration and gets the corresponding
+ * descriptor.
+ *
+ * @param classHandle The class handle.
+ * @param headDesc The head function descriptor pointer.
+ * @param callManageDesc The call management functional descriptor pointer.
+ * @param abstractControlDesc The abstract control management functional pointer.
+ * @param unionInterfaceDesc The union functional descriptor pointer.
+ *
+ * @retval kStatus_USB_Error Analyse descriptor error.
+ */
+extern usb_status_t USB_HostCdcGetAcmDescriptor(usb_host_class_handle classHandle,
+ usb_host_cdc_head_function_desc_struct_t **headDesc,
+ usb_host_cdc_call_manage_desc_struct_t **callManageDesc,
+ usb_host_cdc_abstract_control_desc_struct_t **abstractControlDesc,
+ usb_host_cdc_union_interface_desc_struct_t **unionInterfaceDesc);
+
+/*!
+ * @brief CDC send control transfer common code.
+ *
+ * @param classHandle The class handle.
+ * @param request_type Set up the packet request type.
+ * @param request Set up the packet request value.
+ * @param wvalue_l Set up the packet wvalue low byte.
+ * @param wvalue_h Set up the packet wvalue high byte.
+ * @param wlength Set up the packet wlength value.
+ * @param data Data buffer pointer
+ * @param callbackFn This callback is called after this function completes.
+ * @param callbackParam The first parameter in the callback function.
+ *
+ * @return An error code or kStatus_USB_Success.
+ */
+extern usb_status_t USB_HostCdcControl(usb_host_class_handle classHandle,
+ uint8_t request_type,
+ uint8_t request,
+ uint8_t wvalue_l,
+ uint8_t wvalue_h,
+ uint16_t wlength,
+ uint8_t *data,
+ transfer_callback_t callbackFn,
+ void *callbackParam);
+/*@}*/
+
+#ifdef __cplusplus
+}
+#endif
+/*@}*/
+
+#endif /*__USB_HOST_CDC_H__*/
diff --git a/usb_1.1.0/host/class/usb_host_hid.c b/usb_1.1.0/host/class/usb_host_hid.c
new file mode 100644
index 0000000..ddaf3be
--- /dev/null
+++ b/usb_1.1.0/host/class/usb_host_hid.c
@@ -0,0 +1,804 @@
+/*
+ * Copyright (c) 2015 - 2016, Freescale Semiconductor, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * o Redistributions of source code must retain the above copyright notice, this list
+ * of conditions and the following disclaimer.
+ *
+ * o Redistributions in binary form must reproduce the above copyright notice, this
+ * list of conditions and the following disclaimer in the documentation and/or
+ * other materials provided with the distribution.
+ *
+ * o Neither the name of Freescale Semiconductor, Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "usb_host_config.h"
+#if ((defined USB_HOST_CONFIG_HID) && (USB_HOST_CONFIG_HID))
+#include "usb_host.h"
+#include "usb_host_hid.h"
+
+/*******************************************************************************
+ * API
+ ******************************************************************************/
+
+/*!
+ * @brief hid in pipe transfer callback.
+ *
+ * @param param callback parameter.
+ * @param transfer callback transfer.
+ * @param status transfer status.
+ */
+static void USB_HostHidInPipeCallback(void *param, usb_host_transfer_t *transfer, usb_status_t status);
+
+/*!
+ * @brief hid out pipe transfer callback.
+ *
+ * @param param callback parameter.
+ * @param transfer callback transfer.
+ * @param status transfer status.
+ */
+static void USB_HostHidOutPipeCallback(void *param, usb_host_transfer_t *transfer, usb_status_t status);
+
+/*!
+ * @brief hid control pipe transfer callback.
+ *
+ * @param param callback parameter.
+ * @param transfer callback transfer.
+ * @param status transfer status.
+ */
+static void USB_HostHidControlCallback(void *param, usb_host_transfer_t *transfer, usb_status_t status);
+
+/*!
+ * @brief hid open interface. It is called when set interface request success or open alternate setting 0 interface.
+ *
+ * @param hidInstance hid instance pointer.
+ *
+ * @return kStatus_USB_Success or error codes.
+ */
+static usb_status_t USB_HostHidOpenInterface(usb_host_hid_instance_t *hidInstance);
+
+/*!
+ * @brief hid set interface callback, open pipes.
+ *
+ * @param param callback parameter.
+ * @param transfer callback transfer.
+ * @param status transfer status.
+ */
+static void USB_HostHidSetInterfaceCallback(void *param, usb_host_transfer_t *transfer, usb_status_t status);
+
+/*!
+ * @brief hid send control transfer common code.
+ *
+ * @param classHandle the class handle.
+ * @param requestType setup packet request type.
+ * @param request setup packet request value.
+ * @param wvalueL setup packet wvalue low byte.
+ * @param wvalueH setup packet wvalue high byte.
+ * @param wlength setup packet wlength value.
+ * @param data data buffer pointer
+ * @param callbackFn this callback is called after this function completes.
+ * @param callbackParam the first parameter in the callback function.
+ *
+ * @return An error code or kStatus_USB_Success.
+ */
+static usb_status_t USB_HostHidControl(usb_host_class_handle classHandle,
+ uint8_t requestType,
+ uint8_t request,
+ uint8_t wvalueL,
+ uint8_t wvalueH,
+ uint16_t wlength,
+ uint8_t *data,
+ transfer_callback_t callbackFn,
+ void *callbackParam);
+
+/*******************************************************************************
+ * Definitions
+ ******************************************************************************/
+/*******************************************************************************
+ * Prototypes
+ ******************************************************************************/
+/*******************************************************************************
+ * Variables
+ ******************************************************************************/
+/*******************************************************************************
+ * Code
+ ******************************************************************************/
+
+#if ((defined USB_HOST_CONFIG_CLASS_AUTO_CLEAR_STALL) && USB_HOST_CONFIG_CLASS_AUTO_CLEAR_STALL)
+
+static void USB_HostHidClearInHaltCallback(void *param, usb_host_transfer_t *transfer, usb_status_t status)
+{
+ usb_host_hid_instance_t *hidInstance = (usb_host_hid_instance_t *)param;
+
+ hidInstance->controlTransfer = NULL;
+ if (hidInstance->inCallbackFn != NULL)
+ {
+ /* callback to application */
+ hidInstance->inCallbackFn(hidInstance->inCallbackParam, hidInstance->stallDataBuffer,
+ hidInstance->stallDataLength, kStatus_USB_TransferStall);
+ }
+ USB_HostFreeTransfer(hidInstance->hostHandle, transfer);
+}
+
+static void USB_HostHidClearOutHaltCallback(void *param, usb_host_transfer_t *transfer, usb_status_t status)
+{
+ usb_host_hid_instance_t *hidInstance = (usb_host_hid_instance_t *)param;
+
+ hidInstance->controlTransfer = NULL;
+ if (hidInstance->outCallbackFn != NULL)
+ {
+ /* callback to application */
+ hidInstance->outCallbackFn(hidInstance->outCallbackParam, hidInstance->stallDataBuffer,
+ hidInstance->stallDataLength, kStatus_USB_TransferStall);
+ }
+ USB_HostFreeTransfer(hidInstance->hostHandle, transfer);
+}
+
+static usb_status_t USB_HostHidClearHalt(usb_host_hid_instance_t *hidInstance,
+ usb_host_transfer_t *stallTransfer,
+ host_inner_transfer_callback_t callbackFn,
+ uint8_t endpoint)
+{
+ usb_status_t status;
+ usb_host_transfer_t *transfer;
+
+ /* malloc one transfer */
+ status = USB_HostMallocTransfer(hidInstance->hostHandle, &transfer);
+ if (status != kStatus_USB_Success)
+ {
+#ifdef HOST_ECHO
+ usb_echo("allocate transfer error\r\n");
+#endif
+ return status;
+ }
+ hidInstance->stallDataBuffer = stallTransfer->transferBuffer;
+ hidInstance->stallDataLength = stallTransfer->transferSofar;
+ /* save the application callback function */
+ hidInstance->controlCallbackFn = NULL;
+ hidInstance->controlCallbackParam = NULL;
+ /* initialize transfer */
+ transfer->callbackFn = callbackFn;
+ transfer->callbackParam = hidInstance;
+ transfer->transferBuffer = NULL;
+ transfer->transferLength = 0;
+ transfer->setupPacket.bRequest = USB_REQUEST_STANDARD_CLEAR_FEATURE;
+ transfer->setupPacket.bmRequestType = USB_REQUEST_TYPE_RECIPIENT_ENDPOINT;
+ transfer->setupPacket.wValue = USB_SHORT_TO_LITTLE_ENDIAN(USB_REQUEST_STANDARD_FEATURE_SELECTOR_ENDPOINT_HALT);
+ transfer->setupPacket.wIndex = USB_SHORT_TO_LITTLE_ENDIAN(endpoint);
+ transfer->setupPacket.wLength = 0;
+ status = USB_HostSendSetup(hidInstance->hostHandle, hidInstance->controlPipe, transfer);
+
+ if (status != kStatus_USB_Success)
+ {
+ USB_HostFreeTransfer(hidInstance->hostHandle, transfer);
+ }
+ hidInstance->controlTransfer = transfer;
+
+ return status;
+}
+#endif
+
+static void USB_HostHidInPipeCallback(void *param, usb_host_transfer_t *transfer, usb_status_t status)
+{
+ usb_host_hid_instance_t *hidInstance = (usb_host_hid_instance_t *)param;
+
+#if ((defined USB_HOST_CONFIG_CLASS_AUTO_CLEAR_STALL) && USB_HOST_CONFIG_CLASS_AUTO_CLEAR_STALL)
+ if (status == kStatus_USB_TransferStall)
+ {
+ if (USB_HostHidClearHalt(hidInstance, transfer, USB_HostHidClearInHaltCallback,
+ (USB_REQUEST_TYPE_DIR_IN |
+ ((usb_host_pipe_t *)hidInstance->inPipe)->endpointAddress)) == kStatus_USB_Success)
+ {
+ USB_HostFreeTransfer(hidInstance->hostHandle, transfer);
+ return;
+ }
+ }
+#endif
+ if (hidInstance->inCallbackFn != NULL)
+ {
+ hidInstance->inCallbackFn(hidInstance->inCallbackParam, transfer->transferBuffer, transfer->transferSofar,
+ status); /* callback to application */
+ }
+ USB_HostFreeTransfer(hidInstance->hostHandle, transfer);
+}
+
+static void USB_HostHidOutPipeCallback(void *param, usb_host_transfer_t *transfer, usb_status_t status)
+{
+ usb_host_hid_instance_t *hidInstance = (usb_host_hid_instance_t *)param;
+
+#if ((defined USB_HOST_CONFIG_CLASS_AUTO_CLEAR_STALL) && USB_HOST_CONFIG_CLASS_AUTO_CLEAR_STALL)
+ if (status == kStatus_USB_TransferStall)
+ {
+ if (USB_HostHidClearHalt(hidInstance, transfer, USB_HostHidClearOutHaltCallback,
+ (USB_REQUEST_TYPE_DIR_OUT |
+ ((usb_host_pipe_t *)hidInstance->outPipe)->endpointAddress)) == kStatus_USB_Success)
+ {
+ USB_HostFreeTransfer(hidInstance->hostHandle, transfer);
+ return;
+ }
+ }
+#endif
+ if (hidInstance->outCallbackFn != NULL)
+ {
+ hidInstance->outCallbackFn(hidInstance->outCallbackParam, transfer->transferBuffer, transfer->transferSofar,
+ status); /* callback to application */
+ }
+ USB_HostFreeTransfer(hidInstance->hostHandle, transfer);
+}
+
+static void USB_HostHidControlCallback(void *param, usb_host_transfer_t *transfer, usb_status_t status)
+{
+ usb_host_hid_instance_t *hidInstance = (usb_host_hid_instance_t *)param;
+
+ hidInstance->controlTransfer = NULL;
+ if (hidInstance->controlCallbackFn != NULL)
+ {
+ hidInstance->controlCallbackFn(hidInstance->controlCallbackParam, transfer->transferBuffer,
+ transfer->transferSofar, status); /* callback to application */
+ }
+ USB_HostFreeTransfer(hidInstance->hostHandle, transfer);
+}
+
+static usb_status_t USB_HostHidOpenInterface(usb_host_hid_instance_t *hidInstance)
+{
+ usb_status_t status;
+ uint8_t epIndex = 0;
+ usb_host_pipe_init_t pipeInit;
+ usb_descriptor_endpoint_t *epDesc = NULL;
+ usb_host_interface_t *interfacePointer;
+
+ if (hidInstance->inPipe != NULL) /* close interrupt in pipe if it is open */
+ {
+ status = USB_HostClosePipe(hidInstance->hostHandle, hidInstance->inPipe);
+
+ if (status != kStatus_USB_Success)
+ {
+#ifdef HOST_ECHO
+ usb_echo("error when close pipe\r\n");
+#endif
+ }
+ hidInstance->inPipe = NULL;
+ }
+ if (hidInstance->outPipe != NULL) /* close interrupt out pipe if it is open */
+ {
+ status = USB_HostClosePipe(hidInstance->hostHandle, hidInstance->outPipe);
+
+ if (status != kStatus_USB_Success)
+ {
+#ifdef HOST_ECHO
+ usb_echo("error when close pipe\r\n");
+#endif
+ }
+ hidInstance->outPipe = NULL;
+ }
+
+ /* open interface pipes */
+ interfacePointer = (usb_host_interface_t *)hidInstance->interfaceHandle;
+ for (epIndex = 0; epIndex < interfacePointer->epCount; ++epIndex)
+ {
+ epDesc = interfacePointer->epList[epIndex].epDesc;
+ if (((epDesc->bEndpointAddress & USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_MASK) ==
+ USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_IN) &&
+ ((epDesc->bmAttributes & USB_DESCRIPTOR_ENDPOINT_ATTRIBUTE_TYPE_MASK) == USB_ENDPOINT_INTERRUPT))
+ {
+ pipeInit.devInstance = hidInstance->deviceHandle;
+ pipeInit.pipeType = USB_ENDPOINT_INTERRUPT;
+ pipeInit.direction = USB_IN;
+ pipeInit.endpointAddress = (epDesc->bEndpointAddress & USB_DESCRIPTOR_ENDPOINT_ADDRESS_NUMBER_MASK);
+ pipeInit.interval = epDesc->bInterval;
+ pipeInit.maxPacketSize = (uint16_t)(USB_SHORT_FROM_LITTLE_ENDIAN_ADDRESS(epDesc->wMaxPacketSize) &
+ USB_DESCRIPTOR_ENDPOINT_MAXPACKETSIZE_SIZE_MASK);
+ pipeInit.numberPerUframe = (USB_SHORT_FROM_LITTLE_ENDIAN_ADDRESS(epDesc->wMaxPacketSize) &
+ USB_DESCRIPTOR_ENDPOINT_MAXPACKETSIZE_MULT_TRANSACTIONS_MASK);
+ pipeInit.nakCount = USB_HOST_CONFIG_MAX_NAK;
+
+ hidInstance->inPacketSize = pipeInit.maxPacketSize;
+
+ status = USB_HostOpenPipe(hidInstance->hostHandle, &hidInstance->inPipe, &pipeInit);
+ if (status != kStatus_USB_Success)
+ {
+#ifdef HOST_ECHO
+ usb_echo("USB_HostHidSetInterface fail to open pipe\r\n");
+#endif
+ return kStatus_USB_Error;
+ }
+ }
+ else if (((epDesc->bEndpointAddress & USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_MASK) ==
+ USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_OUT) &&
+ ((epDesc->bmAttributes & USB_DESCRIPTOR_ENDPOINT_ATTRIBUTE_TYPE_MASK) == USB_ENDPOINT_INTERRUPT))
+ {
+ pipeInit.devInstance = hidInstance->deviceHandle;
+ pipeInit.pipeType = USB_ENDPOINT_INTERRUPT;
+ pipeInit.direction = USB_OUT;
+ pipeInit.endpointAddress = (epDesc->bEndpointAddress & USB_DESCRIPTOR_ENDPOINT_ADDRESS_NUMBER_MASK);
+ pipeInit.interval = epDesc->bInterval;
+ pipeInit.maxPacketSize = (uint16_t)(USB_SHORT_FROM_LITTLE_ENDIAN_ADDRESS(epDesc->wMaxPacketSize) &
+ USB_DESCRIPTOR_ENDPOINT_MAXPACKETSIZE_SIZE_MASK);
+ pipeInit.numberPerUframe = (USB_SHORT_FROM_LITTLE_ENDIAN_ADDRESS(epDesc->wMaxPacketSize) &
+ USB_DESCRIPTOR_ENDPOINT_MAXPACKETSIZE_MULT_TRANSACTIONS_MASK);
+ pipeInit.nakCount = USB_HOST_CONFIG_MAX_NAK;
+
+ hidInstance->outPacketSize = pipeInit.maxPacketSize;
+
+ status = USB_HostOpenPipe(hidInstance->hostHandle, &hidInstance->outPipe, &pipeInit);
+ if (status != kStatus_USB_Success)
+ {
+#ifdef HOST_ECHO
+ usb_echo("USB_HostHidSetInterface fail to open pipe\r\n");
+#endif
+ return kStatus_USB_Error;
+ }
+ }
+ else
+ {
+ }
+ }
+
+ return kStatus_USB_Success;
+}
+
+static void USB_HostHidSetInterfaceCallback(void *param, usb_host_transfer_t *transfer, usb_status_t status)
+{
+ usb_host_hid_instance_t *hidInstance = (usb_host_hid_instance_t *)param;
+
+ hidInstance->controlTransfer = NULL;
+ if (status == kStatus_USB_Success)
+ {
+ status = USB_HostHidOpenInterface(hidInstance); /* hid open interface */
+ }
+
+ if (hidInstance->controlCallbackFn != NULL)
+ {
+ hidInstance->controlCallbackFn(hidInstance->controlCallbackParam, NULL, 0,
+ status); /* callback to application */
+ }
+ USB_HostFreeTransfer(hidInstance->hostHandle, transfer);
+}
+
+usb_status_t USB_HostHidInit(usb_device_handle deviceHandle, usb_host_class_handle *classHandle)
+{
+ uint32_t infoValue;
+ usb_host_hid_instance_t *hidInstance = (usb_host_hid_instance_t *)USB_OsaMemoryAllocate(
+ sizeof(usb_host_hid_instance_t)); /* malloc hid class instance */
+
+ if (hidInstance == NULL)
+ {
+ return kStatus_USB_AllocFail;
+ }
+
+ /* initialize hid instance */
+ hidInstance->deviceHandle = deviceHandle;
+ hidInstance->interfaceHandle = NULL;
+ USB_HostHelperGetPeripheralInformation(deviceHandle, kUSB_HostGetHostHandle, &infoValue);
+ hidInstance->hostHandle = (usb_host_handle)infoValue;
+ USB_HostHelperGetPeripheralInformation(deviceHandle, kUSB_HostGetDeviceControlPipe, &infoValue);
+ hidInstance->controlPipe = (usb_host_pipe_handle)infoValue;
+
+ *classHandle = hidInstance;
+ return kStatus_USB_Success;
+}
+
+usb_status_t USB_HostHidSetInterface(usb_host_class_handle classHandle,
+ usb_host_interface_handle interfaceHandle,
+ uint8_t alternateSetting,
+ transfer_callback_t callbackFn,
+ void *callbackParam)
+{
+ usb_status_t status;
+ usb_host_hid_instance_t *hidInstance = (usb_host_hid_instance_t *)classHandle;
+ usb_host_transfer_t *transfer;
+
+ if (classHandle == NULL)
+ {
+ return kStatus_USB_InvalidParameter;
+ }
+
+ hidInstance->interfaceHandle = interfaceHandle;
+ status = USB_HostOpenDeviceInterface(hidInstance->deviceHandle,
+ interfaceHandle); /* notify host driver the interface is open */
+ if (status != kStatus_USB_Success)
+ {
+ return status;
+ }
+
+ /* cancel transfers */
+ if (hidInstance->inPipe != NULL)
+ {
+ status = USB_HostCancelTransfer(hidInstance->hostHandle, hidInstance->inPipe, NULL);
+
+ if (status != kStatus_USB_Success)
+ {
+#ifdef HOST_ECHO
+ usb_echo("error when cancel pipe\r\n");
+#endif
+ }
+ }
+ if (hidInstance->outPipe != NULL)
+ {
+ status = USB_HostCancelTransfer(hidInstance->hostHandle, hidInstance->outPipe, NULL);
+
+ if (status != kStatus_USB_Success)
+ {
+#ifdef HOST_ECHO
+ usb_echo("error when cancel pipe\r\n");
+#endif
+ }
+ }
+
+ if (alternateSetting == 0) /* open interface directly */
+ {
+ if (callbackFn != NULL)
+ {
+ status = USB_HostHidOpenInterface(hidInstance);
+ callbackFn(callbackParam, NULL, 0, status);
+ }
+ }
+ else /* send setup transfer */
+ {
+ /* malloc one transfer */
+ if (USB_HostMallocTransfer(hidInstance->hostHandle, &transfer) != kStatus_USB_Success)
+ {
+#ifdef HOST_ECHO
+ usb_echo("error to get transfer\r\n");
+#endif
+ return kStatus_USB_Error;
+ }
+
+ /* save the application callback function */
+ hidInstance->controlCallbackFn = callbackFn;
+ hidInstance->controlCallbackParam = callbackParam;
+ /* initialize transfer */
+ transfer->callbackFn = USB_HostHidSetInterfaceCallback;
+ transfer->callbackParam = hidInstance;
+ transfer->setupPacket.bRequest = USB_REQUEST_STANDARD_SET_INTERFACE;
+ transfer->setupPacket.bmRequestType = USB_REQUEST_TYPE_RECIPIENT_INTERFACE;
+ transfer->setupPacket.wIndex = USB_SHORT_TO_LITTLE_ENDIAN(
+ ((usb_host_interface_t *)hidInstance->interfaceHandle)->interfaceDesc->bInterfaceNumber);
+ transfer->setupPacket.wValue = USB_SHORT_TO_LITTLE_ENDIAN(alternateSetting);
+ transfer->setupPacket.wLength = 0;
+ transfer->transferBuffer = NULL;
+ transfer->transferLength = 0;
+ status = USB_HostSendSetup(hidInstance->hostHandle, hidInstance->controlPipe, transfer);
+
+ if (status == kStatus_USB_Success)
+ {
+ hidInstance->controlTransfer = transfer;
+ }
+ else
+ {
+ USB_HostFreeTransfer(hidInstance->hostHandle, transfer);
+ }
+ }
+
+ return status;
+}
+
+usb_status_t USB_HostHidDeinit(usb_device_handle deviceHandle, usb_host_class_handle classHandle)
+{
+ usb_status_t status;
+ usb_host_hid_instance_t *hidInstance = (usb_host_hid_instance_t *)classHandle;
+
+ if (deviceHandle == NULL)
+ {
+ return kStatus_USB_InvalidHandle;
+ }
+
+ if (classHandle != NULL) /* class instance has initialized */
+ {
+ if (hidInstance->inPipe != NULL)
+ {
+ status = USB_HostCancelTransfer(hidInstance->hostHandle, hidInstance->inPipe, NULL); /* cancel pipe */
+ status = USB_HostClosePipe(hidInstance->hostHandle, hidInstance->inPipe); /* close pipe */
+
+ if (status != kStatus_USB_Success)
+ {
+#ifdef HOST_ECHO
+ usb_echo("error when close pipe\r\n");
+#endif
+ }
+ hidInstance->inPipe = NULL;
+ }
+ if (hidInstance->outPipe != NULL)
+ {
+ status = USB_HostCancelTransfer(hidInstance->hostHandle, hidInstance->outPipe, NULL); /* cancel pipe */
+ status = USB_HostClosePipe(hidInstance->hostHandle, hidInstance->outPipe); /* close pipe */
+
+ if (status != kStatus_USB_Success)
+ {
+#ifdef HOST_ECHO
+ usb_echo("error when close pipe\r\n");
+#endif
+ }
+ hidInstance->outPipe = NULL;
+ }
+ if ((hidInstance->controlPipe != NULL) &&
+ (hidInstance->controlTransfer != NULL)) /* cancel control transfer if there is on-going control transfer */
+ {
+ status =
+ USB_HostCancelTransfer(hidInstance->hostHandle, hidInstance->controlPipe, hidInstance->controlTransfer);
+ }
+ USB_HostCloseDeviceInterface(deviceHandle,
+ hidInstance->interfaceHandle); /* notify host driver the interface is closed */
+ USB_OsaMemoryFree(hidInstance);
+ }
+ else
+ {
+ USB_HostCloseDeviceInterface(deviceHandle, NULL);
+ }
+
+ return kStatus_USB_Success;
+}
+
+uint16_t USB_HostHidGetPacketsize(usb_host_class_handle classHandle, uint8_t pipeType, uint8_t direction)
+{
+ usb_host_hid_instance_t *hidInstance = (usb_host_hid_instance_t *)classHandle;
+ if (classHandle == NULL)
+ {
+ return 0;
+ }
+
+ if (pipeType == USB_ENDPOINT_INTERRUPT)
+ {
+ if (direction == USB_IN)
+ {
+ return hidInstance->inPacketSize;
+ }
+ else
+ {
+ return hidInstance->outPacketSize;
+ }
+ }
+
+ return 0;
+}
+
+usb_status_t USB_HostHidRecv(usb_host_class_handle classHandle,
+ uint8_t *buffer,
+ uint32_t bufferLength,
+ transfer_callback_t callbackFn,
+ void *callbackParam)
+{
+ usb_host_hid_instance_t *hidInstance = (usb_host_hid_instance_t *)classHandle;
+ usb_host_transfer_t *transfer;
+
+ if (classHandle == NULL)
+ {
+ return kStatus_USB_InvalidHandle;
+ }
+
+ if (hidInstance->inPipe == NULL)
+ {
+ return kStatus_USB_Error;
+ }
+
+ /* malloc one transfer */
+ if (USB_HostMallocTransfer(hidInstance->hostHandle, &transfer) != kStatus_USB_Success)
+ {
+#ifdef HOST_ECHO
+ usb_echo("error to get transfer\r\n");
+#endif
+ return kStatus_USB_Busy;
+ }
+ /* save the application callback function */
+ hidInstance->inCallbackFn = callbackFn;
+ hidInstance->inCallbackParam = callbackParam;
+ /* initialize transfer */
+ transfer->transferBuffer = buffer;
+ transfer->transferLength = bufferLength;
+ transfer->callbackFn = USB_HostHidInPipeCallback;
+ transfer->callbackParam = hidInstance;
+
+ if (USB_HostRecv(hidInstance->hostHandle, hidInstance->inPipe, transfer) !=
+ kStatus_USB_Success) /* call host driver api */
+ {
+#ifdef HOST_ECHO
+ usb_echo("failt to USB_HostRecv\r\n");
+#endif
+ USB_HostFreeTransfer(hidInstance->hostHandle, transfer);
+ return kStatus_USB_Error;
+ }
+
+ return kStatus_USB_Success;
+}
+
+usb_status_t USB_HostHidSend(usb_host_class_handle classHandle,
+ uint8_t *buffer,
+ uint32_t bufferLength,
+ transfer_callback_t callbackFn,
+ void *callbackParam)
+{
+ usb_host_hid_instance_t *hidInstance = (usb_host_hid_instance_t *)classHandle;
+ usb_host_transfer_t *transfer;
+
+ if (classHandle == NULL)
+ {
+ return kStatus_USB_InvalidHandle;
+ }
+
+ if (hidInstance->outPipe == NULL)
+ {
+ return kStatus_USB_Error;
+ }
+
+ /* malloc one transfer */
+ if (USB_HostMallocTransfer(hidInstance->hostHandle, &transfer) != kStatus_USB_Success)
+ {
+#ifdef HOST_ECHO
+ usb_echo("error to get transfer\r\n");
+#endif
+ return kStatus_USB_Error;
+ }
+ /* save the application callback function */
+ hidInstance->outCallbackFn = callbackFn;
+ hidInstance->outCallbackParam = callbackParam;
+ /* initialize transfer */
+ transfer->transferBuffer = buffer;
+ transfer->transferLength = bufferLength;
+ transfer->callbackFn = USB_HostHidOutPipeCallback;
+ transfer->callbackParam = hidInstance;
+
+ if (USB_HostSend(hidInstance->hostHandle, hidInstance->outPipe, transfer) !=
+ kStatus_USB_Success) /* call host driver api */
+ {
+#ifdef HOST_ECHO
+ usb_echo("failt to USB_HostSend\r\n");
+#endif
+ USB_HostFreeTransfer(hidInstance->hostHandle, transfer);
+ return kStatus_USB_Error;
+ }
+
+ return kStatus_USB_Success;
+}
+
+static usb_status_t USB_HostHidControl(usb_host_class_handle classHandle,
+ uint8_t requestType,
+ uint8_t request,
+ uint8_t wvalueL,
+ uint8_t wvalueH,
+ uint16_t wlength,
+ uint8_t *data,
+ transfer_callback_t callbackFn,
+ void *callbackParam)
+{
+ usb_host_hid_instance_t *hidInstance = (usb_host_hid_instance_t *)classHandle;
+ usb_host_transfer_t *transfer;
+
+ if (classHandle == NULL)
+ {
+ return kStatus_USB_InvalidHandle;
+ }
+
+ /* malloc one transfer */
+ if (USB_HostMallocTransfer(hidInstance->hostHandle, &transfer) != kStatus_USB_Success)
+ {
+#ifdef HOST_ECHO
+ usb_echo("error to get transfer\r\n");
+#endif
+ return kStatus_USB_Busy;
+ }
+ /* save the application callback function */
+ hidInstance->controlCallbackFn = callbackFn;
+ hidInstance->controlCallbackParam = callbackParam;
+ /* initialize transfer */
+ transfer->transferBuffer = data;
+ transfer->transferLength = wlength;
+ transfer->callbackFn = USB_HostHidControlCallback;
+ transfer->callbackParam = hidInstance;
+ transfer->setupPacket.bmRequestType = requestType;
+ transfer->setupPacket.bRequest = request;
+ transfer->setupPacket.wValue = (wvalueL | (uint16_t)((uint16_t)wvalueH << 8));
+ transfer->setupPacket.wIndex = USB_SHORT_TO_LITTLE_ENDIAN(
+ ((usb_host_interface_t *)hidInstance->interfaceHandle)->interfaceDesc->bInterfaceNumber);
+ transfer->setupPacket.wLength = USB_SHORT_TO_LITTLE_ENDIAN(wlength);
+
+ if (USB_HostSendSetup(hidInstance->hostHandle, hidInstance->controlPipe, transfer) !=
+ kStatus_USB_Success) /* call host driver api */
+ {
+#ifdef HOST_ECHO
+ usb_echo("failt for USB_HostSendSetup\r\n");
+#endif
+ USB_HostFreeTransfer(hidInstance->hostHandle, transfer);
+ return kStatus_USB_Error;
+ }
+ hidInstance->controlTransfer = transfer;
+
+ return kStatus_USB_Success;
+}
+
+usb_status_t USB_HostHidGetReportDescriptor(usb_host_class_handle classHandle,
+ uint8_t *buffer,
+ uint16_t buffer_len,
+ transfer_callback_t callbackFn,
+ void *callbackParam)
+{
+ return USB_HostHidControl(
+ classHandle, USB_REQUEST_TYPE_DIR_IN | USB_REQUEST_TYPE_TYPE_STANDARD | USB_REQUEST_TYPE_RECIPIENT_INTERFACE,
+ USB_REQUEST_STANDARD_GET_DESCRIPTOR, 0, USB_DESCRIPTOR_TYPE_HID_REPORT, buffer_len, buffer, callbackFn,
+ callbackParam);
+}
+
+usb_status_t USB_HostHidGetIdle(usb_host_class_handle classHandle,
+ uint8_t reportId,
+ uint8_t *idleRate,
+ transfer_callback_t callbackFn,
+ void *callbackParam)
+{
+ return USB_HostHidControl(
+ classHandle, USB_REQUEST_TYPE_DIR_IN | USB_REQUEST_TYPE_TYPE_CLASS | USB_REQUEST_TYPE_RECIPIENT_INTERFACE,
+ USB_HOST_HID_GET_IDLE, reportId, 0, 1, idleRate, callbackFn, callbackParam);
+}
+
+usb_status_t USB_HostHidSetIdle(usb_host_class_handle classHandle,
+ uint8_t reportId,
+ uint8_t idleRate,
+ transfer_callback_t callbackFn,
+ void *callbackParam)
+{
+ return USB_HostHidControl(
+ classHandle, USB_REQUEST_TYPE_DIR_OUT | USB_REQUEST_TYPE_TYPE_CLASS | USB_REQUEST_TYPE_RECIPIENT_INTERFACE,
+ USB_HOST_HID_SET_IDLE, reportId, idleRate, 0, NULL, callbackFn, callbackParam);
+}
+
+usb_status_t USB_HostHidGetProtocol(usb_host_class_handle classHandle,
+ uint8_t *protocol,
+ transfer_callback_t callbackFn,
+ void *callbackParam)
+{
+ return USB_HostHidControl(
+ classHandle, USB_REQUEST_TYPE_DIR_IN | USB_REQUEST_TYPE_TYPE_CLASS | USB_REQUEST_TYPE_RECIPIENT_INTERFACE,
+ USB_HOST_HID_GET_PROTOCOL, 0, 0, 1, protocol, callbackFn, callbackParam);
+}
+
+usb_status_t USB_HostHidSetProtocol(usb_host_class_handle classHandle,
+ uint8_t protocol,
+ transfer_callback_t callbackFn,
+ void *callbackParam)
+{
+ return USB_HostHidControl(
+ classHandle, USB_REQUEST_TYPE_DIR_OUT | USB_REQUEST_TYPE_TYPE_CLASS | USB_REQUEST_TYPE_RECIPIENT_INTERFACE,
+ USB_HOST_HID_SET_PROTOCOL, protocol, 0, 0, NULL, callbackFn, callbackParam);
+}
+
+usb_status_t USB_HostHidGetReport(usb_host_class_handle classHandle,
+ uint8_t reportId,
+ uint8_t reportType,
+ uint8_t *buffer,
+ uint32_t bufferLength,
+ transfer_callback_t callbackFn,
+ void *callbackParam)
+{
+ return USB_HostHidControl(
+ classHandle, USB_REQUEST_TYPE_DIR_IN | USB_REQUEST_TYPE_TYPE_CLASS | USB_REQUEST_TYPE_RECIPIENT_INTERFACE,
+ USB_HOST_HID_GET_REPORT, reportId, reportType, bufferLength, buffer, callbackFn, callbackParam);
+}
+
+usb_status_t USB_HostHidSetReport(usb_host_class_handle classHandle,
+ uint8_t reportId,
+ uint8_t reportType,
+ uint8_t *buffer,
+ uint32_t bufferLength,
+ transfer_callback_t callbackFn,
+ void *callbackParam)
+{
+ return USB_HostHidControl(
+ classHandle, USB_REQUEST_TYPE_DIR_OUT | USB_REQUEST_TYPE_TYPE_CLASS | USB_REQUEST_TYPE_RECIPIENT_INTERFACE,
+ USB_HOST_HID_SET_REPORT, reportId, reportType, bufferLength, buffer, callbackFn, callbackParam);
+}
+
+#endif /* USB_HOST_CONFIG_HID */
diff --git a/usb_1.1.0/host/class/usb_host_hid.h b/usb_1.1.0/host/class/usb_host_hid.h
new file mode 100644
index 0000000..86e66d6
--- /dev/null
+++ b/usb_1.1.0/host/class/usb_host_hid.h
@@ -0,0 +1,411 @@
+/*
+ * Copyright (c) 2015 - 2016, Freescale Semiconductor, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * o Redistributions of source code must retain the above copyright notice, this list
+ * of conditions and the following disclaimer.
+ *
+ * o Redistributions in binary form must reproduce the above copyright notice, this
+ * list of conditions and the following disclaimer in the documentation and/or
+ * other materials provided with the distribution.
+ *
+ * o Neither the name of Freescale Semiconductor, Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _USB_HOST_HID_H_
+#define _USB_HOST_HID_H_
+
+/*******************************************************************************
+ * HID class public structure, enumerations, macros, functions
+ ******************************************************************************/
+
+/*******************************************************************************
+ * Definitions
+ ******************************************************************************/
+
+/*!
+ * @addtogroup usb_host_hid_drv
+ * @{
+ */
+
+/*! @brief HID class-specific request (get report) */
+#define USB_HOST_HID_GET_REPORT (0x01U)
+/*! @brief HID class-specific request (get idle) */
+#define USB_HOST_HID_GET_IDLE (0x02U)
+/*! @brief HID class-specific request (get protocol) */
+#define USB_HOST_HID_GET_PROTOCOL (0x03U)
+/*! @brief HID class-specific request (set report) */
+#define USB_HOST_HID_SET_REPORT (0x09U)
+/*! @brief HID class-specific request (set idle) */
+#define USB_HOST_HID_SET_IDLE (0x0AU)
+/*! @brief HID class-specific request (set protocol) */
+#define USB_HOST_HID_SET_PROTOCOL (0x0BU)
+
+/*! @brief HID class code */
+#define USB_HOST_HID_CLASS_CODE (3U)
+/*! @brief HID sub-class code */
+#define USB_HOST_HID_SUBCLASS_CODE_NONE (0U)
+/*! @brief HID sub-class code */
+#define USB_HOST_HID_SUBCLASS_CODE_BOOT (1U)
+/*! @brief HID class protocol code */
+#define USB_HOST_HID_PROTOCOL_KEYBOARD (1U)
+/*! @brief HID class protocol code */
+#define USB_HOST_HID_PROTOCOL_MOUSE (2U)
+/*! @brief HID class protocol code */
+#define USB_HOST_HID_PROTOCOL_NONE (0U)
+
+/*! @brief HID get/set protocol request data code */
+#define USB_HOST_HID_REQUEST_PROTOCOL_BOOT (0U)
+/*! @brief HID get/set protocol request data code */
+#define USB_HOST_HID_REQUEST_PROTOCOL_REPORT (1U)
+
+/*! @brief HID instance structure and HID usb_host_class_handle pointer to this structure */
+typedef struct _usb_host_hid_instance
+{
+ usb_host_handle hostHandle; /*!< This instance's related host handle*/
+ usb_device_handle deviceHandle; /*!< This instance's related device handle*/
+ usb_host_interface_handle interfaceHandle; /*!< This instance's related interface handle*/
+ usb_host_pipe_handle controlPipe; /*!< This instance's related device control pipe*/
+ usb_host_pipe_handle inPipe; /*!< HID interrupt in pipe*/
+ usb_host_pipe_handle outPipe; /*!< HID interrupt out pipe*/
+ transfer_callback_t inCallbackFn; /*!< HID interrupt in transfer callback function pointer*/
+ void *inCallbackParam; /*!< HID interrupt in transfer callback parameter*/
+ transfer_callback_t outCallbackFn; /*!< HID interrupt out transfer callback function pointer*/
+ void *outCallbackParam; /*!< HID interrupt out transfer callback parameter*/
+ transfer_callback_t controlCallbackFn; /*!< HID control transfer callback function pointer*/
+ void *controlCallbackParam; /*!< HID control transfer callback parameter*/
+ usb_host_transfer_t *controlTransfer; /*!< Ongoing control transfer*/
+#if ((defined USB_HOST_CONFIG_CLASS_AUTO_CLEAR_STALL) && USB_HOST_CONFIG_CLASS_AUTO_CLEAR_STALL)
+ uint8_t *stallDataBuffer; /*!< keep the data buffer for stall transfer's data*/
+ uint32_t stallDataLength; /*!< keep the data length for stall transfer's data*/
+#endif
+
+ uint16_t inPacketSize; /*!< HID interrupt in maximum packet size*/
+ uint16_t outPacketSize; /*!< HID interrupt out maximum packet size*/
+} usb_host_hid_instance_t;
+
+/*! @brief HID descriptor structure according to the 6.2.1 in HID specification */
+typedef struct _usb_host_hid_descriptor
+{
+ uint8_t bLength; /*!< Total size of the HID descriptor*/
+ uint8_t bDescriptorType; /*!< Constant name specifying type of HID descriptor*/
+ uint8_t bcdHID[2]; /*!< Numeric expression identifying the HID Class Specification release*/
+ uint8_t bCountryCode; /*!< Numeric expression identifying country code of the localized hardware*/
+ uint8_t bNumDescriptors; /*!< Numeric expression specifying the number of class descriptors*/
+ uint8_t bHidDescriptorType; /*!< Constant name identifying type of class descriptor*/
+ uint8_t wDescriptorLength[2]; /*!< Numeric expression that is the total size of the Report descriptor*/
+} usb_host_hid_descriptor_t;
+
+/*! @brief HID descriptor structure according to the 6.2.1 in HID specification */
+typedef struct _usb_host_hid_class_descriptor
+{
+ uint8_t bHidDescriptorType; /*!< Constant name specifying type of optional descriptor*/
+ uint8_t wDescriptorLength[2]; /*!< Numeric expression that is the total size of the optional descriptor*/
+} usb_host_hid_class_descriptor_t;
+
+/*******************************************************************************
+ * API
+ ******************************************************************************/
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*!
+ * @name USB host HID class APIs
+ * @{
+ */
+
+/*!
+ * @brief Initializes the HID instance.
+ *
+ * This function allocate the resource for the HID instance.
+ *
+ * @param[in] deviceHandle The device handle.
+ * @param[out] classHandle Return class handle.
+ *
+ * @retval kStatus_USB_Success The device is initialized successfully.
+ * @retval kStatus_USB_AllocFail Allocate memory fail.
+ */
+extern usb_status_t USB_HostHidInit(usb_device_handle deviceHandle, usb_host_class_handle *classHandle);
+
+/*!
+ * @brief Sets the interface.
+ *
+ * This function binds the interface with the HID instance.
+ *
+ * @param[in] classHandle The class handle.
+ * @param[in] interfaceHandle The interface handle.
+ * @param[in] alternateSetting The alternate setting value.
+ * @param[in] callbackFn This callback is called after this function completes.
+ * @param[in] callbackParam The first parameter in the callback function.
+ *
+ * @retval kStatus_USB_Success The device is initialized successfully.
+ * @retval kStatus_USB_InvalidHandle The classHandle is NULL pointer.
+ * @retval kStatus_USB_Busy There is no idle transfer.
+ * @retval kStatus_USB_Error Send transfer fail. See the USB_HostSendSetup.
+ * @retval kStatus_USB_Busy Callback return status, there is no idle pipe.
+ * @retval kStatus_USB_TransferStall Callback return status, the transfer is stalled by the device.
+ * @retval kStatus_USB_Error Callback return status, open pipe fail. See the USB_HostOpenPipe.
+ */
+extern usb_status_t USB_HostHidSetInterface(usb_host_class_handle classHandle,
+ usb_host_interface_handle interfaceHandle,
+ uint8_t alternateSetting,
+ transfer_callback_t callbackFn,
+ void *callbackParam);
+
+/*!
+ * @brief Deinitializes the the HID instance.
+ *
+ * This function frees the resources for the HID instance.
+ *
+ * @param[in] deviceHandle The device handle.
+ * @param[in] classHandle The class handle.
+ *
+ * @retval kStatus_USB_Success The device is de-initialized successfully.
+ */
+extern usb_status_t USB_HostHidDeinit(usb_device_handle deviceHandle, usb_host_class_handle classHandle);
+
+/*!
+ * @brief Gets the pipe maximum packet size.
+ *
+ * @param[in] classHandle The class handle.
+ * @param[in] pipeType Its value is USB_ENDPOINT_CONTROL, USB_ENDPOINT_ISOCHRONOUS, USB_ENDPOINT_BULK or
+ * USB_ENDPOINT_INTERRUPT.
+ * See the usb_spec.h
+ * @param[in] direction Pipe direction.
+ *
+ * @retval 0 The classHandle is NULL.
+ * @retval Maximum packet size.
+ */
+extern uint16_t USB_HostHidGetPacketsize(usb_host_class_handle classHandle, uint8_t pipeType, uint8_t direction);
+
+/*!
+ * @brief HID get report descriptor.
+ *
+ * This function implements the HID report descriptor request.
+ *
+ * @param[in] classHandle The class handle.
+ * @param[out] buffer The buffer pointer.
+ * @param[in] buffer_len The buffer length.
+ * @param[in] callbackFn This callback is called after this function completes.
+ * @param[in] callbackParam The first parameter in the callback function.
+ *
+ * @retval kStatus_USB_Success Request successful.
+ * @retval kStatus_USB_InvalidHandle The classHandle is NULL pointer.
+ * @retval kStatus_USB_Busy There is no idle transfer.
+ * @retval kStatus_USB_Error Send transfer fail. See the USB_HostSendSetup.
+ */
+extern usb_status_t USB_HostHidGetReportDescriptor(usb_host_class_handle classHandle,
+ uint8_t *buffer,
+ uint16_t buffer_len,
+ transfer_callback_t callbackFn,
+ void *callbackParam);
+
+/*!
+ * @brief Receives data.
+ *
+ * This function implements the HID receiving data.
+ *
+ * @param[in] classHandle The class handle.
+ * @param[out] buffer The buffer pointer.
+ * @param[in] bufferLength The buffer length.
+ * @param[in] callbackFn This callback is called after this function completes.
+ * @param[in] callbackParam The first parameter in the callback function.
+ *
+ * @retval kStatus_USB_Success Receive request successfully.
+ * @retval kStatus_USB_InvalidHandle The classHandle is NULL pointer.
+ * @retval kStatus_USB_Busy There is no idle transfer.
+ * @retval kStatus_USB_Error Pipe is not initialized.
+ * Or, send transfer fail. See the USB_HostRecv.
+ */
+extern usb_status_t USB_HostHidRecv(usb_host_class_handle classHandle,
+ uint8_t *buffer,
+ uint32_t bufferLength,
+ transfer_callback_t callbackFn,
+ void *callbackParam);
+
+/*!
+ * @brief Sends data.
+ *
+ * This function implements the HID sending data.
+ *
+ * @param[in] classHandle The class handle.
+ * @param[in] buffer The buffer pointer.
+ * @param[in] bufferLength The buffer length.
+ * @param[in] callbackFn This callback is called after this function completes.
+ * @param[in] callbackParam The first parameter in the callback function.
+ *
+ * @retval kStatus_USB_Success Send request successfully.
+ * @retval kStatus_USB_InvalidHandle The classHandle is NULL pointer.
+ * @retval kStatus_USB_Busy There is no idle transfer.
+ * @retval kStatus_USB_Error Pipe is not initialized.
+ * Or, send transfer fail. See the USB_HostSend.
+ */
+extern usb_status_t USB_HostHidSend(usb_host_class_handle classHandle,
+ uint8_t *buffer,
+ uint32_t bufferLength,
+ transfer_callback_t callbackFn,
+ void *callbackParam);
+
+/*!
+ * @brief HID get idle.
+ *
+ * This function implements the HID class-specific request (get idle).
+ *
+ * @param[in] classHandle The class handle.
+ * @param[in] reportId Report ID.
+ * @param[out] idleRate Return idle rate value.
+ * @param[in] callbackFn This callback is called after this function completes.
+ * @param[in] callbackParam The first parameter in the callback function.
+ *
+ * @retval kStatus_USB_Success Request successful.
+ * @retval kStatus_USB_InvalidHandle The classHandle is NULL pointer.
+ * @retval kStatus_USB_Busy There is no idle transfer.
+ * @retval kStatus_USB_Error Send transfer fail. See the USB_HostSendSetup.
+ */
+extern usb_status_t USB_HostHidGetIdle(usb_host_class_handle classHandle,
+ uint8_t reportId,
+ uint8_t *idleRate,
+ transfer_callback_t callbackFn,
+ void *callbackParam);
+
+/*!
+ * @brief HID set idle.
+ *
+ * This function implements the HID class-specific request (set idle).
+ *
+ * @param[in] classHandle The class handle.
+ * @param[in] reportId Report ID.
+ * @param[in] idleRate Idle rate value.
+ * @param[in] callbackFn This callback is called after this function completes.
+ * @param[in] callbackParam The first parameter in the callback function.
+ *
+ * @retval kStatus_USB_Success Request successful.
+ * @retval kStatus_USB_InvalidHandle The classHandle is NULL pointer.
+ * @retval kStatus_USB_Busy There is no idle transfer.
+ * @retval kStatus_USB_Error Send transfer fail. See the USB_HostSendSetup.
+ */
+extern usb_status_t USB_HostHidSetIdle(usb_host_class_handle classHandle,
+ uint8_t reportId,
+ uint8_t idleRate,
+ transfer_callback_t callbackFn,
+ void *callbackParam);
+
+/*!
+ * @brief HID get protocol.
+ *
+ * This function implements the HID class-specific request (get protocol).
+ *
+ * @param[in] classHandle The class handle.
+ * @param[out] protocol Return protocol value.
+ * @param[in] callbackFn This callback is called after this function completes.
+ * @param[in] callbackParam The first parameter in the callback function.
+ *
+ * @retval kStatus_USB_Success Request successful.
+ * @retval kStatus_USB_InvalidHandle The classHandle is NULL pointer.
+ * @retval kStatus_USB_Busy There is no idle transfer.
+ * @retval kStatus_USB_Error Send transfer fail. See the USB_HostSendSetup.
+ */
+extern usb_status_t USB_HostHidGetProtocol(usb_host_class_handle classHandle,
+ uint8_t *protocol,
+ transfer_callback_t callbackFn,
+ void *callbackParam);
+
+/*!
+ * @brief HID set protocol.
+ *
+ * This function implements the HID class-specific request (set protocol).
+ *
+ * @param[in] classHandle The class handle.
+ * @param[in] protocol Protocol value.
+ * @param[in] callbackFn This callback is called after this function completes.
+ * @param[in] callbackParam The first parameter in the callback function.
+ *
+ * @retval kStatus_USB_Success Request successful.
+ * @retval kStatus_USB_InvalidHandle The classHandle is NULL pointer.
+ * @retval kStatus_USB_Busy There is no idle transfer.
+ * @retval kStatus_USB_Error Send transfer fail. See the USB_HostSendSetup.
+ */
+extern usb_status_t USB_HostHidSetProtocol(usb_host_class_handle classHandle,
+ uint8_t protocol,
+ transfer_callback_t callbackFn,
+ void *callbackParam);
+
+/*!
+ * @brief HID get report.
+ *
+ * This function implements the HID class-specific request (get report).
+ *
+ * @param[in] classHandle The class handle.
+ * @param[in] reportId Report ID.
+ * @param[in] reportType Report type.
+ * @param[out] buffer The buffer pointer.
+ * @param[in] bufferLength The buffer length.
+ * @param[in] callbackFn This callback is called after this function completes.
+ * @param[in] callbackParam The first parameter in the callback function.
+ *
+ * @retval kStatus_USB_Success Request successful.
+ * @retval kStatus_USB_InvalidHandle The classHandle is NULL pointer.
+ * @retval kStatus_USB_Busy There is no idle transfer.
+ * @retval kStatus_USB_Error Send transfer fail. See the USB_HostSendSetup.
+ */
+extern usb_status_t USB_HostHidGetReport(usb_host_class_handle classHandle,
+ uint8_t reportId,
+ uint8_t reportType,
+ uint8_t *buffer,
+ uint32_t bufferLength,
+ transfer_callback_t callbackFn,
+ void *callbackParam);
+
+/*!
+ * @brief HID set report.
+ *
+ * This function implements the HID class-specific request (set report).
+ *
+ * @param[in] classHandle The class handle.
+ * @param[in] reportId Report ID.
+ * @param[in] reportType Report type.
+ * @param[in] buffer The buffer pointer.
+ * @param[in] bufferLength The buffer length.
+ * @param[in] callbackFn This callback is called after this function completes.
+ * @param[in] callbackParam The first parameter in the callback function.
+ *
+ * @retval kStatus_USB_Success Request successful.
+ * @retval kStatus_USB_InvalidHandle The classHandle is NULL pointer.
+ * @retval kStatus_USB_Busy There is no idle transfer.
+ * @retval kStatus_USB_Error Send transfer fail. See the USB_HostSendSetup.
+ */
+extern usb_status_t USB_HostHidSetReport(usb_host_class_handle classHandle,
+ uint8_t reportId,
+ uint8_t reportType,
+ uint8_t *buffer,
+ uint32_t bufferLength,
+ transfer_callback_t callbackFn,
+ void *callbackParam);
+
+/*! @}*/
+
+#ifdef __cplusplus
+}
+#endif
+
+/*! @}*/
+
+#endif /* _USB_HOST_HID_H_ */
diff --git a/usb_1.1.0/host/class/usb_host_hub.c b/usb_1.1.0/host/class/usb_host_hub.c
new file mode 100644
index 0000000..1200770
--- /dev/null
+++ b/usb_1.1.0/host/class/usb_host_hub.c
@@ -0,0 +1,612 @@
+/*
+ * Copyright (c) 2015 - 2016, Freescale Semiconductor, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * o Redistributions of source code must retain the above copyright notice, this list
+ * of conditions and the following disclaimer.
+ *
+ * o Redistributions in binary form must reproduce the above copyright notice, this
+ * list of conditions and the following disclaimer in the documentation and/or
+ * other materials provided with the distribution.
+ *
+ * o Neither the name of Freescale Semiconductor, Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "usb_host_config.h"
+#if ((defined USB_HOST_CONFIG_HUB) && (USB_HOST_CONFIG_HUB))
+#include "usb_host.h"
+#include "usb_host_hub.h"
+
+/*******************************************************************************
+ * Definitions
+ ******************************************************************************/
+
+/*******************************************************************************
+ * Prototypes
+ ******************************************************************************/
+/*!
+ * @brief hub control transfer callback.
+ *
+ * @param param callback parameter.
+ * @param transfer callback transfer.
+ * @param status transfer status.
+ */
+static void USB_HostHubControlCallback(void *param, usb_host_transfer_t *transfer, usb_status_t status);
+
+/*!
+ * @brief hub interrupt in transfer callback.
+ *
+ * @param param callback parameter.
+ * @param transfer callback transfer.
+ * @param status transfer status.
+ */
+static void USB_HostHubInPipeCallback(void *param, usb_host_transfer_t *transfer, usb_status_t status);
+
+/*!
+ * @brief USB_HostHubSendPortReset's transfer callback.
+ *
+ * @param param callback parameter.
+ * @param transfer callback transfer.
+ * @param status transfer status.
+ */
+static void USB_HostHubResetCallback(void *param, usb_host_transfer_t *transfer, usb_status_t status);
+
+/*!
+ * @brief hub control transfer common code.
+ *
+ * @param classHandle the class handle.
+ * @param requestType request type.
+ * @param request setup packet request field.
+ * @param wvalue setup packet wValue field.
+ * @param windex setup packet wIndex field.
+ * @param buffer the buffer pointer.
+ * @param bufferLength the buffer length.
+ * @param callbackFn this callback is called after this function completes.
+ * @param callbackParam the first parameter in the callback function.
+ *
+ * @return kStatus_USB_Success or error codes.
+ */
+static usb_status_t USB_HostHubClassRequestCommon(usb_host_class_handle classHandle,
+ uint8_t requestType,
+ uint8_t request,
+ uint16_t wvalue,
+ uint16_t windex,
+ uint8_t *buffer,
+ uint16_t bufferLength,
+ transfer_callback_t callbackFn,
+ void *callbackParam);
+
+/*******************************************************************************
+ * Variables
+ ******************************************************************************/
+
+/*******************************************************************************
+ * Code
+ ******************************************************************************/
+
+static void USB_HostHubControlCallback(void *param, usb_host_transfer_t *transfer, usb_status_t status)
+{
+ usb_host_hub_instance_t *hubInstance = (usb_host_hub_instance_t *)param;
+
+ hubInstance->controlTransfer = NULL;
+ if (hubInstance->controlCallbackFn)
+ {
+ hubInstance->controlCallbackFn(hubInstance->controlCallbackParam, transfer->transferBuffer,
+ transfer->transferSofar, status); /* callback to application */
+ }
+ USB_HostFreeTransfer(hubInstance->hostHandle, transfer);
+}
+
+static void USB_HostHubInPipeCallback(void *param, usb_host_transfer_t *transfer, usb_status_t status)
+{
+ usb_host_hub_instance_t *hubInstance = (usb_host_hub_instance_t *)param;
+
+ if (hubInstance->inCallbackFn)
+ {
+ hubInstance->inCallbackFn(hubInstance->inCallbackParam, transfer->transferBuffer, transfer->transferSofar,
+ status); /* callback to application */
+ }
+ USB_HostFreeTransfer(hubInstance->hostHandle, transfer);
+}
+
+static void USB_HostHubResetCallback(void *param, usb_host_transfer_t *transfer, usb_status_t status)
+{
+ usb_host_hub_instance_t *hubInstance = (usb_host_hub_instance_t *)param;
+
+ /* note: there is not callback to application, the re-enumeration will start automatically after reset. */
+ USB_HostFreeTransfer(hubInstance->hostHandle, transfer);
+}
+
+static usb_status_t USB_HostHubClassRequestCommon(usb_host_class_handle classHandle,
+ uint8_t requestType,
+ uint8_t request,
+ uint16_t wvalue,
+ uint16_t windex,
+ uint8_t *buffer,
+ uint16_t bufferLength,
+ transfer_callback_t callbackFn,
+ void *callbackParam)
+{
+ usb_host_hub_instance_t *hubInstance = (usb_host_hub_instance_t *)classHandle;
+ usb_host_transfer_t *transfer;
+
+ if (hubInstance->controlTransfer != NULL)
+ {
+ return kStatus_USB_Busy;
+ }
+
+ /* get transfer */
+ if (USB_HostMallocTransfer(hubInstance->hostHandle, &transfer) != kStatus_USB_Success)
+ {
+#ifdef HOST_ECHO
+ usb_echo("error to get transfer\r\n");
+#endif
+ return kStatus_USB_Error;
+ }
+
+ /* save hub application callback */
+ hubInstance->controlCallbackFn = callbackFn;
+ hubInstance->controlCallbackParam = callbackParam;
+
+ /* initialize transfer */
+ transfer->transferBuffer = buffer;
+ transfer->transferLength = bufferLength;
+ transfer->callbackFn = USB_HostHubControlCallback;
+ transfer->callbackParam = hubInstance;
+ transfer->setupPacket.bmRequestType = requestType;
+ transfer->setupPacket.bRequest = request;
+ transfer->setupPacket.wValue = USB_SHORT_TO_LITTLE_ENDIAN(wvalue);
+ transfer->setupPacket.wIndex = USB_SHORT_TO_LITTLE_ENDIAN(windex);
+ transfer->setupPacket.wLength = USB_SHORT_TO_LITTLE_ENDIAN(bufferLength);
+
+ /* send transfer */
+ if (USB_HostSendSetup(hubInstance->hostHandle, hubInstance->controlPipe, transfer) != kStatus_USB_Success)
+ {
+#ifdef HOST_ECHO
+ usb_echo("Error in hid get report descriptor\r\n");
+#endif
+ USB_HostFreeTransfer(hubInstance->hostHandle, transfer);
+ return kStatus_USB_Error;
+ }
+ hubInstance->controlTransfer = transfer; /* record the on-going setup transfer */
+ return kStatus_USB_Success;
+}
+
+usb_status_t USB_HostHubInit(usb_device_handle deviceHandle, usb_host_class_handle *classHandle)
+{
+ /* malloc the hub instance */
+ usb_host_hub_instance_t *hubInstance =
+ (usb_host_hub_instance_t *)USB_OsaMemoryAllocate(sizeof(usb_host_hub_instance_t));
+ uint32_t infoValue;
+
+ if (hubInstance == NULL)
+ {
+ return kStatus_USB_AllocFail;
+ }
+
+ /* initialize hub instance structure */
+ hubInstance->deviceHandle = deviceHandle;
+ hubInstance->interfaceHandle = NULL;
+ USB_HostHelperGetPeripheralInformation(deviceHandle, kUSB_HostGetHostHandle, &infoValue);
+ hubInstance->hostHandle = (usb_host_handle)infoValue;
+ USB_HostHelperGetPeripheralInformation(deviceHandle, kUSB_HostGetDeviceControlPipe, &infoValue);
+ hubInstance->controlPipe = (usb_host_pipe_handle)infoValue;
+ USB_HostHelperGetPeripheralInformation(deviceHandle, kUSB_HostGetDeviceLevel, &infoValue);
+ hubInstance->hubLevel = infoValue;
+
+ *classHandle = hubInstance; /* return the hub class handle */
+ return kStatus_USB_Success;
+}
+
+usb_status_t USB_HostHubSetInterface(usb_host_class_handle classHandle,
+ usb_host_interface_handle interfaceHandle,
+ uint8_t alternateSetting,
+ transfer_callback_t callbackFn,
+ void *callbackParam)
+{
+ usb_status_t status;
+ usb_host_hub_instance_t *hubInstance = (usb_host_hub_instance_t *)classHandle;
+ usb_host_interface_t *interface = (usb_host_interface_t *)interfaceHandle;
+ usb_descriptor_endpoint_t *epDesc = NULL;
+ usb_host_pipe_init_t pipeInit;
+ uint8_t epIndex;
+
+ if (classHandle == NULL)
+ {
+ return kStatus_USB_InvalidHandle;
+ }
+
+ hubInstance->interfaceHandle = interfaceHandle; /* save the interface handle */
+
+ /* notify the host driver that the interface is used by class */
+ status = USB_HostOpenDeviceInterface(hubInstance->deviceHandle, interfaceHandle);
+ if (status != kStatus_USB_Success)
+ {
+ return status;
+ }
+
+ /* close opened hub interrupt pipe */
+ if (hubInstance->interruptPipe != NULL)
+ {
+ status = USB_HostCancelTransfer(hubInstance->hostHandle, hubInstance->interruptPipe, NULL);
+ status = USB_HostClosePipe(hubInstance->hostHandle, hubInstance->interruptPipe);
+ if (status != kStatus_USB_Success)
+ {
+#ifdef HOST_ECHO
+ usb_echo("error when close pipe\r\n");
+#endif
+ }
+ hubInstance->interruptPipe = NULL;
+ }
+
+ /* open hub interrupt pipe */
+ for (epIndex = 0; epIndex < interface->epCount; ++epIndex)
+ {
+ epDesc = interface->epList[epIndex].epDesc;
+ if (((epDesc->bEndpointAddress & USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_MASK) ==
+ USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_IN) &&
+ ((epDesc->bmAttributes & USB_DESCRIPTOR_ENDPOINT_ATTRIBUTE_TYPE_MASK) == USB_ENDPOINT_INTERRUPT))
+ {
+ /* get pipe information from endpoint descriptor */
+ pipeInit.devInstance = hubInstance->deviceHandle;
+ pipeInit.pipeType = USB_ENDPOINT_INTERRUPT;
+ pipeInit.direction = USB_IN;
+ pipeInit.endpointAddress = (epDesc->bEndpointAddress & USB_DESCRIPTOR_ENDPOINT_ADDRESS_NUMBER_MASK);
+ pipeInit.interval = epDesc->bInterval;
+ pipeInit.maxPacketSize = (uint16_t)(USB_SHORT_FROM_LITTLE_ENDIAN_ADDRESS(epDesc->wMaxPacketSize) &
+ USB_DESCRIPTOR_ENDPOINT_MAXPACKETSIZE_SIZE_MASK);
+ pipeInit.numberPerUframe = (USB_SHORT_FROM_LITTLE_ENDIAN_ADDRESS(epDesc->wMaxPacketSize) &
+ USB_DESCRIPTOR_ENDPOINT_MAXPACKETSIZE_MULT_TRANSACTIONS_MASK);
+ pipeInit.nakCount = USB_HOST_CONFIG_MAX_NAK;
+
+ /* open hub interrupt in pipe */
+ status = USB_HostOpenPipe(hubInstance->hostHandle, &hubInstance->interruptPipe, &pipeInit);
+ if (status != kStatus_USB_Success)
+ {
+#ifdef HOST_ECHO
+ usb_echo("usb_host_hid_set_interface fail to open pipe\r\n");
+#endif
+ return kStatus_USB_Error;
+ }
+ break;
+ }
+ }
+
+ /* hub don't support alternatesetting that is not 0 */
+ if (alternateSetting == 0)
+ {
+ if (callbackFn != NULL)
+ {
+ callbackFn(callbackParam, NULL, 0, kStatus_USB_Success);
+ }
+ }
+ else
+ {
+#ifdef HOST_ECHO
+ usb_echo("host don't supprt alternate setting\r\n");
+#endif
+ return kStatus_USB_Error;
+ }
+
+ return status;
+}
+
+usb_status_t USB_HostHubDeinit(usb_device_handle deviceHandle, usb_host_class_handle classHandle)
+{
+ usb_host_hub_instance_t *hubInstance = (usb_host_hub_instance_t *)classHandle;
+ uint8_t status;
+ if (deviceHandle == NULL)
+ {
+ return kStatus_USB_InvalidHandle;
+ }
+
+ if (classHandle != NULL)
+ {
+ /* close opened hub interrupt pipe */
+ if (hubInstance->interruptPipe != NULL)
+ {
+ status = USB_HostCancelTransfer(hubInstance->hostHandle, hubInstance->interruptPipe, NULL);
+ status = USB_HostClosePipe(hubInstance->hostHandle, hubInstance->interruptPipe);
+ if (status != kStatus_USB_Success)
+ {
+#ifdef HOST_ECHO
+ usb_echo("hub close interrupt pipe error\r\n");
+#endif
+ }
+ hubInstance->interruptPipe = NULL;
+ }
+
+ /* cancel control transfer if exist */
+ if ((hubInstance->controlPipe != NULL) && (hubInstance->controlTransfer != NULL))
+ {
+ status =
+ USB_HostCancelTransfer(hubInstance->hostHandle, hubInstance->controlPipe, hubInstance->controlTransfer);
+ }
+
+ /* notify host driver that the interface will not be used */
+ USB_HostCloseDeviceInterface(deviceHandle, hubInstance->interfaceHandle);
+ USB_OsaMemoryFree(hubInstance);
+ }
+ else
+ {
+ /* notify host driver that the interface will not be used */
+ USB_HostCloseDeviceInterface(deviceHandle, NULL);
+ }
+
+ return kStatus_USB_Success;
+}
+
+usb_status_t USB_HostHubInterruptRecv(usb_host_class_handle classHandle,
+ uint8_t *buffer,
+ uint16_t bufferLength,
+ transfer_callback_t callbackFn,
+ void *callbackParam)
+{
+ usb_host_hub_instance_t *hubInstance = (usb_host_hub_instance_t *)classHandle;
+ usb_host_transfer_t *transfer;
+
+ if (classHandle == NULL)
+ {
+ return kStatus_USB_InvalidHandle;
+ }
+
+ /* get transfer */
+ if (USB_HostMallocTransfer(hubInstance->hostHandle, &transfer) != kStatus_USB_Success)
+ {
+#ifdef HOST_ECHO
+ usb_echo("error to get transfer\r\n");
+#endif
+ return kStatus_USB_Error;
+ }
+
+ /* save hub application callback */
+ hubInstance->inCallbackFn = callbackFn;
+ hubInstance->inCallbackParam = callbackParam;
+
+ /* initialize transfer */
+ transfer->transferBuffer = buffer;
+ transfer->transferLength = bufferLength;
+ transfer->callbackFn = USB_HostHubInPipeCallback;
+ transfer->callbackParam = hubInstance;
+
+ /* call host driver API to receive data */
+ if (USB_HostRecv(hubInstance->hostHandle, hubInstance->interruptPipe, transfer) != kStatus_USB_Success)
+ {
+#ifdef HOST_ECHO
+ usb_echo("failt to USB_HostRecv\r\n");
+#endif
+ USB_HostFreeTransfer(hubInstance->hostHandle, transfer);
+ return kStatus_USB_Error;
+ }
+
+ return kStatus_USB_Success;
+}
+
+usb_status_t USB_HostHubSendPortReset(usb_host_class_handle classHandle, uint8_t portNumber)
+{
+ usb_host_hub_instance_t *hubInstance = (usb_host_hub_instance_t *)classHandle;
+ usb_host_transfer_t *transfer;
+
+ if (classHandle == NULL)
+ {
+ return kStatus_USB_InvalidHandle;
+ }
+
+ /* get transfer */
+ if (USB_HostMallocTransfer(hubInstance->hostHandle, &transfer) != kStatus_USB_Success)
+ {
+#ifdef HOST_ECHO
+ usb_echo("error to get transfer\r\n");
+#endif
+ return kStatus_USB_Busy;
+ }
+
+ /* initialize transfer */
+ transfer->transferBuffer = NULL;
+ transfer->transferLength = 0;
+ transfer->callbackFn = USB_HostHubResetCallback;
+ transfer->callbackParam = hubInstance;
+ transfer->setupPacket.bmRequestType =
+ USB_REQUEST_TYPE_DIR_OUT | USB_REQUEST_TYPE_TYPE_CLASS | USB_REQUEST_TYPE_RECIPIENT_OTHER;
+ transfer->setupPacket.bRequest = USB_REQUEST_STANDARD_SET_FEATURE;
+ transfer->setupPacket.wValue = USB_SHORT_TO_LITTLE_ENDIAN(PORT_RESET);
+ transfer->setupPacket.wIndex = USB_SHORT_TO_LITTLE_ENDIAN(portNumber);
+ transfer->setupPacket.wLength = 0;
+
+ /* send the transfer */
+ if (USB_HostSendSetup(hubInstance->hostHandle, hubInstance->controlPipe, transfer) != kStatus_USB_Success)
+ {
+#ifdef HOST_ECHO
+ usb_echo("Error in hid get report descriptor\r\n");
+#endif
+ USB_HostFreeTransfer(hubInstance->hostHandle, transfer);
+ return kStatus_USB_Error;
+ }
+ return kStatus_USB_Success;
+}
+
+/*!
+ * @brief hub get descriptor.
+ *
+ * This function implements get hub descriptor specific request.
+ *
+ * @param classHandle the class handle.
+ * @param buffer the buffer pointer.
+ * @param bufferLength the buffer length.
+ * @param callbackFn this callback is called after this function completes.
+ * @param callbackParam the first parameter in the callback function.
+ *
+ * @retval kStatus_USB_Success send successfully.
+ * @retval kStatus_USB_InvalidHandle The classHandle is NULL pointer.
+ * @retval kStatus_USB_Busy There is no idle transfer.
+ * @retval kStatus_USB_Error pipe is not initialized.
+ * Or, send transfer fail, please reference to USB_HostSendSetup.
+ */
+usb_status_t USB_HostHubGetDescriptor(usb_host_class_handle classHandle,
+ uint8_t *buffer,
+ uint16_t bufferLength,
+ transfer_callback_t callbackFn,
+ void *callbackParam)
+{
+ return USB_HostHubClassRequestCommon(
+ classHandle, USB_REQUEST_TYPE_DIR_IN | USB_REQUEST_TYPE_TYPE_CLASS | USB_REQUEST_TYPE_RECIPIENT_DEVICE,
+ USB_REQUEST_STANDARD_GET_DESCRIPTOR, 0x00, 0, buffer, bufferLength, callbackFn, callbackParam);
+}
+
+/*!
+ * @brief hub clear feature.
+ *
+ * This function implements clear hub feature specific request.
+ *
+ * @param classHandle the class handle.
+ * @param buffer the buffer pointer.
+ * @param bufferLength the buffer length.
+ * @param callbackFn this callback is called after this function completes.
+ * @param callbackParam the first parameter in the callback function.
+ *
+ * @retval kStatus_USB_Success send successfully.
+ * @retval kStatus_USB_InvalidHandle The classHandle is NULL pointer.
+ * @retval kStatus_USB_Busy There is no idle transfer.
+ * @retval kStatus_USB_Error pipe is not initialized.
+ * Or, send transfer fail, please reference to USB_HostSendSetup.
+ */
+usb_status_t USB_HostHubClearFeature(usb_host_class_handle classHandle,
+ uint8_t feature,
+ transfer_callback_t callbackFn,
+ void *callbackParam)
+{
+ return USB_HostHubClassRequestCommon(classHandle, USB_REQUEST_TYPE_DIR_OUT | USB_REQUEST_TYPE_TYPE_CLASS,
+ USB_REQUEST_STANDARD_CLEAR_FEATURE, feature, 0, NULL, 0, callbackFn,
+ callbackParam);
+}
+
+/*!
+ * @brief hub get status.
+ *
+ * This function implements get hub status specific request.
+ *
+ * @param classHandle the class handle.
+ * @param buffer the buffer pointer.
+ * @param bufferLength the buffer length.
+ * @param callbackFn this callback is called after this function completes.
+ * @param callbackParam the first parameter in the callback function.
+ *
+ * @retval kStatus_USB_Success send successfully.
+ * @retval kStatus_USB_InvalidHandle The classHandle is NULL pointer.
+ * @retval kStatus_USB_Busy There is no idle transfer.
+ * @retval kStatus_USB_Error pipe is not initialized.
+ * Or, send transfer fail, please reference to USB_HostSendSetup.
+ */
+usb_status_t USB_HostHubGetStatus(usb_host_class_handle classHandle,
+ uint8_t *buffer,
+ uint16_t bufferLength,
+ transfer_callback_t callbackFn,
+ void *callbackParam)
+{
+ return USB_HostHubClassRequestCommon(classHandle, USB_REQUEST_TYPE_DIR_IN | USB_REQUEST_TYPE_TYPE_CLASS,
+ USB_REQUEST_STANDARD_GET_STATUS, 0, 0, buffer, bufferLength, callbackFn,
+ callbackParam);
+}
+
+/*!
+ * @brief hub set feature.
+ *
+ * This function implements set hub feature specific request.
+ *
+ * @param classHandle the class handle.
+ * @param buffer the buffer pointer.
+ * @param bufferLength the buffer length.
+ * @param callbackFn this callback is called after this function completes.
+ * @param callbackParam the first parameter in the callback function.
+ *
+ * @retval kStatus_USB_Success send successfully.
+ * @retval kStatus_USB_InvalidHandle The classHandle is NULL pointer.
+ * @retval kStatus_USB_Busy There is no idle transfer.
+ * @retval kStatus_USB_Error pipe is not initialized.
+ * Or, send transfer fail, please reference to USB_HostSendSetup.
+ */
+usb_status_t USB_HostHubSetPortFeature(usb_host_class_handle classHandle,
+ uint8_t portNumber,
+ uint8_t feature,
+ transfer_callback_t callbackFn,
+ void *callbackParam)
+{
+ return USB_HostHubClassRequestCommon(
+ classHandle, USB_REQUEST_TYPE_DIR_OUT | USB_REQUEST_TYPE_TYPE_CLASS | USB_REQUEST_TYPE_RECIPIENT_OTHER,
+ USB_REQUEST_STANDARD_SET_FEATURE, feature, portNumber, NULL, 0, callbackFn, callbackParam);
+}
+
+/*!
+ * @brief hub clear port feature.
+ *
+ * This function implements clear hub port feature specific request.
+ *
+ * @param classHandle the class handle.
+ * @param buffer the buffer pointer.
+ * @param bufferLength the buffer length.
+ * @param callbackFn this callback is called after this function completes.
+ * @param callbackParam the first parameter in the callback function.
+ *
+ * @retval kStatus_USB_Success send successfully.
+ * @retval kStatus_USB_InvalidHandle The classHandle is NULL pointer.
+ * @retval kStatus_USB_Busy There is no idle transfer.
+ * @retval kStatus_USB_Error pipe is not initialized.
+ * Or, send transfer fail, please reference to USB_HostSendSetup.
+ */
+usb_status_t USB_HostHubClearPortFeature(usb_host_class_handle classHandle,
+ uint8_t portNumber,
+ uint8_t feature,
+ transfer_callback_t callbackFn,
+ void *callbackParam)
+{
+ return USB_HostHubClassRequestCommon(
+ classHandle, USB_REQUEST_TYPE_DIR_OUT | USB_REQUEST_TYPE_TYPE_CLASS | USB_REQUEST_TYPE_RECIPIENT_OTHER,
+ USB_REQUEST_STANDARD_CLEAR_FEATURE, feature, portNumber, NULL, 0, callbackFn, callbackParam);
+}
+
+/*!
+ * @brief hub port get status.
+ *
+ * This function implements get hub port status specific request.
+ *
+ * @param classHandle the class handle.
+ * @param buffer the buffer pointer.
+ * @param bufferLength the buffer length.
+ * @param callbackFn this callback is called after this function completes.
+ * @param callbackParam the first parameter in the callback function.
+ *
+ * @retval kStatus_USB_Success send successfully.
+ * @retval kStatus_USB_InvalidHandle The classHandle is NULL pointer.
+ * @retval kStatus_USB_Busy There is no idle transfer.
+ * @retval kStatus_USB_Error pipe is not initialized.
+ * Or, send transfer fail, please reference to USB_HostSendSetup.
+ */
+usb_status_t USB_HostHubGetPortStatus(usb_host_class_handle classHandle,
+ uint8_t portNumber,
+ uint8_t *buffer,
+ uint16_t bufferLength,
+ transfer_callback_t callbackFn,
+ void *callbackParam)
+{
+ return USB_HostHubClassRequestCommon(
+ classHandle, USB_REQUEST_TYPE_DIR_IN | USB_REQUEST_TYPE_TYPE_CLASS | USB_REQUEST_TYPE_RECIPIENT_OTHER,
+ USB_REQUEST_STANDARD_GET_STATUS, 0, portNumber, buffer, bufferLength, callbackFn, callbackParam);
+}
+
+#endif /* USB_HOST_CONFIG_HUB */
diff --git a/usb_1.1.0/host/class/usb_host_hub.h b/usb_1.1.0/host/class/usb_host_hub.h
new file mode 100644
index 0000000..4ea3700
--- /dev/null
+++ b/usb_1.1.0/host/class/usb_host_hub.h
@@ -0,0 +1,390 @@
+/*
+ * Copyright (c) 2015, Freescale Semiconductor, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * o Redistributions of source code must retain the above copyright notice, this list
+ * of conditions and the following disclaimer.
+ *
+ * o Redistributions in binary form must reproduce the above copyright notice, this
+ * list of conditions and the following disclaimer in the documentation and/or
+ * other materials provided with the distribution.
+ *
+ * o Neither the name of Freescale Semiconductor, Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _USB_HOST_HUB_H_
+#define _USB_HSOT_HUB_H_
+
+#if ((defined USB_HOST_CONFIG_HUB) && (USB_HOST_CONFIG_HUB))
+
+/*******************************************************************************
+ * Definitions
+ ******************************************************************************/
+
+/*! @brief USB host HUB maximum port count */
+#define USB_HOST_HUB_MAX_PORT (7U)
+
+/*! @brief HUB class code */
+#define USB_HOST_HUB_CLASS_CODE (9U)
+/*! @brief HUB sub-class code */
+#define USB_HOST_HUB_SUBCLASS_CODE_NONE (0U)
+
+/* HUB and PORT status according to Table 11-17 in chapter 11.*/
+/*! @brief Local Power Status Change: This field indicates that a change has occurred in the HUB's Local Power Source */
+#define C_HUB_LOCAL_POWER (0U)
+/*! @brief Over-Current Change: This field indicates if a change has occurred in the Over-Current field*/
+#define C_HUB_OVER_CURRENT (1U)
+/*! @brief Current Connect Status: This field reflects whether or not a device is currently connected to this port*/
+#define PORT_CONNECTION (0U)
+/*! @brief Port Enabled/Disabled: Ports can be enabled by the USB System Software only. Ports
+can be disabled by either a fault condition (disconnect event or other fault condition) or by the USB System
+Software*/
+#define PORT_ENABLE (1U)
+/*! @brief Suspend: This field indicates whether or not the device on this port is suspended */
+#define PORT_SUSPEND (2U)
+/*! @brief this field indicate that the current drain on the port exceeds the specified maximum. */
+#define PORT_OVER_CURRENT (3U)
+/*! @brief This field is set when the host wishes to reset the attached device */
+#define PORT_RESET (4U)
+/*! @brief This field reflects a port's logical, power control state */
+#define PORT_POWER (8U)
+/*! @brief Low- Speed Device Attached: This is relevant only if a device is attached */
+#define PORT_LOW_SPEED (9U)
+/*! @brief High-speed Device Attached: This is relevant only if a device is attached */
+#define PORT_HIGH_SPEED (10U)
+/*! @brief Connect Status Change: Indicates a change has occurred in the port's Current Connect Status */
+#define C_PORT_CONNECTION (16U)
+/*! @brief Port Enable/Disable Change: This field is set to one when a port is disabled because of a Port_Error
+ * condition */
+#define C_PORT_ENABLE (17U)
+/*! @brief Suspend Change: This field indicates a change in the host-visible suspend state of the attached device */
+#define C_PORT_SUSPEND (18U)
+/*! @brief Over-Current Indicator Change: This field applies only to HUBs that report over-current conditions on a
+ * per-port basis */
+#define C_PORT_OVER_CURRENT (19U)
+/*! @brief Reset Change: This field is set when reset processing on this port is complete */
+#define C_PORT_RESET (20U)
+
+/*! @brief Get HUB think time value */
+#define USB_HOST_HUB_DESCRIPTOR_CHARACTERISTICS_THINK_TIME_MASK (0x60U)
+/*! @brief Get HUB think time value */
+#define USB_HOST_HUB_DESCRIPTOR_CHARACTERISTICS_THINK_TIME_SHIFT (5U)
+
+/*******************************************************************************
+ * Prototypes
+ ******************************************************************************/
+
+/*! @brief HUB descriptor structure */
+typedef struct _usb_host_hub_descriptor
+{
+ uint8_t blength; /*!< Number of bytes in this descriptor*/
+ uint8_t bdescriptortype; /*!< Descriptor Type*/
+ uint8_t bnrports; /*!< Number of downstream facing ports that this HUB supports*/
+ uint8_t whubcharacteristics[2]; /*!< HUB characteristics please reference to Table 11-13 in usb2.0 specification*/
+ uint8_t bpwron2pwrgood; /*!< Time (in 2 ms intervals) from the time the power-on sequence begins on a port until
+ power is good on that port.*/
+ uint8_t bhubcontrcurrent; /*!< Maximum current requirements of the HUB Controller electronics in mA*/
+ uint8_t deviceremovable; /*!< Indicates if a port has a removable device attached*/
+} usb_host_hub_descriptor_t;
+
+/*! @brief HUB port instance structure */
+typedef struct _usb_host_hub_port_instance
+{
+ usb_device_handle deviceHandle; /*!< Device handle*/
+ uint8_t portStatus; /*!< Port running status*/
+ uint8_t resetCount; /*!< Port reset time*/
+ uint8_t speed; /*!< Port's device speed*/
+} usb_host_hub_port_instance_t;
+
+/*! @brief HUB instance structure */
+typedef struct _usb_host_hub_instance
+{
+ struct _usb_host_hub_instance *next; /*!< Next HUB instance*/
+ usb_host_handle hostHandle; /*!< Host handle*/
+ usb_device_handle deviceHandle; /*!< Device handle*/
+ usb_host_interface_handle interfaceHandle; /*!< Interface handle*/
+ usb_host_pipe_handle controlPipe; /*!< Control pipe handle*/
+ usb_host_pipe_handle interruptPipe; /*!< HUB interrupt in pipe handle*/
+ usb_host_hub_port_instance_t *portList; /*!< HUB's port instance list*/
+ usb_host_transfer_t *controlTransfer; /*!< Control transfer in progress*/
+ transfer_callback_t inCallbackFn; /*!< Interrupt in callback*/
+ void *inCallbackParam; /*!< Interrupt in callback parameter*/
+ transfer_callback_t controlCallbackFn; /*!< Control callback*/
+ void *controlCallbackParam; /*!< Control callback parameter*/
+ /* HUB property */
+ uint16_t totalThinktime; /*!< HUB total think time*/
+ uint8_t hubLevel; /*!< HUB level, the root HUB's level is 1*/
+
+ /* HUB application parameter */
+ uint8_t hubDescriptor[7 + (USB_HOST_HUB_MAX_PORT >> 3) + 1]; /*!< HUB descriptor buffer*/
+ uint8_t hubBitmapBuffer[(USB_HOST_HUB_MAX_PORT >> 3) + 1]; /*!< HUB receiving bitmap data buffer*/
+ uint8_t hubStatusBuffer[4]; /*!< HUB status buffer*/
+ uint8_t portStatusBuffer[4]; /*!< Port status buffer*/
+ uint8_t hubStatus; /*!< HUB instance running status*/
+ uint8_t portCount; /*!< HUB port count*/
+ uint8_t portIndex; /*!< Record the index when processing ports in turn*/
+ uint8_t portProcess; /*!< The port that is processing*/
+ uint8_t primeStatus; /*!< Data prime transfer status*/
+ uint8_t invalid; /*!< 0/1, when invalid, cannot send transfer to the class*/
+} usb_host_hub_instance_t;
+
+/*******************************************************************************
+ * Variables
+ ******************************************************************************/
+
+/*******************************************************************************
+ * Code
+ ******************************************************************************/
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*!
+ * @brief Initializes the HUB instance.
+ *
+ * This function allocates the resource for HUB instance.
+ *
+ * @param deviceHandle The device handle.
+ * @param classHandle Return class handle.
+ *
+ * @retval kStatus_USB_Success The device is initialized successfully.
+ * @retval kStatus_USB_AllocFail Allocate memory fail.
+ */
+extern usb_status_t USB_HostHubInit(usb_device_handle deviceHandle, usb_host_class_handle *classHandle);
+
+/*!
+ * @brief Sets interface.
+ *
+ * This function binds the interfaces with the HUB instance.
+ *
+ * @param classHandle The class handle.
+ * @param interfaceHandle The interface handle.
+ * @param alternateSetting The alternate setting value.
+ * @param callbackFn This callback is called after this function completes.
+ * @param callbackParam The first parameter in the callback function.
+ *
+ * @retval kStatus_USB_Success The device is initialized successfully.
+ * @retval kStatus_USB_InvalidHandle The classHandle is NULL pointer.
+ * @retval kStatus_USB_Busy There is no idle transfer.
+ * @retval kStatus_USB_Error Open pipe fail. See the USB_HostOpenPipe.
+ * Or send transfer fail. See the USB_HostSendSetup,
+ */
+extern usb_status_t USB_HostHubSetInterface(usb_host_class_handle classHandle,
+ usb_host_interface_handle interfaceHandle,
+ uint8_t alternateSetting,
+ transfer_callback_t callbackFn,
+ void *callbackParam);
+
+/*!
+ * @brief Deinitializes the HUB instance.
+ *
+ * This function releases the resource for HUB instance.
+ *
+ * @param deviceHandle The device handle.
+ * @param classHandle The class handle.
+ *
+ * @retval kStatus_USB_Success The device is deinitialized successfully.
+ */
+extern usb_status_t USB_HostHubDeinit(usb_device_handle deviceHandle, usb_host_class_handle classHandle);
+
+/*!
+ * @brief Receives data.
+ *
+ * This function implements the HUB receiving data.
+ *
+ * @param classHandle The class handle.
+ * @param buffer The buffer pointer.
+ * @param bufferLength The buffer length.
+ * @param callbackFn This callback is called after this function completes.
+ * @param callbackParam The first parameter in the callback function.
+ *
+ * @retval kStatus_USB_Success Receive request successfully.
+ * @retval kStatus_USB_InvalidHandle The classHandle is NULL pointer.
+ * @retval kStatus_USB_Busy There is no idle transfer.
+ * @retval kStatus_USB_Error Pipe is not initialized.
+ * Or, send transfer fail. See the USB_HostRecv.
+ */
+extern usb_status_t USB_HostHubInterruptRecv(usb_host_class_handle classHandle,
+ uint8_t *buffer,
+ uint16_t bufferLength,
+ transfer_callback_t callbackFn,
+ void *callbackParam);
+
+/*!
+ * @brief Port reset setup.
+ *
+ * This function sends the HUB port reset transfer.
+ *
+ * @param classHandle The class handle.
+ * @param portNumber Port number.
+ *
+ * @retval kStatus_USB_Success Send successfully.
+ * @retval kStatus_USB_InvalidHandle The classHandle is NULL pointer.
+ * @retval kStatus_USB_Busy There is no idle transfer.
+ * @retval kStatus_USB_Error Pipe is not initialized.
+ * Or, send transfer fail. See the USB_HostSendSetup.
+ */
+extern usb_status_t USB_HostHubSendPortReset(usb_host_class_handle classHandle, uint8_t portNumber);
+
+/*!
+ * @brief HUB get descriptor.
+ *
+ * This function implements get HUB descriptor-specific request.
+ *
+ * @param classHandle The class handle.
+ * @param buffer The buffer pointer.
+ * @param bufferLength The buffer length.
+ * @param callbackFn This callback is called after this function completes.
+ * @param callbackParam The first parameter in the callback function.
+ *
+ * @retval kStatus_USB_Success Send successfully.
+ * @retval kStatus_USB_InvalidHandle The classHandle is NULL pointer.
+ * @retval kStatus_USB_Busy There is no idle transfer.
+ * @retval kStatus_USB_Error Pipe is not initialized.
+ * Or, send transfer fail. See the USB_HostSendSetup.
+ */
+extern usb_status_t USB_HostHubGetDescriptor(usb_host_class_handle classHandle,
+ uint8_t *buffer,
+ uint16_t bufferLength,
+ transfer_callback_t callbackFn,
+ void *callbackParam);
+
+/*!
+ * @brief HUB clear feature.
+ *
+ * This function implements clear HUB feature specific request.
+ *
+ * @param classHandle the class handle.
+ * @param buffer the buffer pointer.
+ * @param bufferLength the buffer length.
+ * @param callbackFn this callback is called after this function completes.
+ * @param callbackParam the first parameter in the callback function.
+ *
+ * @retval kStatus_USB_Success send successfully.
+ * @retval kStatus_USB_InvalidHandle The classHandle is NULL pointer.
+ * @retval kStatus_USB_Busy There is no idle transfer.
+ * @retval kStatus_USB_Error pipe is not initialized.
+ * Or, send transfer fail, please reference to USB_HostSendSetup.
+ */
+extern usb_status_t USB_HostHubClearFeature(usb_host_class_handle classHandle,
+ uint8_t feature,
+ transfer_callback_t callbackFn,
+ void *callbackParam);
+
+/*!
+ * @brief HUB get status.
+ *
+ * This function implements the get HUB status-specific request.
+ *
+ * @param classHandle The class handle.
+ * @param buffer The buffer pointer.
+ * @param bufferLength The buffer length.
+ * @param callbackFn This callback is called after this function completes.
+ * @param callbackParam The first parameter in the callback function.
+ *
+ * @retval kStatus_USB_Success Send successfully.
+ * @retval kStatus_USB_InvalidHandle The classHandle is NULL pointer.
+ * @retval kStatus_USB_Busy There is no idle transfer.
+ * @retval kStatus_USB_Error Pipe is not initialized.
+ * Or, send transfer fail. See the USB_HostSendSetup.
+ */
+extern usb_status_t USB_HostHubGetStatus(usb_host_class_handle classHandle,
+ uint8_t *buffer,
+ uint16_t bufferLength,
+ transfer_callback_t callbackFn,
+ void *callbackParam);
+
+/*!
+ * @brief HUB set feature.
+ *
+ * This function implements the set HUB feature-specific request.
+ *
+ * @param classHandle The class handle.
+ * @param buffer The buffer pointer.
+ * @param bufferLength The buffer length.
+ * @param callbackFn This callback is called after this function completes.
+ * @param callbackParam The first parameter in the callback function.
+ *
+ * @retval kStatus_USB_Success Send successfully.
+ * @retval kStatus_USB_InvalidHandle The classHandle is NULL pointer.
+ * @retval kStatus_USB_Busy There is no idle transfer.
+ * @retval kStatus_USB_Error Pipe is not initialized.
+ * Or, send transfer fail. See the USB_HostSendSetup.
+ */
+extern usb_status_t USB_HostHubSetPortFeature(usb_host_class_handle classHandle,
+ uint8_t portNumber,
+ uint8_t feature,
+ transfer_callback_t callbackFn,
+ void *callbackParam);
+
+/*!
+ * @brief HUB clear port feature.
+ *
+ * This function implements the clear HUB port feature-specific request.
+ *
+ * @param classHandle The class handle.
+ * @param buffer The buffer pointer.
+ * @param bufferLength The buffer length.
+ * @param callbackFn This callback is called after this function completes.
+ * @param callbackParam The first parameter in the callback function.
+ *
+ * @retval kStatus_USB_Success Send successfully.
+ * @retval kStatus_USB_InvalidHandle The classHandle is NULL pointer.
+ * @retval kStatus_USB_Busy There is no idle transfer.
+ * @retval kStatus_USB_Error Pipe is not initialized.
+ * Or, send transfer fail. See the USB_HostSendSetup.
+ */
+extern usb_status_t USB_HostHubClearPortFeature(usb_host_class_handle classHandle,
+ uint8_t portNumber,
+ uint8_t feature,
+ transfer_callback_t callbackFn,
+ void *callbackParam);
+
+/*!
+ * @brief HUB port get status.
+ *
+ * This function implements the get HUB port status-specific request.
+ *
+ * @param classHandle The class handle.
+ * @param buffer The buffer pointer.
+ * @param bufferLength The buffer length.
+ * @param callbackFn This callback is called after this function completes.
+ * @param callbackParam The first parameter in the callback function.
+ *
+ * @retval kStatus_USB_Success Send successfully.
+ * @retval kStatus_USB_InvalidHandle The classHandle is NULL pointer.
+ * @retval kStatus_USB_Busy There is no idle transfer.
+ * @retval kStatus_USB_Error Pipe is not initialized.
+ * Or, send transfer fail. See the USB_HostSendSetup.
+ */
+extern usb_status_t USB_HostHubGetPortStatus(usb_host_class_handle classHandle,
+ uint8_t portNumber,
+ uint8_t *buffer,
+ uint16_t bufferLength,
+ transfer_callback_t callbackFn,
+ void *callbackParam);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* USB_HOST_CONFIG_HUB */
+
+#endif /* _USB_HSOT_HUB_H_ */
diff --git a/usb_1.1.0/host/class/usb_host_hub_app.c b/usb_1.1.0/host/class/usb_host_hub_app.c
new file mode 100644
index 0000000..1755b69
--- /dev/null
+++ b/usb_1.1.0/host/class/usb_host_hub_app.c
@@ -0,0 +1,1106 @@
+/*
+ * Copyright (c) 2015, Freescale Semiconductor, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * o Redistributions of source code must retain the above copyright notice, this list
+ * of conditions and the following disclaimer.
+ *
+ * o Redistributions in binary form must reproduce the above copyright notice, this
+ * list of conditions and the following disclaimer in the documentation and/or
+ * other materials provided with the distribution.
+ *
+ * o Neither the name of Freescale Semiconductor, Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "usb_host_config.h"
+#if ((defined USB_HOST_CONFIG_HUB) && (USB_HOST_CONFIG_HUB))
+
+#include "usb_host.h"
+#include "usb_host_hub.h"
+#include "usb_host_hub_app.h"
+#include "usb_host_devices.h"
+
+/*******************************************************************************
+ * Definitions
+ ******************************************************************************/
+/*******************************************************************************
+ * Prototypes
+ ******************************************************************************/
+
+/*!
+ * @brief prime interrupt in data.
+ *
+ * @param hubInstance hub instance pointer.
+ */
+static void USB_HostHubGetInterruptStatus(usb_host_hub_instance_t *hubInstance);
+
+/*!
+ * @brief hub process state machine. hub is enable after the state machine.
+ *
+ * @param hubInstance hub instance pointer.
+ */
+static void USB_HostHubProcess(usb_host_hub_instance_t *hubInstance);
+
+/*!
+ * @brief hub port attach process state machine. one device is attached to the port after the state machine.
+ *
+ * @param hubInstance hub instance pointer.
+ */
+static void USB_HostHubProcessPortAttach(usb_host_hub_instance_t *hubInstance);
+
+/*!
+ * @brief hub port detach process state machine. one device is detached from the port after the state machine.
+ *
+ * @param hubInstance hub instance pointer.
+ */
+static void USB_HostHubProcessPortDetach(usb_host_hub_instance_t *hubInstance);
+
+/*!
+ * @brief hub port process.
+ *
+ * @param hubInstance hub instance pointer.
+ */
+static void USB_HostHubProcessPort(usb_host_hub_instance_t *hubInstance);
+
+/*!
+ * @brief hub interrupt in data process.
+ *
+ * @param hubInstance hub instance pointer.
+ */
+static void USB_HostHubProcessData(usb_host_hub_instance_t *hubInstance);
+
+/*!
+ * @brief hub control pipe transfer callback.
+ *
+ * @param param callback parameter.
+ * @param transfer callback transfer.
+ * @param status transfer status.
+ */
+void USB_HostHubControlCallback(void *param, uint8_t *data, uint32_t data_len, usb_status_t status);
+
+/*!
+ * @brief hub interrupt pipe transfer callback.
+ *
+ * @param param callback parameter.
+ * @param transfer callback transfer.
+ * @param status transfer status.
+ */
+void USB_HostHubInterruptInCallback(void *param, uint8_t *data, uint32_t data_len, usb_status_t status);
+
+/*******************************************************************************
+ * Variables
+ ******************************************************************************/
+
+static usb_device_handle s_HubDeviceHandle;
+static usb_host_interface_handle s_HubInterfaceHandle;
+static usb_host_hub_global_t s_HubGlobal;
+
+/*******************************************************************************
+ * Code
+ ******************************************************************************/
+
+static void USB_HostHubGetInterruptStatus(usb_host_hub_instance_t *hubInstance)
+{
+ if (hubInstance == NULL)
+ {
+ return;
+ }
+
+ /* there is no prime for control or interrupt */
+ if (hubInstance->primeStatus != kPrimeNone)
+ {
+ return;
+ }
+
+ /* receive interrupt data */
+ if (USB_HostHubInterruptRecv(hubInstance, hubInstance->hubBitmapBuffer, (hubInstance->portCount >> 3) + 1,
+ USB_HostHubInterruptInCallback, hubInstance) != kStatus_USB_Success)
+ {
+#ifdef HOST_ECHO
+ usb_echo("error in hub interrupt recv\r\n");
+#endif
+ }
+ else
+ {
+ hubInstance->primeStatus = kPrimeInterrupt;
+ }
+}
+
+static void USB_HostHubProcess(usb_host_hub_instance_t *hubInstance)
+{
+ uint8_t needPrimeInterrupt = 0; /* need to prime interrupt in transfer (0 - don't need; 1 - need) */
+ uint8_t processSuccess = 0; /* the code excute successfully (0 - fail; 1 - success) */
+ uint32_t tmp = 0;
+ usb_host_hub_descriptor_t *hubDescriptor;
+
+ switch (hubInstance->hubStatus)
+ {
+ case kHubRunIdle:
+ case kHubRunInvalid:
+ break;
+
+ case kHubRunWaitSetInterface:
+ hubInstance->hubStatus = kHubRunGetDescriptor7; /* update as next state */
+ /* get hub descriptor */
+ if (USB_HostHubGetDescriptor(hubInstance, hubInstance->hubDescriptor, 7, USB_HostHubControlCallback,
+ hubInstance) == kStatus_USB_Success)
+ {
+ hubInstance->primeStatus = kPrimeHubControl; /* control transfer is on-going */
+ processSuccess = 1;
+#ifdef HOST_ECHO
+ usb_echo("hub get descriptor 7\r\n");
+#endif
+ }
+ else
+ {
+#ifdef HOST_ECHO
+ usb_echo("hub get descriptor 7 error\r\n");
+#endif
+ break;
+ }
+ break;
+
+ case kHubRunGetDescriptor7:
+ hubDescriptor = (usb_host_hub_descriptor_t *)&hubInstance->hubDescriptor[0];
+
+ /* get the hub think time */
+ USB_HostHelperGetPeripheralInformation(hubInstance->deviceHandle, kUSB_HostGetHubThinkTime, &tmp);
+ hubInstance->totalThinktime = tmp + (((uint32_t)hubDescriptor->whubcharacteristics[0] &
+ USB_HOST_HUB_DESCRIPTOR_CHARACTERISTICS_THINK_TIME_MASK) >>
+ USB_HOST_HUB_DESCRIPTOR_CHARACTERISTICS_THINK_TIME_SHIFT);
+
+ /* get hub port number */
+ hubInstance->portCount = hubDescriptor->bnrports;
+ if (hubInstance->portCount > USB_HOST_HUB_MAX_PORT)
+ {
+#ifdef HOST_ECHO
+ usb_echo("port number is bigger than USB_HOST_HUB_MAX_PORT\r\n");
+#endif
+ return;
+ }
+
+ hubInstance->hubStatus = kHubRunGetDescriptor; /* update as next state */
+ /* get hub descriptor */
+ if (USB_HostHubGetDescriptor(hubInstance, hubInstance->hubDescriptor, 7 + (hubInstance->portCount >> 3) + 1,
+ USB_HostHubControlCallback, hubInstance) == kStatus_USB_Success)
+ {
+ hubInstance->primeStatus = kPrimeHubControl; /* control transfer is on-going */
+ processSuccess = 1;
+#ifdef HOST_ECHO
+ usb_echo("hub get descriptor\r\n");
+#endif
+ }
+ else
+ {
+#ifdef HOST_ECHO
+ usb_echo("hub get descriptor error\r\n");
+#endif
+ break;
+ }
+ break;
+
+ case kHubRunGetDescriptor:
+ /* malloc port instance for the hub's ports */
+ hubInstance->portList = (usb_host_hub_port_instance_t *)USB_OsaMemoryAllocate(
+ hubInstance->portCount * sizeof(usb_host_hub_port_instance_t));
+ if (hubInstance->portList == NULL)
+ {
+#ifdef HOST_ECHO
+ usb_echo("port list allocate fail\r\n");
+#endif
+ hubInstance->hubStatus = kHubRunInvalid;
+ break;
+ }
+ /* TODO: port instance status -> can be removed. app_status */
+
+ hubInstance->hubStatus = kHubRunSetPortPower; /* update as next state */
+ hubInstance->portIndex = 0;
+
+ /* there is no significance, just for fixing misra error */
+ if (hubInstance->hubStatus != kHubRunSetPortPower)
+ {
+ break;
+ }
+
+ case kHubRunSetPortPower:
+ /* set PORT_POWER for all ports */
+ if (hubInstance->portIndex < hubInstance->portCount)
+ {
+ hubInstance->portIndex++;
+ if (USB_HostHubSetPortFeature(hubInstance, hubInstance->portIndex, PORT_POWER,
+ USB_HostHubControlCallback, hubInstance) == kStatus_USB_Success)
+ {
+ hubInstance->primeStatus = kPrimeHubControl; /* update as next state */
+ processSuccess = 1;
+#ifdef HOST_ECHO
+ usb_echo("set port feature PORT_POWER\r\n");
+#endif
+ }
+ else
+ {
+#ifdef HOST_ECHO
+ usb_echo("set port feature PORT_POWER fail\r\n");
+#endif
+ needPrimeInterrupt = 1;
+ break;
+ }
+ break;
+ }
+ hubInstance->portProcess = 0;
+ /* reset port information as default */
+ for (tmp = 0; tmp < hubInstance->portCount; ++tmp)
+ {
+ hubInstance->portList[tmp].deviceHandle = NULL;
+ hubInstance->portList[tmp].resetCount = USB_HOST_HUB_PORT_RESET_TIMES;
+ hubInstance->portList[tmp].portStatus = kPortRunWaitPortChange;
+ }
+ hubInstance->hubStatus = kHubRunIdle;
+ needPrimeInterrupt = 1;
+ break;
+
+ case kHubRunGetStatusDone: /* process hub status change */
+ tmp = USB_SHORT_FROM_LITTLE_ENDIAN_ADDRESS((&hubInstance->hubStatusBuffer[2]));
+ hubInstance->hubStatus = kHubRunIdle;
+ if ((1 << C_HUB_LOCAL_POWER) & tmp) /* C_HUB_LOCAL_POWER */
+ {
+ if (USB_HostHubClearFeature(hubInstance, C_HUB_LOCAL_POWER, USB_HostHubControlCallback, hubInstance) ==
+ kStatus_USB_Success)
+ {
+ hubInstance->primeStatus = kPrimeHubControl;
+ processSuccess = 1;
+ }
+ else
+ {
+ needPrimeInterrupt = 1;
+ }
+ }
+ else if ((1 << C_HUB_OVER_CURRENT) & tmp) /* C_HUB_OVER_CURRENT */
+ {
+ if (USB_HostHubClearFeature(hubInstance, C_HUB_OVER_CURRENT, USB_HostHubControlCallback, hubInstance) ==
+ kStatus_USB_Success)
+ {
+ hubInstance->primeStatus = kPrimeHubControl;
+ processSuccess = 1;
+ }
+ else
+ {
+ needPrimeInterrupt = 1;
+ }
+ }
+ else
+ {
+ needPrimeInterrupt = 1;
+ }
+ break;
+
+ default:
+ break;
+ }
+
+ if (needPrimeInterrupt == 1) /* prime interrupt in transfer */
+ {
+ hubInstance->hubStatus = kHubRunIdle;
+ USB_HostHubGetInterruptStatus(hubInstance);
+ }
+ else
+ {
+ if (processSuccess == 0)
+ {
+ hubInstance->hubStatus = kHubRunInvalid;
+ }
+ }
+}
+
+static void USB_HostHubProcessPort(usb_host_hub_instance_t *hubInstance)
+{
+ usb_host_hub_port_instance_t *portInstance = &hubInstance->portList[hubInstance->portProcess - 1];
+
+ /* for device attach */
+ if (portInstance->deviceHandle == NULL)
+ {
+ USB_HostHubProcessPortAttach(hubInstance);
+ }
+ else /* for device detach */
+ {
+ USB_HostHubProcessPortDetach(hubInstance);
+ }
+}
+
+static void USB_HostHubProcessPortAttach(usb_host_hub_instance_t *hubInstance)
+{
+ usb_host_hub_port_instance_t *portInstance = &hubInstance->portList[hubInstance->portProcess - 1];
+ uint8_t processSuccess = 0;
+ uint32_t specStatus;
+ uint8_t feature;
+ uint32_t infoValue;
+
+ switch (portInstance->portStatus)
+ {
+ case kPortRunIdle:
+ case kPortRunInvalid:
+ break;
+ case kPortRunWaitPortChange: /* (1) port is changed, and get port status */
+ portInstance->portStatus = kPortRunCheckCPortConnection; /* update as next state */
+ /* send class-specific request to get port status */
+ if (USB_HostHubGetPortStatus(hubInstance, hubInstance->portProcess, hubInstance->portStatusBuffer, 4,
+ USB_HostHubControlCallback, hubInstance) == kStatus_USB_Success)
+ {
+ hubInstance->primeStatus = kPrimePortControl;
+ processSuccess = 1;
+ }
+ break;
+
+ case kPortRunCheckCPortConnection: /* (2) check port status, and clear the status bits */
+ feature = 0;
+ specStatus = USB_LONG_FROM_LITTLE_ENDIAN_ADDRESS((hubInstance->portStatusBuffer));
+ if ((1 << C_PORT_CONNECTION) & specStatus)
+ {
+ portInstance->portStatus = kPortRunGetPortConnection; /* update as next state */
+ /* clear C_PORT_CONNECTION */
+ if (USB_HostHubClearPortFeature(hubInstance, hubInstance->portProcess, C_PORT_CONNECTION,
+ USB_HostHubControlCallback, hubInstance) == kStatus_USB_Success)
+ {
+ hubInstance->primeStatus = kPrimePortControl;
+ processSuccess = 1;
+ }
+ break;
+ }
+ else if ((1 << PORT_CONNECTION) & specStatus)
+ {
+ portInstance->portStatus = kPortRunWaitPortResetDone; /* update as next state */
+ /* set PORT_RESET */
+ if (USB_HostHubSetPortFeature(hubInstance, hubInstance->portProcess, PORT_RESET,
+ USB_HostHubControlCallback, hubInstance) == kStatus_USB_Success)
+ {
+ hubInstance->primeStatus = kPrimePortControl;
+ processSuccess = 1;
+ if (portInstance->resetCount > 0)
+ {
+ portInstance->resetCount--;
+ }
+ }
+ break;
+ }
+ else if ((1 << C_PORT_RESET) & specStatus)
+ {
+ feature = C_PORT_RESET; /* clear C_PORT_RESET */
+#ifdef HOST_ECHO
+ usb_echo("hub: C_PORT_RESET when detached\r\n");
+#endif
+ }
+ else if ((1 << C_PORT_ENABLE) & specStatus)
+ {
+ feature = C_PORT_ENABLE; /* clear C_PORT_ENABLE */
+#ifdef HOST_ECHO
+ usb_echo("hub: C_PORT_ENABLE when detached\r\n");
+#endif
+ }
+ else if ((1 << C_PORT_OVER_CURRENT) & specStatus)
+ {
+ feature = C_PORT_OVER_CURRENT; /* clear C_PORT_OVER_CURRENT */
+#ifdef HOST_ECHO
+ usb_echo("hub: C_PORT_OVER_CURRENT when detached\r\n");
+#endif
+ }
+ else
+ {
+ }
+
+ if (feature != 0)
+ {
+ portInstance->portStatus = kPortRunWaitPortChange; /* update as next state */
+ /* clear feature */
+ if (USB_HostHubClearPortFeature(hubInstance, hubInstance->portProcess, feature,
+ USB_HostHubControlCallback, hubInstance) == kStatus_USB_Success)
+ {
+ hubInstance->primeStatus = kPrimePortControl;
+ processSuccess = 1;
+ }
+ }
+ break;
+
+ case kPortRunGetPortConnection: /* (3) get port status */
+ portInstance->portStatus = kPortRunCheckPortConnection; /* update as next state */
+ /* get port status bits */
+ if (USB_HostHubGetPortStatus(hubInstance, hubInstance->portProcess, hubInstance->portStatusBuffer, 4,
+ USB_HostHubControlCallback, hubInstance) == kStatus_USB_Success)
+ {
+ hubInstance->primeStatus = kPrimePortControl; /* control transfer is on-going */
+ processSuccess = 1;
+ }
+ break;
+
+ case kPortRunCheckPortConnection: /* (4) check PORT_CONNECTION bit */
+ specStatus = USB_LONG_FROM_LITTLE_ENDIAN_ADDRESS(hubInstance->portStatusBuffer);
+ if ((1 << PORT_CONNECTION) & specStatus)
+ {
+ portInstance->portStatus = kPortRunWaitPortResetDone; /* update as next state */
+ /* set PORT_RESET */
+ if (USB_HostHubSetPortFeature(hubInstance, hubInstance->portProcess, PORT_RESET,
+ USB_HostHubControlCallback, hubInstance) == kStatus_USB_Success)
+ {
+ hubInstance->primeStatus = kPrimePortControl;
+ processSuccess = 1;
+ if (portInstance->resetCount > 0)
+ {
+ portInstance->resetCount--;
+ }
+ }
+ }
+ break;
+
+ case kPortRunWaitPortResetDone: /* (5) wait port change */
+ portInstance->portStatus = kPortRunWaitCPortReset; /* update as next state */
+ processSuccess = 1;
+ /* must wait the enumeration done, then operate the next port */
+ USB_HostHubGetInterruptStatus(hubInstance);
+ break;
+
+ case kPortRunWaitCPortReset: /* (6) get port satus for checking C_PORT_RESET */
+ portInstance->portStatus = KPortRunCheckCPortReset; /* update as next state */
+ /* get port status bits */
+ if (USB_HostHubGetPortStatus(hubInstance, hubInstance->portProcess, hubInstance->portStatusBuffer, 4,
+ USB_HostHubControlCallback, hubInstance) == kStatus_USB_Success)
+ {
+ hubInstance->primeStatus = kPrimePortControl;
+ processSuccess = 1;
+ }
+ break;
+
+ case KPortRunCheckCPortReset: /* (7) check C_PORT_RESET and clear C_PORT_RESET */
+ specStatus = USB_LONG_FROM_LITTLE_ENDIAN_ADDRESS(hubInstance->portStatusBuffer);
+ if ((1 << C_PORT_RESET) & specStatus)
+ {
+ if (portInstance->resetCount == 0)
+ {
+ portInstance->portStatus = kPortRunPortAttached; /* update as next state */
+ /* get port's device speed */
+ if (specStatus & (1 << PORT_HIGH_SPEED))
+ {
+ portInstance->speed = USB_SPEED_HIGH;
+ }
+ else if (specStatus & (1 << PORT_LOW_SPEED))
+ {
+ portInstance->speed = USB_SPEED_LOW;
+ }
+ else
+ {
+ portInstance->speed = USB_SPEED_FULL;
+ }
+ }
+ else
+ {
+ portInstance->portStatus = kPortRunResetAgain; /* update as next state */
+ }
+
+ /* clear C_PORT_RESET */
+ if (USB_HostHubClearPortFeature(hubInstance, hubInstance->portProcess, C_PORT_RESET,
+ USB_HostHubControlCallback, hubInstance) == kStatus_USB_Success)
+ {
+ hubInstance->primeStatus = kPrimePortControl;
+ processSuccess = 1;
+ }
+ }
+ break;
+
+ case kPortRunResetAgain: /* (8) reset again */
+ portInstance->portStatus = kPortRunCheckPortConnection; /* check connection then reset again */
+ if (USB_HostHubGetPortStatus(hubInstance, hubInstance->portProcess, hubInstance->portStatusBuffer, 4,
+ USB_HostHubControlCallback, hubInstance) == kStatus_USB_Success)
+ {
+ hubInstance->primeStatus = kPrimePortControl;
+ processSuccess = 1;
+ }
+ break;
+
+ case kPortRunPortAttached: /* (9) the port have one device attached */
+ USB_HostHelperGetPeripheralInformation(hubInstance->deviceHandle, kUSB_HostGetDeviceAddress, &infoValue);
+ USB_HostAttachDevice(hubInstance->hostHandle, portInstance->speed, infoValue, hubInstance->portProcess,
+ hubInstance->hubLevel + 1, &portInstance->deviceHandle);
+ processSuccess = 1;
+ hubInstance->portProcess = 0;
+ s_HubGlobal.hubProcess = NULL;
+ portInstance->resetCount = USB_HOST_HUB_PORT_RESET_TIMES;
+ USB_HostHubGetInterruptStatus(hubInstance);
+ break;
+
+ default:
+ break;
+ }
+
+ if (processSuccess == 0)
+ {
+ portInstance->portStatus = kPortRunWaitPortChange;
+ hubInstance->portProcess = 0;
+ s_HubGlobal.hubProcess = NULL;
+ portInstance->resetCount = USB_HOST_HUB_PORT_RESET_TIMES;
+
+ USB_HostHubGetInterruptStatus(hubInstance);
+ }
+}
+
+static void USB_HostHubProcessPortDetach(usb_host_hub_instance_t *hubInstance)
+{
+ usb_host_hub_port_instance_t *portInstance = &hubInstance->portList[hubInstance->portProcess - 1];
+ uint8_t processSuccess = 0;
+ uint32_t specStatus;
+
+ switch (portInstance->portStatus)
+ {
+ case kPortRunIdle:
+ case kPortRunInvalid:
+ break;
+
+ case kPortRunPortAttached: /* (1) port is changed, then get port status */
+ portInstance->portStatus = kPortRunCheckPortDetach;
+ /* get port status */
+ if (USB_HostHubGetPortStatus(hubInstance, hubInstance->portProcess, hubInstance->portStatusBuffer, 4,
+ USB_HostHubControlCallback, hubInstance) == kStatus_USB_Success)
+ {
+ hubInstance->primeStatus = kPrimePortControl;
+ processSuccess = 1;
+ }
+ break;
+
+ case kPortRunCheckPortDetach: /* (2) check port status bits */
+ specStatus = USB_LONG_FROM_LITTLE_ENDIAN_ADDRESS(hubInstance->portStatusBuffer);
+ portInstance->portStatus = kPortRunGetConnectionBit;
+ if ((1 << C_PORT_CONNECTION) & specStatus) /* C_PORT_CONNECTION */
+ {
+ if (USB_HostHubClearPortFeature(hubInstance, hubInstance->portProcess, C_PORT_CONNECTION,
+ USB_HostHubControlCallback, hubInstance) == kStatus_USB_Success)
+ {
+ hubInstance->primeStatus = kPrimePortControl;
+ processSuccess = 1;
+ }
+ break;
+ }
+ else if ((1 << C_PORT_ENABLE) & specStatus) /* C_PORT_ENABLE */
+ {
+ if (USB_HostHubClearPortFeature(hubInstance, hubInstance->portProcess, C_PORT_ENABLE,
+ USB_HostHubControlCallback, hubInstance) == kStatus_USB_Success)
+ {
+ hubInstance->primeStatus = kPrimePortControl;
+ processSuccess = 1;
+ }
+ break;
+ }
+ else
+ {
+ /* don't break to check CONNECTION bit */
+ }
+
+ case kPortRunGetConnectionBit: /* (3) get port status */
+ portInstance->portStatus = kPortRunCheckConnectionBit;
+ if (USB_HostHubGetPortStatus(hubInstance, hubInstance->portProcess, hubInstance->portStatusBuffer, 4,
+ USB_HostHubControlCallback, hubInstance) == kStatus_USB_Success)
+ {
+ hubInstance->primeStatus = kPrimePortControl;
+ processSuccess = 1;
+ }
+ break;
+
+ case kPortRunCheckConnectionBit: /* (4) check port connection bit */
+ specStatus = USB_LONG_FROM_LITTLE_ENDIAN_ADDRESS(hubInstance->portStatusBuffer);
+ if ((1 << PORT_CONNECTION) & specStatus) /* PORT_CONNECTION */
+ {
+ portInstance->portStatus = kPortRunPortAttached;
+#ifdef HOST_ECHO
+ usb_echo("PORT_CONNECTION in attach for detach\r\n");
+#endif
+ }
+ else
+ {
+ processSuccess = 1;
+ /* port's device is detached */
+ portInstance->portStatus = kPortRunWaitPortChange;
+ USB_HostDetachDeviceInternal(hubInstance->hostHandle, portInstance->deviceHandle);
+ portInstance->deviceHandle = NULL;
+ s_HubGlobal.hubProcess = NULL;
+ hubInstance->portProcess = 0;
+ USB_HostHubGetInterruptStatus(hubInstance);
+ }
+ break;
+ default:
+ break;
+ }
+
+ if (processSuccess == 0)
+ {
+ portInstance->portStatus = kPortRunPortAttached;
+ s_HubGlobal.hubProcess = NULL;
+ hubInstance->portProcess = 0;
+ USB_HostHubGetInterruptStatus(hubInstance);
+ }
+}
+
+static void USB_HostHubProcessData(usb_host_hub_instance_t *hubInstance)
+{
+ uint8_t needPrimeInterrupt = 1;
+ uint8_t portIndex;
+
+ /* process the port which status change */
+ for (portIndex = 0; portIndex <= hubInstance->portCount; ++portIndex)
+ {
+ if ((0x01u << (portIndex & 0x07u)) & (hubInstance->hubBitmapBuffer[portIndex >> 3]))
+ {
+ if (portIndex == 0) /* hub status change */
+ {
+ if ((s_HubGlobal.hubProcess == NULL) ||
+ ((s_HubGlobal.hubProcess == hubInstance) && (hubInstance->portProcess == 0)))
+ {
+ hubInstance->hubStatus = kHubRunGetStatusDone;
+ if (USB_HostHubGetStatus(hubInstance, hubInstance->hubStatusBuffer, 4, USB_HostHubControlCallback,
+ hubInstance) != kStatus_USB_Success)
+ {
+#ifdef HOST_ECHO
+ usb_echo("error in usb_class_hub_get_status\r\n");
+#endif
+ hubInstance->hubStatus = kHubRunIdle;
+ }
+ else
+ {
+ hubInstance->primeStatus = kPrimeHubControl;
+ needPrimeInterrupt = 0;
+ }
+ }
+ }
+ else /* port's status change */
+ {
+ /* process the on-going port or process one new port */
+ if ((s_HubGlobal.hubProcess == NULL) ||
+ ((s_HubGlobal.hubProcess == hubInstance) && (hubInstance->portProcess == 0)) ||
+ ((s_HubGlobal.hubProcess == hubInstance) && (hubInstance->portProcess == portIndex)))
+ {
+ if (hubInstance->controlTransfer == NULL)
+ {
+ s_HubGlobal.hubProcess = hubInstance;
+ hubInstance->portProcess = portIndex;
+ needPrimeInterrupt = 0;
+ USB_HostHubProcessPort(hubInstance);
+ }
+ break; /* process the port change in turn */
+ }
+ }
+ }
+ }
+
+ if (needPrimeInterrupt == 1)
+ {
+ USB_HostHubGetInterruptStatus(hubInstance);
+ }
+}
+
+void USB_HostHubControlCallback(void *param, uint8_t *data, uint32_t data_len, usb_status_t status)
+{
+ usb_host_hub_instance_t *hubInstance = (usb_host_hub_instance_t *)param;
+
+ if (hubInstance->invalid == 1)
+ {
+ return;
+ }
+ if (status != kStatus_USB_Success)
+ {
+ /* if transfer fail, prime a new interrupt in transfer */
+ hubInstance->primeStatus = kPrimeNone;
+ s_HubGlobal.hubProcess = NULL;
+ hubInstance->portProcess = 0;
+ USB_HostHubGetInterruptStatus(hubInstance);
+ return;
+ }
+
+ if (hubInstance->primeStatus == kPrimeHubControl) /* hub related control transfer */
+ {
+ hubInstance->primeStatus = kPrimeNone;
+ USB_HostHubProcess(hubInstance);
+ }
+ else if (hubInstance->primeStatus == kPrimePortControl) /* hub's port related control transfer */
+ {
+ hubInstance->primeStatus = kPrimeNone;
+ USB_HostHubProcessPort(hubInstance);
+ }
+ else
+ {
+ }
+}
+
+void USB_HostHubInterruptInCallback(void *param, uint8_t *data, uint32_t data_len, usb_status_t status)
+{
+ usb_host_hub_instance_t *hubInstance = (usb_host_hub_instance_t *)param;
+
+ if (hubInstance->invalid == 1)
+ {
+ return;
+ }
+ /* interrupt data received */
+ hubInstance->primeStatus = kPrimeNone;
+ if (status != kStatus_USB_Success)
+ {
+#ifdef HOST_ECHO
+ usb_echo("hub interrupt in data callback error\r\n");
+#endif
+ /* prime nexe interrupt transfer */
+ if (hubInstance->controlTransfer == NULL)
+ {
+ s_HubGlobal.hubProcess = NULL;
+ hubInstance->portProcess = 0;
+ USB_HostHubGetInterruptStatus(hubInstance);
+ }
+ }
+ else
+ {
+ USB_HostHubProcessData(hubInstance); /* process the interrupt data */
+ }
+}
+
+/*!
+ * @brief host hub callback function.
+ *
+ * This function should be called in the host callback function.
+ *
+ * @param deviceHandle device handle.
+ * @param configurationHandle attached device's configuration descriptor information.
+ * @param event_code callback event code, please reference to enumeration host_event_t.
+ *
+ * @retval kStatus_USB_Success The host is initialized successfully.
+ * @retval kStatus_USB_NotSupported The configuration don't contain hub interface.
+ */
+usb_status_t USB_HostHubDeviceEvent(usb_device_handle deviceHandle,
+ usb_host_configuration_handle configurationHandle,
+ uint32_t eventCode)
+{
+ usb_host_configuration_t *configuration;
+ usb_host_interface_t *interface;
+ uint8_t interfaceIndex;
+ uint8_t id;
+ usb_status_t status = kStatus_USB_Success;
+ usb_host_class_handle hubClassHandle;
+ usb_host_hub_instance_t *hubInstance;
+ usb_host_hub_instance_t *prevInstance;
+ uint32_t infoValue;
+ usb_osa_status_t osaStatus;
+
+ switch (eventCode)
+ {
+ case kUSB_HostEventAttach:
+ /* judge whether is configurationHandle supported */
+ configuration = (usb_host_configuration_t *)configurationHandle;
+ for (interfaceIndex = 0; interfaceIndex < configuration->interfaceCount; ++interfaceIndex)
+ {
+ interface = &configuration->interfaceList[interfaceIndex];
+ id = interface->interfaceDesc->bInterfaceClass;
+ if (id != USB_HOST_HUB_CLASS_CODE)
+ {
+ continue;
+ }
+ id = interface->interfaceDesc->bInterfaceSubClass;
+ if (id != USB_HOST_HUB_SUBCLASS_CODE_NONE)
+ {
+ continue;
+ }
+ else
+ {
+ USB_HostHelperGetPeripheralInformation(deviceHandle, kUSB_HostGetDeviceLevel, &infoValue);
+ if (infoValue > 5)
+ {
+#ifdef HOST_ECHO
+ usb_echo("Host can support max 5 level hubs\r\n");
+#endif
+ continue;
+ }
+ /* the interface is hub */
+ s_HubDeviceHandle = deviceHandle;
+ s_HubInterfaceHandle = interface;
+ return kStatus_USB_Success;
+ }
+ }
+ status = kStatus_USB_NotSupported;
+ break;
+
+ case kUSB_HostEventEnumerationDone:
+ /* the device enumeration is done */
+ if ((s_HubDeviceHandle != NULL) && (s_HubInterfaceHandle != NULL))
+ {
+ /* print hub information */
+ USB_HostHelperGetPeripheralInformation(deviceHandle, kUSB_HostGetDeviceLevel, &infoValue);
+ usb_echo("hub attached:level=%d ", infoValue);
+ USB_HostHelperGetPeripheralInformation(deviceHandle, kUSB_HostGetDeviceAddress, &infoValue);
+ usb_echo("address=%d\r\n", infoValue);
+
+ /* initialize hub mutex */
+ if (s_HubGlobal.hubMutex == (usb_osa_mutex_handle)NULL)
+ {
+ osaStatus = USB_OsaMutexCreate(&s_HubGlobal.hubMutex);
+ if (osaStatus != kStatus_USB_OSA_Success)
+ {
+ s_HubGlobal.hubMutex = NULL;
+#ifdef HOST_ECHO
+ usb_echo("hub mutex error\r\n");
+#endif
+ }
+ }
+
+ /* initialize hub class instance */
+ status = USB_HostHubInit(s_HubDeviceHandle, &hubClassHandle);
+ hubInstance = (usb_host_hub_instance_t *)hubClassHandle;
+
+ /* link hub instance to list */
+ USB_HostHubLock();
+ hubInstance->next = s_HubGlobal.hubList;
+ s_HubGlobal.hubList = hubInstance;
+ USB_HostHubUnlock();
+
+ /* set hub instance's interface */
+ if (status == kStatus_USB_Success)
+ {
+ hubInstance->primeStatus = kPrimeHubControl;
+ hubInstance->hubStatus = kHubRunWaitSetInterface;
+ if (USB_HostHubSetInterface(hubClassHandle, s_HubInterfaceHandle, 0, USB_HostHubControlCallback,
+ hubInstance) != kStatus_USB_Success)
+ {
+ hubInstance->hubStatus = kHubRunInvalid;
+ }
+ }
+ }
+ break;
+
+ case kUSB_HostEventDetach:
+ /* the device is detached */
+ hubInstance = NULL;
+
+ /* get device's hub instance handle */
+ USB_HostHubLock();
+ prevInstance = s_HubGlobal.hubList;
+ if (prevInstance->deviceHandle == deviceHandle)
+ {
+ hubInstance = prevInstance;
+ s_HubGlobal.hubList = prevInstance->next;
+ }
+ else
+ {
+ hubInstance = prevInstance->next;
+ while (hubInstance != NULL)
+ {
+ if (hubInstance->deviceHandle == deviceHandle)
+ {
+ prevInstance->next = hubInstance->next;
+ break;
+ }
+ prevInstance = hubInstance;
+ hubInstance = hubInstance->next;
+ }
+ }
+ USB_HostHubUnlock();
+
+ if (hubInstance != NULL)
+ {
+ if (hubInstance == s_HubGlobal.hubProcess)
+ {
+ s_HubGlobal.hubProcess = NULL;
+ }
+ /* print hub information */
+ USB_HostHelperGetPeripheralInformation(hubInstance->deviceHandle, kUSB_HostGetDeviceLevel, &infoValue);
+ usb_echo("hub detached:level=%d ", infoValue);
+ USB_HostHelperGetPeripheralInformation(deviceHandle, kUSB_HostGetDeviceAddress, &infoValue);
+ usb_echo("address=%d\r\n", infoValue);
+ hubInstance->invalid = 1;
+ /* detach hub ports' devices */
+ for (uint8_t portIndex = 0; portIndex < hubInstance->portCount; ++portIndex)
+ {
+ if ((hubInstance->portList != NULL) && (hubInstance->portList[portIndex].deviceHandle != NULL))
+ {
+ USB_HostDetachDeviceInternal(hubInstance->hostHandle,
+ hubInstance->portList[portIndex].deviceHandle);
+ hubInstance->portList[portIndex].deviceHandle = NULL;
+ }
+ }
+ if (hubInstance->portList != NULL)
+ {
+ USB_OsaMemoryFree(hubInstance->portList);
+ }
+ USB_HostHubDeinit(deviceHandle, hubInstance); /* de-initialize hub instance */
+ }
+
+ /* destory hub mutex if there is no hub instance */
+ if (s_HubGlobal.hubList == NULL)
+ {
+ if (s_HubGlobal.hubMutex != NULL)
+ {
+ USB_OsaMutexDestroy(s_HubGlobal.hubMutex);
+ s_HubGlobal.hubMutex = NULL;
+ }
+ }
+ break;
+
+ default:
+ break;
+ }
+
+ return status;
+}
+
+/*!
+ * @brief remove attached device. called by USB_HostRemoveDevice.
+ *
+ * @param hubNumber the device attached hub.
+ * @param portNumber the device attached port.
+ *
+ * @return kStatus_USB_Success or error codes.
+ */
+usb_status_t USB_HostHubRemovePort(uint8_t hubNumber, uint8_t portNumber)
+{
+ usb_host_hub_instance_t *hubInstance;
+ uint32_t infoValue;
+
+ /* get hub number's hub instance handle */
+ hubInstance = (usb_host_hub_instance_t *)s_HubGlobal.hubList;
+ while (hubInstance != NULL)
+ {
+ USB_HostHelperGetPeripheralInformation(hubInstance->deviceHandle, kUSB_HostGetDeviceAddress, &infoValue);
+ if (infoValue == hubNumber)
+ {
+ break;
+ }
+ hubInstance = hubInstance->next;
+ }
+
+ /* set port's status as default, and reset port */
+ if (hubInstance != NULL)
+ {
+ hubInstance->portList[portNumber - 1].deviceHandle = NULL;
+ hubInstance->portList[portNumber - 1].portStatus = kPortRunInvalid;
+ if (hubInstance->portProcess == portNumber)
+ {
+ hubInstance->portProcess = 0;
+ }
+ USB_HostHubSendPortReset(hubInstance, portNumber);
+ }
+ return kStatus_USB_Error;
+}
+
+/*!
+ * @brief get device's high-speed hub's address.
+ *
+ * @param parent_hub_no device's parent hub's address.
+ *
+ * @return hub number.
+ */
+uint32_t USB_HostHubGetHsHubNumber(uint8_t parentHubNo)
+{
+ usb_host_hub_instance_t *hubInstance = s_HubGlobal.hubList;
+ uint32_t deviceInfo;
+ uint32_t hubNumber;
+
+ /* get parentHubNo's hub instance handle */
+ while (hubInstance != NULL)
+ {
+ USB_HostHelperGetPeripheralInformation(hubInstance->deviceHandle, kUSB_HostGetDeviceAddress, &deviceInfo);
+ if (parentHubNo == deviceInfo)
+ {
+ break;
+ }
+ hubInstance = hubInstance->next;
+ }
+ if (hubInstance != NULL)
+ {
+ USB_HostHelperGetPeripheralInformation(hubInstance->deviceHandle, kUSB_HostGetDeviceSpeed, &deviceInfo);
+ if (deviceInfo == USB_SPEED_HIGH) /* parent hub is HS */
+ {
+ hubNumber = parentHubNo;
+ }
+ else /* parent hub is not HS */
+ {
+ USB_HostHelperGetPeripheralInformation(hubInstance->deviceHandle, kUSB_HostGetDeviceHSHubNumber,
+ &hubNumber);
+ }
+ return hubNumber;
+ }
+ return 0;
+}
+
+/*!
+ * @brief get device's high-speed hub's port number.
+ *
+ * @param parent_hub_no device's parent hub's address.
+ * @param parent_port_no device's parent port no.
+ *
+ * @return port number.
+ */
+uint32_t USB_HostHubGetHsHubPort(uint8_t parentHubNo, uint8_t parentPortNo)
+{
+ usb_host_hub_instance_t *hubInstance = s_HubGlobal.hubList;
+ uint32_t deviceInfo;
+ uint32_t hubPort;
+
+ /* get parentHubNo's hub instance handle */
+ while (hubInstance != NULL)
+ {
+ USB_HostHelperGetPeripheralInformation(hubInstance->deviceHandle, kUSB_HostGetDeviceAddress, &deviceInfo);
+ if (parentHubNo == deviceInfo)
+ {
+ break;
+ }
+ hubInstance = hubInstance->next;
+ }
+ if (hubInstance != NULL)
+ {
+ USB_HostHelperGetPeripheralInformation(hubInstance->deviceHandle, kUSB_HostGetDeviceSpeed, &deviceInfo);
+ if (deviceInfo == USB_SPEED_HIGH) /* parent hub is HS */
+ {
+ hubPort = parentPortNo;
+ }
+ else /* parent hub is not HS */
+ {
+ USB_HostHelperGetPeripheralInformation(hubInstance->deviceHandle, kUSB_HostGetDeviceHSHubNumber, &hubPort);
+ }
+ return hubPort;
+ }
+ return 0;
+}
+
+/*!
+ * @brief get device's hub total think time.
+ *
+ * @param parent_hub_no device's parent hub's address.
+ *
+ * @return think time value.
+ */
+uint32_t USB_HostHubGetTotalThinkTime(uint8_t parentHubNo)
+{
+ usb_host_hub_instance_t *hubInstance = s_HubGlobal.hubList;
+ uint32_t deviceAddress;
+
+ /* get parentHubNo's hub instance handle */
+ while (hubInstance != NULL)
+ {
+ USB_HostHelperGetPeripheralInformation(hubInstance->deviceHandle, kUSB_HostGetDeviceAddress, &deviceAddress);
+ if (parentHubNo == deviceAddress)
+ {
+ break;
+ }
+ hubInstance = hubInstance->next;
+ }
+ if (hubInstance != NULL)
+ {
+ return hubInstance->totalThinktime;
+ }
+ return 0;
+}
+
+#endif /* USB_HOST_CONFIG_HUB */
diff --git a/usb_1.1.0/host/class/usb_host_hub_app.h b/usb_1.1.0/host/class/usb_host_hub_app.h
new file mode 100644
index 0000000..fd7df5b
--- /dev/null
+++ b/usb_1.1.0/host/class/usb_host_hub_app.h
@@ -0,0 +1,103 @@
+/*
+ * Copyright (c) 2015, Freescale Semiconductor, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * o Redistributions of source code must retain the above copyright notice, this list
+ * of conditions and the following disclaimer.
+ *
+ * o Redistributions in binary form must reproduce the above copyright notice, this
+ * list of conditions and the following disclaimer in the documentation and/or
+ * other materials provided with the distribution.
+ *
+ * o Neither the name of Freescale Semiconductor, Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _USB_HOST_HUB_APP_H_
+#define _USB_HOST_HUB_APP_H_
+
+#if ((defined USB_HOST_CONFIG_HUB) && (USB_HOST_CONFIG_HUB))
+
+/*******************************************************************************
+ * Definitions
+ ******************************************************************************/
+
+/*! @brief HUB reset times*/
+#define USB_HOST_HUB_PORT_RESET_TIMES (1)
+
+/*! @brief HUB lock */
+#define USB_HostHubLock() USB_OsaMutexLock(s_HubGlobal.hubMutex)
+/*! @brief HUB unlock */
+#define USB_HostHubUnlock() USB_OsaMutexUnlock(s_HubGlobal.hubMutex)
+
+/*! @brief HUB application global structure */
+typedef struct _usb_host_hub_global
+{
+ usb_host_handle hostHandle; /*!< This HUB list belong to this host*/
+ usb_host_hub_instance_t *hubProcess; /*!< HUB in processing*/
+ usb_host_hub_instance_t *hubList; /*!< host's HUB list*/
+ usb_osa_mutex_handle hubMutex; /*!< HUB mutex*/
+} usb_host_hub_global_t;
+
+/*! @brief HUB application status */
+typedef enum _usb_host_hub_app_status
+{
+ kHubRunIdle = 0, /*!< Idle */
+ kHubRunInvalid, /*!< Invalid state */
+ kHubRunWaitSetInterface, /*!< Wait callback of set interface */
+ kHubRunGetDescriptor7, /*!< Get 7 bytes HUB descriptor */
+ kHubRunGetDescriptor, /*!< Get all HUB descriptor */
+ kHubRunSetPortPower, /*!< Set HUB's port power */
+ kHubRunGetStatusDone, /*!< HUB status changed */
+} usb_host_hub_app_status_t;
+
+/*! @brief HUB port application status */
+typedef enum _usb_host_port_app_status
+{
+ kPortRunIdle = 0, /*!< Idle */
+ kPortRunInvalid, /*!< Invalid state */
+ kPortRunWaitPortChange, /*!< Wait port status change */
+ kPortRunCheckCPortConnection, /*!< Check C_PORT_CONNECTION */
+ kPortRunGetPortConnection, /*!< Get port status data */
+ kPortRunCheckPortConnection, /*!< Check PORT_CONNECTION */
+ kPortRunWaitPortResetDone, /*!< Wait port reset transfer done */
+ kPortRunWaitCPortReset, /*!< Wait C_PORT_RESET */
+ KPortRunCheckCPortReset, /*!< Check C_PORT_RESET */
+ kPortRunResetAgain, /*!< Reset port again */
+ kPortRunPortAttached, /*!< Device is attached on the port */
+ kPortRunCheckPortDetach, /*!< Check port is detached */
+ kPortRunGetConnectionBit, /*!< Get the port status data */
+ kPortRunCheckConnectionBit, /*!< Check PORT_CONNECTION */
+} usb_host_port_app_status_t;
+
+/*! @brief HUB data prime status */
+typedef enum _usb_host_hub_prime_status
+{
+ kPrimeNone = 0, /*!< Don't prime data*/
+ kPrimeHubControl, /*!< Prime HUB control transfer*/
+ kPrimePortControl, /*!< Prime port control transfer*/
+ kPrimeInterrupt, /*!< Prime interrupt transfer*/
+} usb_host_hub_prime_status_t;
+
+/*******************************************************************************
+ * API
+ ******************************************************************************/
+
+#endif /* USB_HOST_CONFIG_HUB */
+
+#endif /* _USB_HOST_HUB_APP_H_ */
diff --git a/usb_1.1.0/host/class/usb_host_msd.c b/usb_1.1.0/host/class/usb_host_msd.c
new file mode 100644
index 0000000..ecb9706
--- /dev/null
+++ b/usb_1.1.0/host/class/usb_host_msd.c
@@ -0,0 +1,1155 @@
+/*
+ * Copyright (c) 2015 - 2016, Freescale Semiconductor, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * o Redistributions of source code must retain the above copyright notice, this list
+ * of conditions and the following disclaimer.
+ *
+ * o Redistributions in binary form must reproduce the above copyright notice, this
+ * list of conditions and the following disclaimer in the documentation and/or
+ * other materials provided with the distribution.
+ *
+ * o Neither the name of Freescale Semiconductor, Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "usb_host_config.h"
+#if ((defined USB_HOST_CONFIG_MSD) && (USB_HOST_CONFIG_MSD))
+#include "usb_host.h"
+#include "usb_host_msd.h"
+#include "usb_host_hci.h"
+
+/*******************************************************************************
+ * Definitions
+ ******************************************************************************/
+
+/*******************************************************************************
+ * Prototypes
+ ******************************************************************************/
+
+/*!
+ * @brief clear stall transfer callback.
+ *
+ * @param param callback parameter.
+ * @param transfer transfer.
+ * @param status transfer result status.
+ */
+static void USB_HostMsdClearHaltCallback(void *param, usb_host_transfer_t *transfer, usb_status_t status);
+
+/*!
+ * @brief send clear stall transfer.
+ *
+ * @param msdInstance msd instance pointer.
+ * @param callbackFn callback function.
+ * @param endpoint endpoint address.
+ *
+ * @return An error code or kStatus_USB_Success.
+ */
+static usb_status_t USB_HostMsdClearHalt(usb_host_msd_instance_t *msdInstance,
+ host_inner_transfer_callback_t callbackFn,
+ uint8_t endpoint);
+
+/*!
+ * @brief mass storage reset three step processes are done.
+ *
+ * @param msdInstance msd instance pointer.
+ * @param status result status.
+ */
+static void USB_HostMsdResetDone(usb_host_msd_instance_t *msdInstance, usb_status_t status);
+
+/*!
+ * @brief mass storage reset process step 3 callback.
+ *
+ * @param msdInstance msd instance pointer.
+ * @param transfer transfer
+ * @param status result status.
+ */
+static void USB_HostMsdMassResetClearOutCallback(void *param, usb_host_transfer_t *transfer, usb_status_t status);
+
+/*!
+ * @brief mass storage reset process step 2 callback.
+ *
+ * @param msdInstance msd instance pointer.
+ * @transfer transfer
+ * @param status result status.
+ */
+static void USB_HostMsdMassResetClearInCallback(void *param, usb_host_transfer_t *transfer, usb_status_t status);
+
+/*!
+ * @brief mass storage reset process step 1 callback.
+ *
+ * @param msdInstance msd instance pointer.
+ * @param transfer transfer
+ * @param status result status.
+ */
+static void USB_HostMsdMassResetCallback(void *param, usb_host_transfer_t *transfer, usb_status_t status);
+
+/*!
+ * @brief mass storage control transfer callback function.
+ *
+ * @param msdInstance msd instance pointer.
+ * @param transfer transfer
+ * @param status result status.
+ */
+static void USB_HostMsdControlCallback(void *param, usb_host_transfer_t *transfer, usb_status_t status);
+
+/*!
+ * @brief this function is called when ufi command is done.
+ *
+ * @param msdInstance msd instance pointer.
+ */
+static void USB_HostMsdCommandDone(usb_host_msd_instance_t *msdInstance, usb_status_t status);
+
+/*!
+ * @brief csw transfer callback.
+ *
+ * @param msdInstance msd instance pointer.
+ * @param transfer transfer
+ * @param status result status.
+ */
+static void USB_HostMsdCswCallback(void *param, usb_host_transfer_t *transfer, usb_status_t status);
+
+/*!
+ * @brief cbw transfer callback.
+ *
+ * @param msdInstance msd instance pointer.
+ * @param transfer transfer
+ * @param status result status.
+ */
+static void USB_HostMsdCbwCallback(void *param, usb_host_transfer_t *transfer, usb_status_t status);
+
+/*!
+ * @brief data transfer callback.
+ *
+ * @param msdInstance sd instance pointer.
+ * @param transfer transfer
+ * @param status result status.
+ */
+static void USB_HostMsdDataCallback(void *param, usb_host_transfer_t *transfer, usb_status_t status);
+
+/*!
+ * @brief msd open interface.
+ *
+ * @param msdInstance msd instance pointer.
+ *
+ * @return kStatus_USB_Success or error codes.
+ */
+static usb_status_t USB_HostMsdOpenInterface(usb_host_msd_instance_t *msdInstance);
+
+/*!
+ * @brief msd set interface callback, open pipes.
+ *
+ * @param param callback parameter.
+ * @param transfer callback transfer.
+ * @param status transfer status.
+ */
+static void USB_HostMsdSetInterfaceCallback(void *param, usb_host_transfer_t *transfer, usb_status_t status);
+
+/*!
+ * @brief msd control transfer common code.
+ *
+ * This function allocate the resource for msd instance.
+ *
+ * @param msdInstance the msd class instance.
+ * @param pipeCallbackFn inner callback function.
+ * @param callbackFn callback function.
+ * @param callbackParam callback parameter.
+ * @param buffer buffer pointer.
+ * @param bufferLength buffer length.
+ * @param requestType request type.
+ * @param requestValue request value.
+ *
+ * @return An error code or kStatus_USB_Success.
+ */
+static usb_status_t USB_HostMsdControl(usb_host_msd_instance_t *msdInstance,
+ host_inner_transfer_callback_t pipeCallbackFn,
+ transfer_callback_t callbackFn,
+ void *callbackParam,
+ uint8_t *buffer,
+ uint16_t bufferLength,
+ uint8_t requestType,
+ uint8_t requestValue);
+
+/*!
+ * @brief command process function, this function is called many time for one command's different state.
+ *
+ * @param msdInstance the msd class instance.
+ *
+ * @return An error code or kStatus_USB_Success.
+ */
+static usb_status_t USB_HostMsdProcessCommand(usb_host_msd_instance_t *msdInstance);
+
+/*******************************************************************************
+ * Variables
+ ******************************************************************************/
+
+/*******************************************************************************
+ * Code
+ ******************************************************************************/
+
+static void USB_HostMsdClearHaltCallback(void *param, usb_host_transfer_t *transfer, usb_status_t status)
+{
+ usb_host_msd_instance_t *msdInstance = (usb_host_msd_instance_t *)param;
+
+ if (status != kStatus_USB_Success)
+ {
+ USB_HostMsdCommandDone(msdInstance, kStatus_USB_TransferCancel);
+ }
+
+ if (msdInstance->commandStatus == kMSD_CommandErrorDone)
+ {
+ USB_HostMsdCommandDone(msdInstance, kStatus_USB_Error); /* command fail */
+ }
+ else
+ {
+ USB_HostMsdProcessCommand(msdInstance); /* continue to process ufi command */
+ }
+}
+
+static usb_status_t USB_HostMsdClearHalt(usb_host_msd_instance_t *msdInstance,
+ host_inner_transfer_callback_t callbackFn,
+ uint8_t endpoint)
+{
+ usb_status_t status;
+ usb_host_transfer_t *transfer;
+
+ /* malloc one transfer */
+ status = USB_HostMallocTransfer(msdInstance->hostHandle, &transfer);
+ if (status != kStatus_USB_Success)
+ {
+#ifdef HOST_ECHO
+ usb_echo("allocate transfer error\r\n");
+#endif
+ return status;
+ }
+ /* save the application callback function */
+ msdInstance->controlCallbackFn = NULL;
+ msdInstance->controlCallbackParam = NULL;
+ /* initialize transfer */
+ transfer->callbackFn = callbackFn;
+ transfer->callbackParam = msdInstance;
+ transfer->transferBuffer = NULL;
+ transfer->transferLength = 0;
+ transfer->setupPacket.bRequest = USB_REQUEST_STANDARD_CLEAR_FEATURE;
+ transfer->setupPacket.bmRequestType = USB_REQUEST_TYPE_RECIPIENT_ENDPOINT;
+ transfer->setupPacket.wValue = USB_SHORT_TO_LITTLE_ENDIAN(USB_REQUEST_STANDARD_FEATURE_SELECTOR_ENDPOINT_HALT);
+ transfer->setupPacket.wIndex = USB_SHORT_TO_LITTLE_ENDIAN(endpoint);
+ transfer->setupPacket.wLength = 0;
+ status = USB_HostSendSetup(msdInstance->hostHandle, msdInstance->controlPipe, transfer);
+
+ if (status != kStatus_USB_Success)
+ {
+ USB_HostFreeTransfer(msdInstance->hostHandle, transfer);
+ }
+ msdInstance->controlTransfer = transfer;
+
+ return status;
+}
+
+static void USB_HostMsdResetDone(usb_host_msd_instance_t *msdInstance, usb_status_t status)
+{
+ if (msdInstance->internalResetRecovery == 1) /* internal mass reset recovery */
+ {
+ msdInstance->internalResetRecovery = 0;
+
+ if ((status != kStatus_USB_Success) || (msdInstance->commandStatus == kMSD_CommandErrorDone))
+ {
+ USB_HostMsdCommandDone(msdInstance, kStatus_USB_Error); /* command fail */
+ }
+ else
+ {
+ USB_HostMsdProcessCommand(msdInstance); /* continue to process ufi command */
+ }
+ }
+ else /* user call mass storage reset recovery */
+ {
+ if (msdInstance->controlCallbackFn != NULL)
+ {
+ msdInstance->controlCallbackFn(msdInstance->controlCallbackParam, NULL, 0,
+ status); /* callback to application */
+ }
+ }
+}
+
+static void USB_HostMsdMassResetClearOutCallback(void *param, usb_host_transfer_t *transfer, usb_status_t status)
+{
+ usb_host_msd_instance_t *msdInstance = (usb_host_msd_instance_t *)param;
+
+ msdInstance->controlTransfer = NULL;
+ USB_HostFreeTransfer(msdInstance->hostHandle, transfer);
+ USB_HostMsdResetDone(msdInstance, status); /* mass storage reset done */
+}
+
+static void USB_HostMsdMassResetClearInCallback(void *param, usb_host_transfer_t *transfer, usb_status_t status)
+{
+ usb_host_msd_instance_t *msdInstance = (usb_host_msd_instance_t *)param;
+
+ msdInstance->controlTransfer = NULL;
+ USB_HostFreeTransfer(msdInstance->hostHandle, transfer);
+
+ if (status == kStatus_USB_Success)
+ {
+ if (msdInstance->outPipe != NULL)
+ {
+ /* continue to process mass storage reset */
+ USB_HostMsdClearHalt(
+ msdInstance, USB_HostMsdMassResetClearOutCallback,
+ (USB_REQUEST_TYPE_DIR_OUT | ((usb_host_pipe_t *)msdInstance->outPipe)->endpointAddress));
+ }
+ }
+ else
+ {
+ USB_HostMsdResetDone(msdInstance, status); /* mass storage reset done */
+ }
+}
+
+static void USB_HostMsdMassResetCallback(void *param, usb_host_transfer_t *transfer, usb_status_t status)
+{
+ usb_host_msd_instance_t *msdInstance = (usb_host_msd_instance_t *)param;
+
+ msdInstance->controlTransfer = NULL;
+ USB_HostFreeTransfer(msdInstance->hostHandle, transfer);
+ if (status == kStatus_USB_Success)
+ {
+ if (msdInstance->inPipe != NULL)
+ {
+ /* continue to process mass storage reset */
+ USB_HostMsdClearHalt(msdInstance, USB_HostMsdMassResetClearInCallback,
+ (USB_REQUEST_TYPE_DIR_IN | ((usb_host_pipe_t *)msdInstance->inPipe)->endpointAddress));
+ }
+ }
+ else
+ {
+ USB_HostMsdResetDone(msdInstance, status); /* mass storage reset done */
+ }
+}
+
+static void USB_HostMsdControlCallback(void *param, usb_host_transfer_t *transfer, usb_status_t status)
+{
+ usb_host_msd_instance_t *msdInstance = (usb_host_msd_instance_t *)param;
+
+ msdInstance->controlTransfer = NULL;
+ if (msdInstance->controlCallbackFn != NULL)
+ {
+ msdInstance->controlCallbackFn(msdInstance->controlCallbackParam, transfer->transferBuffer,
+ transfer->transferSofar, status); /* callback to application */
+ }
+ USB_HostFreeTransfer(msdInstance->hostHandle, transfer);
+}
+
+static void USB_HostMsdCommandDone(usb_host_msd_instance_t *msdInstance, usb_status_t status)
+{
+ if (msdInstance->commandCallbackFn != NULL)
+ {
+ /* callback to application */
+ msdInstance->commandCallbackFn(msdInstance->commandCallbackParam, msdInstance->msdCommand.dataBuffer,
+ msdInstance->msdCommand.dataSofar, status);
+ }
+ msdInstance->commandStatus = kMSD_CommandIdle;
+}
+
+static void USB_HostMsdCswCallback(void *param, usb_host_transfer_t *transfer, usb_status_t status)
+{
+ usb_host_msd_instance_t *msdInstance = (usb_host_msd_instance_t *)param;
+
+ if (status == kStatus_USB_Success)
+ {
+ /* kStatus_USB_Success */
+ if ((transfer->transferSofar == 13) &&
+ (msdInstance->msdCommand.cswBlock.CSWSignature == USB_HOST_MSD_CSW_SIGNATURE))
+ {
+ switch (msdInstance->msdCommand.cswBlock.CSWStatus)
+ {
+ case 0:
+ USB_HostMsdCommandDone(msdInstance, kStatus_USB_Success);
+ break;
+
+ case 1:
+ USB_HostMsdCommandDone(msdInstance, kStatus_USB_MSDStatusFail);
+ break;
+
+ case 2:
+ msdInstance->internalResetRecovery = 1;
+ msdInstance->commandStatus = kMSD_CommandErrorDone;
+ if (USB_HostMsdMassStorageReset(msdInstance, NULL, NULL) != kStatus_USB_Success)
+ {
+ USB_HostMsdCommandDone(msdInstance, kStatus_USB_Error);
+ }
+ break;
+
+ default:
+ USB_HostMsdCommandDone(msdInstance, kStatus_USB_MSDStatusFail);
+ break;
+ }
+ }
+ else
+ {
+ /* mass reset recovery to end ufi command */
+ msdInstance->internalResetRecovery = 1;
+ msdInstance->commandStatus = kMSD_CommandErrorDone;
+ if (USB_HostMsdMassStorageReset(msdInstance, NULL, NULL) != kStatus_USB_Success)
+ {
+ USB_HostMsdCommandDone(msdInstance, kStatus_USB_Error);
+ }
+ }
+ }
+ else
+ {
+ if (status == kStatus_USB_TransferStall) /* case 1: stall */
+ {
+ if (msdInstance->msdCommand.retryTime > 0)
+ {
+ msdInstance->msdCommand.retryTime--; /* retry reduce when error */
+ }
+ if (msdInstance->msdCommand.retryTime > 0)
+ {
+ /* clear stall to continue the ufi command */
+ if (USB_HostMsdClearHalt(
+ msdInstance, USB_HostMsdClearHaltCallback,
+ (USB_REQUEST_TYPE_DIR_IN | ((usb_host_pipe_t *)msdInstance->inPipe)->endpointAddress)) !=
+ kStatus_USB_Success)
+ {
+ USB_HostMsdCommandDone(msdInstance, kStatus_USB_Error);
+ }
+ }
+ else
+ {
+ /* mass reset recovery to continue ufi command */
+ msdInstance->internalResetRecovery = 1;
+ msdInstance->commandStatus = kMSD_CommandErrorDone;
+ if (USB_HostMsdMassStorageReset(msdInstance, NULL, NULL) != kStatus_USB_Success)
+ {
+ USB_HostMsdCommandDone(msdInstance, kStatus_USB_Error);
+ }
+ }
+ }
+ else if (status == kStatus_USB_TransferCancel) /* case 2: cancel */
+ {
+ USB_HostMsdCommandDone(msdInstance, status); /* command cancel */
+ }
+ else /* case 3: error */
+ {
+ if (msdInstance->msdCommand.retryTime > 0)
+ {
+ msdInstance->msdCommand.retryTime--; /* retry reduce when error */
+ }
+ if (msdInstance->msdCommand.retryTime > 0)
+ {
+ USB_HostMsdProcessCommand(msdInstance); /* retry the last step transaction */
+ }
+ else
+ {
+ /* mass reset recovery to continue ufi command */
+ msdInstance->internalResetRecovery = 1;
+ msdInstance->commandStatus = kMSD_CommandErrorDone;
+ if (USB_HostMsdMassStorageReset(msdInstance, NULL, NULL) != kStatus_USB_Success)
+ {
+ USB_HostMsdCommandDone(msdInstance, kStatus_USB_Error);
+ }
+ }
+ }
+ }
+}
+
+static void USB_HostMsdCbwCallback(void *param, usb_host_transfer_t *transfer, usb_status_t status)
+{
+ usb_host_msd_instance_t *msdInstance = (usb_host_msd_instance_t *)param;
+
+ if (status == kStatus_USB_Success)
+ {
+ /* kStatus_USB_Success */
+ if (transfer->transferSofar == USB_HOST_UFI_CBW_LENGTH)
+ {
+ msdInstance->commandStatus = kMSD_CommandTransferData;
+ USB_HostMsdProcessCommand(msdInstance); /* continue to process ufi command */
+ }
+ else
+ {
+ if (msdInstance->msdCommand.retryTime > 0)
+ {
+ msdInstance->msdCommand.retryTime--;
+ }
+ if (msdInstance->msdCommand.retryTime > 0)
+ {
+ USB_HostMsdProcessCommand(msdInstance); /* retry the last step transaction */
+ }
+ else
+ {
+ /* mass reset recovery to continue ufi command */
+ msdInstance->internalResetRecovery = 1;
+ msdInstance->commandStatus = kMSD_CommandErrorDone;
+ if (USB_HostMsdMassStorageReset(msdInstance, NULL, NULL) != kStatus_USB_Success)
+ {
+ USB_HostMsdCommandDone(msdInstance, kStatus_USB_Error);
+ }
+ }
+ }
+ }
+ else
+ {
+ if (status == kStatus_USB_TransferStall) /* case 1: stall */
+ {
+ if (msdInstance->msdCommand.retryTime > 0)
+ {
+ msdInstance->msdCommand.retryTime--; /* retry reduce when error */
+ }
+ if (msdInstance->msdCommand.retryTime > 0)
+ {
+ /* clear stall to continue the ufi command */
+ if (USB_HostMsdClearHalt(
+ msdInstance, USB_HostMsdClearHaltCallback,
+ (USB_REQUEST_TYPE_DIR_OUT | ((usb_host_pipe_t *)msdInstance->inPipe)->endpointAddress)) !=
+ kStatus_USB_Success)
+ {
+ USB_HostMsdCommandDone(msdInstance, kStatus_USB_Error);
+ }
+ }
+ else
+ {
+ /* mass reset recovery to continue ufi command */
+ msdInstance->internalResetRecovery = 1;
+ msdInstance->commandStatus = kMSD_CommandErrorDone;
+ if (USB_HostMsdMassStorageReset(msdInstance, NULL, NULL) != kStatus_USB_Success)
+ {
+ USB_HostMsdCommandDone(msdInstance, kStatus_USB_Error);
+ }
+ }
+ }
+ else if (status == kStatus_USB_TransferCancel) /* case 2: cancel */
+ {
+ USB_HostMsdCommandDone(msdInstance, status); /* command cancel */
+ }
+ else /* case 3: error */
+ {
+ if (msdInstance->msdCommand.retryTime > 0)
+ {
+ msdInstance->msdCommand.retryTime--;
+ }
+ if (msdInstance->msdCommand.retryTime > 0)
+ {
+ USB_HostMsdProcessCommand(msdInstance); /* retry the last step transaction */
+ }
+ else
+ {
+ /* mass reset recovery to continue ufi command */
+ msdInstance->internalResetRecovery = 1;
+ msdInstance->commandStatus = kMSD_CommandErrorDone;
+ if (USB_HostMsdMassStorageReset(msdInstance, NULL, NULL) != kStatus_USB_Success)
+ {
+ USB_HostMsdCommandDone(msdInstance, kStatus_USB_Error);
+ }
+ }
+ }
+ return;
+ }
+}
+
+static void USB_HostMsdDataCallback(void *param, usb_host_transfer_t *transfer, usb_status_t status)
+{
+ usb_host_msd_instance_t *msdInstance = (usb_host_msd_instance_t *)param;
+ uint8_t direction;
+
+ if (status == kStatus_USB_Success)
+ {
+ /* kStatus_USB_Success */
+ msdInstance->msdCommand.dataSofar += transfer->transferSofar;
+ USB_HostMsdProcessCommand(msdInstance); /* continue to process ufi command */
+ }
+ else
+ {
+ if (status == kStatus_USB_TransferStall) /* case 1: stall */
+ {
+ if (msdInstance->msdCommand.retryTime > 0)
+ {
+ msdInstance->msdCommand.retryTime--; /* retry reduce when error */
+ }
+ if (transfer->direction == USB_IN)
+ {
+ direction = USB_REQUEST_TYPE_DIR_IN;
+ }
+ else
+ {
+ direction = USB_REQUEST_TYPE_DIR_OUT;
+ }
+
+ if (msdInstance->msdCommand.retryTime == 0)
+ {
+ msdInstance->commandStatus = kMSD_CommandTransferCSW; /* next step */
+ }
+ /* clear stall to continue the ufi command */
+ if (USB_HostMsdClearHalt(msdInstance, USB_HostMsdClearHaltCallback,
+ (direction | ((usb_host_pipe_t *)msdInstance->inPipe)->endpointAddress)) !=
+ kStatus_USB_Success)
+ {
+ USB_HostMsdCommandDone(msdInstance, kStatus_USB_Error);
+ }
+ }
+ else if (status == kStatus_USB_TransferCancel) /* case 2: cancel */
+ {
+ USB_HostMsdCommandDone(msdInstance, status); /* command cancel */
+ }
+ else /* case 3: error */
+ {
+ /* mass reset recovery to finish ufi command */
+ msdInstance->internalResetRecovery = 1;
+ msdInstance->commandStatus = kMSD_CommandErrorDone;
+ if (USB_HostMsdMassStorageReset(msdInstance, NULL, NULL) != kStatus_USB_Success)
+ {
+ USB_HostMsdCommandDone(msdInstance, kStatus_USB_Error);
+ }
+ }
+ }
+}
+
+static usb_status_t USB_HostMsdProcessCommand(usb_host_msd_instance_t *msdInstance)
+{
+ usb_status_t status = kStatus_USB_Success;
+ usb_host_transfer_t *transfer;
+
+ if (msdInstance->msdCommand.transfer == NULL)
+ {
+ /* malloc one transfer */
+ status = USB_HostMallocTransfer(msdInstance->hostHandle, &(msdInstance->msdCommand.transfer));
+ if (status != kStatus_USB_Success)
+ {
+ msdInstance->msdCommand.transfer = NULL;
+#ifdef HOST_ECHO
+ usb_echo("allocate transfer error\r\n");
+#endif
+ return kStatus_USB_Busy;
+ }
+ }
+ transfer = msdInstance->msdCommand.transfer;
+ switch (msdInstance->commandStatus)
+ {
+ case kMSD_CommandTransferCBW: /* ufi CBW phase */
+ transfer->direction = USB_OUT;
+ transfer->transferBuffer = (uint8_t *)(&(msdInstance->msdCommand.cbwBlock));
+ transfer->transferLength = USB_HOST_UFI_CBW_LENGTH;
+ transfer->callbackFn = USB_HostMsdCbwCallback;
+ transfer->callbackParam = msdInstance;
+ status = USB_HostSend(msdInstance->hostHandle, msdInstance->outPipe, transfer);
+ if (status != kStatus_USB_Success)
+ {
+#ifdef HOST_ECHO
+ usb_echo("host send error\r\n");
+#endif
+ }
+ break;
+
+ case kMSD_CommandTransferData: /* ufi DATA phase */
+ if (msdInstance->msdCommand.dataBuffer != NULL)
+ {
+ transfer->direction = msdInstance->msdCommand.dataDirection;
+ transfer->transferBuffer = (msdInstance->msdCommand.dataBuffer + msdInstance->msdCommand.dataSofar);
+ transfer->transferLength = (msdInstance->msdCommand.dataLength - msdInstance->msdCommand.dataSofar);
+ transfer->callbackParam = msdInstance;
+ if (msdInstance->msdCommand.dataSofar != msdInstance->msdCommand.dataLength)
+ {
+ if (transfer->direction == USB_OUT)
+ {
+ transfer->callbackFn = USB_HostMsdDataCallback;
+ status = USB_HostSend(msdInstance->hostHandle, msdInstance->outPipe, transfer);
+ if (status != kStatus_USB_Success)
+ {
+#ifdef HOST_ECHO
+ usb_echo("host send error\r\n");
+#endif
+ }
+ }
+ else
+ {
+ transfer->callbackFn = USB_HostMsdDataCallback;
+ status = USB_HostRecv(msdInstance->hostHandle, msdInstance->inPipe, transfer);
+ if (status != kStatus_USB_Success)
+ {
+#ifdef HOST_ECHO
+ usb_echo("host recv error\r\n");
+#endif
+ }
+ }
+ break;
+ }
+ else
+ {
+ /* don't break */
+ }
+ }
+ else
+ {
+ /* don't break */
+ }
+ case kMSD_CommandTransferCSW: /* ufi CSW phase */
+ transfer->direction = USB_IN;
+ transfer->transferBuffer = (uint8_t *)&msdInstance->msdCommand.cswBlock;
+ transfer->transferLength = sizeof(usb_host_csw_t);
+ transfer->callbackFn = USB_HostMsdCswCallback;
+ transfer->callbackParam = msdInstance;
+ status = USB_HostRecv(msdInstance->hostHandle, msdInstance->inPipe, transfer);
+ if (status != kStatus_USB_Success)
+ {
+#ifdef HOST_ECHO
+ usb_echo("host recv error\r\n");
+#endif
+ }
+ break;
+
+ case kMSD_CommandDone:
+ USB_HostMsdCommandDone(msdInstance, kStatus_USB_Success);
+ break;
+
+ default:
+ break;
+ }
+ return status;
+}
+
+/*!
+ * @brief all ufi function calls this api.
+ *
+ * This function implements the common ufi commands.
+ *
+ * @param classHandle the class msd handle.
+ * @param buffer buffer pointer.
+ * @param bufferLength buffer length.
+ * @param callbackFn callback function.
+ * @param callbackParam callback parameter.
+ * @param direction command direction.
+ * @param byteValues ufi command fields value.
+ *
+ * @return An error code or kStatus_USB_Success.
+ */
+usb_status_t USB_HostMsdCommand(usb_host_class_handle classHandle,
+ uint8_t *buffer,
+ uint32_t bufferLength,
+ transfer_callback_t callbackFn,
+ void *callbackParam,
+ uint8_t direction,
+ uint8_t byteValues[10])
+{
+ usb_host_msd_instance_t *msdInstance = (usb_host_msd_instance_t *)classHandle;
+ usb_host_cbw_t *cbwPointer = &(msdInstance->msdCommand.cbwBlock);
+ uint8_t index = 0;
+
+ if (classHandle == NULL)
+ {
+ return kStatus_USB_InvalidHandle;
+ }
+
+ if (msdInstance->commandStatus != kMSD_CommandIdle)
+ {
+ return kStatus_USB_Busy;
+ }
+
+ /* save the application callback function */
+ msdInstance->commandCallbackFn = callbackFn;
+ msdInstance->commandCallbackParam = callbackParam;
+
+ /* initialize CBWCB fields */
+ for (index = 0; index < USB_HOST_UFI_BLOCK_DATA_VALID_LENGTH; ++index)
+ {
+ cbwPointer->CBWCB[index] = byteValues[index];
+ }
+
+ /* initialize CBW fields */
+ cbwPointer->CBWDataTransferLength = USB_LONG_TO_LITTLE_ENDIAN(bufferLength);
+ cbwPointer->CBWFlags = direction;
+ cbwPointer->CBWLun = (byteValues[1] >> USB_HOST_UFI_LOGICAL_UNIT_POSITION);
+ cbwPointer->CBWCBLength = USB_HOST_UFI_BLOCK_DATA_VALID_LENGTH;
+
+ msdInstance->commandStatus = kMSD_CommandTransferCBW;
+ if (direction == USB_HOST_MSD_CBW_FLAGS_DIRECTION_IN)
+ {
+ msdInstance->msdCommand.dataDirection = USB_IN;
+ }
+ else
+ {
+ msdInstance->msdCommand.dataDirection = USB_OUT;
+ }
+ msdInstance->msdCommand.dataBuffer = buffer;
+
+ msdInstance->msdCommand.dataLength = bufferLength;
+ msdInstance->msdCommand.dataSofar = 0;
+ msdInstance->msdCommand.retryTime = USB_HOST_MSD_RETRY_MAX_TIME;
+
+ return USB_HostMsdProcessCommand(msdInstance); /* start to process ufi command */
+}
+
+static usb_status_t USB_HostMsdOpenInterface(usb_host_msd_instance_t *msdInstance)
+{
+ usb_status_t status;
+ uint8_t epIndex = 0;
+ usb_host_pipe_init_t pipeInit;
+ usb_descriptor_endpoint_t *epDesc = NULL;
+ usb_host_interface_t *interfacePointer;
+
+ if (msdInstance->inPipe != NULL) /* close bulk in pipe if the pipe is open */
+ {
+ status = USB_HostClosePipe(msdInstance->hostHandle, msdInstance->inPipe);
+ if (status != kStatus_USB_Success)
+ {
+#ifdef HOST_ECHO
+ usb_echo("error when close pipe\r\n");
+#endif
+ }
+ msdInstance->inPipe = NULL;
+ }
+ if (msdInstance->outPipe != NULL) /* close bulk out pipe if the pipe is open */
+ {
+ status = USB_HostClosePipe(msdInstance->hostHandle, msdInstance->outPipe);
+ if (status != kStatus_USB_Success)
+ {
+#ifdef HOST_ECHO
+ usb_echo("error when close pipe\r\n");
+#endif
+ }
+ msdInstance->outPipe = NULL;
+ }
+
+ /* open interface pipes */
+ interfacePointer = (usb_host_interface_t *)msdInstance->interfaceHandle;
+ for (epIndex = 0; epIndex < interfacePointer->epCount; ++epIndex)
+ {
+ epDesc = interfacePointer->epList[epIndex].epDesc;
+ if (((epDesc->bEndpointAddress & USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_MASK) ==
+ USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_IN) &&
+ ((epDesc->bmAttributes & USB_DESCRIPTOR_ENDPOINT_ATTRIBUTE_TYPE_MASK) == USB_ENDPOINT_BULK))
+ {
+ pipeInit.devInstance = msdInstance->deviceHandle;
+ pipeInit.pipeType = USB_ENDPOINT_BULK;
+ pipeInit.direction = USB_IN;
+ pipeInit.endpointAddress = (epDesc->bEndpointAddress & USB_DESCRIPTOR_ENDPOINT_ADDRESS_NUMBER_MASK);
+ pipeInit.interval = epDesc->bInterval;
+ pipeInit.maxPacketSize = (uint16_t)(USB_SHORT_FROM_LITTLE_ENDIAN_ADDRESS(epDesc->wMaxPacketSize) &
+ USB_DESCRIPTOR_ENDPOINT_MAXPACKETSIZE_SIZE_MASK);
+ pipeInit.numberPerUframe = (USB_SHORT_FROM_LITTLE_ENDIAN_ADDRESS(epDesc->wMaxPacketSize) &
+ USB_DESCRIPTOR_ENDPOINT_MAXPACKETSIZE_MULT_TRANSACTIONS_MASK);
+ pipeInit.nakCount = USB_HOST_CONFIG_MAX_NAK;
+
+ status = USB_HostOpenPipe(msdInstance->hostHandle, &msdInstance->inPipe, &pipeInit);
+ if (status != kStatus_USB_Success)
+ {
+#ifdef HOST_ECHO
+ usb_echo("usb_host_hid_set_interface fail to open pipe\r\n");
+#endif
+ return status;
+ }
+ }
+ else if (((epDesc->bEndpointAddress & USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_MASK) ==
+ USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_OUT) &&
+ ((epDesc->bmAttributes & USB_DESCRIPTOR_ENDPOINT_ATTRIBUTE_TYPE_MASK) == USB_ENDPOINT_BULK))
+ {
+ pipeInit.devInstance = msdInstance->deviceHandle;
+ pipeInit.pipeType = USB_ENDPOINT_BULK;
+ pipeInit.direction = USB_OUT;
+ pipeInit.endpointAddress = (epDesc->bEndpointAddress & USB_DESCRIPTOR_ENDPOINT_ADDRESS_NUMBER_MASK);
+ pipeInit.interval = epDesc->bInterval;
+ pipeInit.maxPacketSize = (uint16_t)(USB_SHORT_FROM_LITTLE_ENDIAN_ADDRESS(epDesc->wMaxPacketSize) &
+ USB_DESCRIPTOR_ENDPOINT_MAXPACKETSIZE_SIZE_MASK);
+ pipeInit.numberPerUframe = (USB_SHORT_FROM_LITTLE_ENDIAN_ADDRESS(epDesc->wMaxPacketSize) &
+ USB_DESCRIPTOR_ENDPOINT_MAXPACKETSIZE_MULT_TRANSACTIONS_MASK);
+ pipeInit.nakCount = USB_HOST_CONFIG_MAX_NAK;
+
+ status = USB_HostOpenPipe(msdInstance->hostHandle, &msdInstance->outPipe, &pipeInit);
+ if (status != kStatus_USB_Success)
+ {
+#ifdef HOST_ECHO
+ usb_echo("usb_host_hid_set_interface fail to open pipe\r\n");
+#endif
+ return status;
+ }
+ }
+ else
+ {
+ }
+ }
+
+ return kStatus_USB_Success;
+}
+
+static void USB_HostMsdSetInterfaceCallback(void *param, usb_host_transfer_t *transfer, usb_status_t status)
+{
+ usb_host_msd_instance_t *msdInstance = (usb_host_msd_instance_t *)param;
+
+ msdInstance->controlTransfer = NULL;
+ if (status == kStatus_USB_Success)
+ {
+ status = USB_HostMsdOpenInterface(msdInstance); /* msd open interface */
+ }
+
+ if (msdInstance->controlCallbackFn != NULL)
+ {
+ msdInstance->controlCallbackFn(msdInstance->controlCallbackParam, NULL, 0,
+ status); /* callback to application */
+ }
+ USB_HostFreeTransfer(msdInstance->hostHandle, transfer);
+}
+
+usb_status_t USB_HostMsdInit(usb_device_handle deviceHandle, usb_host_class_handle *classHandle)
+{
+ uint32_t infoValue;
+ usb_status_t status;
+ usb_host_msd_instance_t *msdInstance = (usb_host_msd_instance_t *)USB_OsaMemoryAllocate(
+ sizeof(usb_host_msd_instance_t)); /* malloc msd class instance */
+
+ if (msdInstance == NULL)
+ {
+ return kStatus_USB_AllocFail;
+ }
+
+ /* initialize msd instance */
+ msdInstance->deviceHandle = deviceHandle;
+ msdInstance->interfaceHandle = NULL;
+ USB_HostHelperGetPeripheralInformation(deviceHandle, kUSB_HostGetHostHandle, &infoValue);
+ msdInstance->hostHandle = (usb_host_handle)infoValue;
+ USB_HostHelperGetPeripheralInformation(deviceHandle, kUSB_HostGetDeviceControlPipe, &infoValue);
+ msdInstance->controlPipe = (usb_host_pipe_handle)infoValue;
+
+ msdInstance->msdCommand.cbwBlock.CBWSignature = USB_LONG_TO_LITTLE_ENDIAN(USB_HOST_MSD_CBW_SIGNATURE);
+ status = USB_HostMallocTransfer(msdInstance->hostHandle, &(msdInstance->msdCommand.transfer));
+ if (status != kStatus_USB_Success)
+ {
+ msdInstance->msdCommand.transfer = NULL;
+#ifdef HOST_ECHO
+ usb_echo("allocate transfer error\r\n");
+#endif
+ }
+
+ *classHandle = msdInstance;
+ return kStatus_USB_Success;
+}
+
+usb_status_t USB_HostMsdSetInterface(usb_host_class_handle classHandle,
+ usb_host_interface_handle interfaceHandle,
+ uint8_t alternateSetting,
+ transfer_callback_t callbackFn,
+ void *callbackParam)
+{
+ usb_status_t status = kStatus_USB_Error;
+ usb_host_msd_instance_t *msdInstance = (usb_host_msd_instance_t *)classHandle;
+ usb_host_transfer_t *transfer;
+
+ if (classHandle == NULL)
+ {
+ return kStatus_USB_InvalidHandle;
+ }
+
+ status = USB_HostOpenDeviceInterface(msdInstance->deviceHandle,
+ interfaceHandle); /* notify host driver the interface is open */
+ if (status != kStatus_USB_Success)
+ {
+ return status;
+ }
+ msdInstance->interfaceHandle = interfaceHandle;
+
+ /* cancel transfers */
+ if (msdInstance->inPipe != NULL)
+ {
+ status = USB_HostCancelTransfer(msdInstance->hostHandle, msdInstance->inPipe, NULL);
+ if (status != kStatus_USB_Success)
+ {
+#ifdef HOST_ECHO
+ usb_echo("error when cancel pipe\r\n");
+#endif
+ }
+ }
+ if (msdInstance->outPipe != NULL)
+ {
+ status = USB_HostCancelTransfer(msdInstance->hostHandle, msdInstance->outPipe, NULL);
+ if (status != kStatus_USB_Success)
+ {
+#ifdef HOST_ECHO
+ usb_echo("error when cancel pipe\r\n");
+#endif
+ }
+ }
+
+ if (alternateSetting == 0) /* open interface directly */
+ {
+ if (callbackFn != NULL)
+ {
+ status = USB_HostMsdOpenInterface(msdInstance);
+ callbackFn(callbackParam, NULL, 0, status);
+ }
+ }
+ else /* send setup transfer */
+ {
+ /* malloc one transfer */
+ if (USB_HostMallocTransfer(msdInstance->hostHandle, &transfer) != kStatus_USB_Success)
+ {
+#ifdef HOST_ECHO
+ usb_echo("error to get transfer\r\n");
+#endif
+ return kStatus_USB_Busy;
+ }
+ /* save the application callback function */
+ msdInstance->controlCallbackFn = callbackFn;
+ msdInstance->controlCallbackParam = callbackParam;
+ /* initialize transfer */
+ transfer->callbackFn = USB_HostMsdSetInterfaceCallback;
+ transfer->callbackParam = msdInstance;
+ transfer->setupPacket.bRequest = USB_REQUEST_STANDARD_SET_INTERFACE;
+ transfer->setupPacket.bmRequestType = USB_REQUEST_TYPE_RECIPIENT_INTERFACE;
+ transfer->setupPacket.wIndex = USB_SHORT_TO_LITTLE_ENDIAN(
+ ((usb_host_interface_t *)msdInstance->interfaceHandle)->interfaceDesc->bInterfaceNumber);
+ transfer->setupPacket.wValue = USB_SHORT_TO_LITTLE_ENDIAN(alternateSetting);
+ transfer->setupPacket.wLength = 0;
+ transfer->transferBuffer = NULL;
+ transfer->transferLength = 0;
+ status = USB_HostSendSetup(msdInstance->hostHandle, msdInstance->controlPipe, transfer);
+
+ if (status == kStatus_USB_Success)
+ {
+ msdInstance->controlTransfer = transfer;
+ }
+ else
+ {
+ USB_HostFreeTransfer(msdInstance->hostHandle, transfer);
+ }
+ }
+
+ return status;
+}
+
+usb_status_t USB_HostMsdDeinit(usb_device_handle deviceHandle, usb_host_class_handle classHandle)
+{
+ usb_host_msd_instance_t *msdInstance = (usb_host_msd_instance_t *)classHandle;
+ usb_status_t status;
+
+ if (classHandle != NULL)
+ {
+ if (msdInstance->inPipe != NULL)
+ {
+ status = USB_HostCancelTransfer(msdInstance->hostHandle, msdInstance->inPipe, NULL); /* cancel pipe */
+ status = USB_HostClosePipe(msdInstance->hostHandle, msdInstance->inPipe); /* close pipe */
+ if (status != kStatus_USB_Success)
+ {
+#ifdef HOST_ECHO
+ usb_echo("error when close pipe\r\n");
+#endif
+ }
+ }
+ if (msdInstance->outPipe != NULL)
+ {
+ status = USB_HostCancelTransfer(msdInstance->hostHandle, msdInstance->outPipe, NULL); /* cancel pipe */
+ status = USB_HostClosePipe(msdInstance->hostHandle, msdInstance->outPipe); /* close pipe */
+ if (status != kStatus_USB_Success)
+ {
+#ifdef HOST_ECHO
+ usb_echo("error when close pipe\r\n");
+#endif
+ }
+ }
+ if ((msdInstance->controlPipe != NULL) &&
+ (msdInstance->controlTransfer != NULL)) /* cancel control transfer if there is on-going control transfer */
+ {
+ status =
+ USB_HostCancelTransfer(msdInstance->hostHandle, msdInstance->controlPipe, msdInstance->controlTransfer);
+ }
+ if (msdInstance->msdCommand.transfer)
+ {
+ USB_HostFreeTransfer(msdInstance->hostHandle, msdInstance->msdCommand.transfer);
+ }
+ USB_HostCloseDeviceInterface(deviceHandle,
+ msdInstance->interfaceHandle); /* notify host driver the interface is closed */
+ USB_OsaMemoryFree(msdInstance);
+ }
+ else
+ {
+ USB_HostCloseDeviceInterface(deviceHandle, NULL);
+ }
+
+ return kStatus_USB_Success;
+}
+
+static usb_status_t USB_HostMsdControl(usb_host_msd_instance_t *msdInstance,
+ host_inner_transfer_callback_t pipeCallbackFn,
+ transfer_callback_t callbackFn,
+ void *callbackParam,
+ uint8_t *buffer,
+ uint16_t bufferLength,
+ uint8_t requestType,
+ uint8_t requestValue)
+{
+ usb_host_transfer_t *transfer;
+
+ if (msdInstance == NULL)
+ {
+ return kStatus_USB_InvalidHandle;
+ }
+
+ /* malloc one transfer */
+ if (USB_HostMallocTransfer(msdInstance->hostHandle, &transfer) != kStatus_USB_Success)
+ {
+#ifdef HOST_ECHO
+ usb_echo("allocate transfer error\r\n");
+#endif
+ return kStatus_USB_Busy;
+ }
+ /* save the application callback function */
+ msdInstance->controlCallbackFn = callbackFn;
+ msdInstance->controlCallbackParam = callbackParam;
+ /* initialize transfer */
+ transfer->transferBuffer = buffer;
+ transfer->transferLength = bufferLength;
+ transfer->callbackFn = pipeCallbackFn;
+ transfer->callbackParam = msdInstance;
+
+ transfer->setupPacket.bmRequestType = requestType;
+ transfer->setupPacket.bRequest = requestValue;
+ transfer->setupPacket.wValue = 0x0000;
+ transfer->setupPacket.wIndex =
+ ((usb_host_interface_t *)msdInstance->interfaceHandle)->interfaceDesc->bInterfaceNumber;
+ transfer->setupPacket.wLength = bufferLength;
+
+ if (USB_HostSendSetup(msdInstance->hostHandle, msdInstance->controlPipe, transfer) !=
+ kStatus_USB_Success) /* call host driver api */
+ {
+ USB_HostFreeTransfer(msdInstance->hostHandle, transfer);
+ return kStatus_USB_Error;
+ }
+ msdInstance->controlTransfer = transfer;
+
+ return kStatus_USB_Success;
+}
+
+usb_status_t USB_HostMsdMassStorageReset(usb_host_class_handle classHandle,
+ transfer_callback_t callbackFn,
+ void *callbackParam)
+{
+ usb_host_msd_instance_t *msdInstance = (usb_host_msd_instance_t *)classHandle;
+
+ return USB_HostMsdControl(msdInstance, USB_HostMsdMassResetCallback, callbackFn, callbackParam, NULL, 0,
+ (USB_REQUEST_TYPE_TYPE_CLASS | USB_REQUEST_TYPE_RECIPIENT_INTERFACE),
+ USB_HOST_HID_MASS_STORAGE_RESET);
+}
+
+usb_status_t USB_HostMsdGetMaxLun(usb_host_class_handle classHandle,
+ uint8_t *logicalUnitNumber,
+ transfer_callback_t callbackFn,
+ void *callbackParam)
+{
+ usb_host_msd_instance_t *msdInstance = (usb_host_msd_instance_t *)classHandle;
+
+ return USB_HostMsdControl(
+ msdInstance, USB_HostMsdControlCallback, callbackFn, callbackParam, logicalUnitNumber, 1,
+ (USB_REQUEST_TYPE_DIR_IN | USB_REQUEST_TYPE_TYPE_CLASS | USB_REQUEST_TYPE_RECIPIENT_INTERFACE),
+ USB_HOST_HID_GET_MAX_LUN);
+}
+
+#endif /* USB_HOST_CONFIG_MSD */
diff --git a/usb_1.1.0/host/class/usb_host_msd.h b/usb_1.1.0/host/class/usb_host_msd.h
new file mode 100644
index 0000000..b062d9a
--- /dev/null
+++ b/usb_1.1.0/host/class/usb_host_msd.h
@@ -0,0 +1,872 @@
+/*
+ * Copyright (c) 2015, Freescale Semiconductor, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * o Redistributions of source code must retain the above copyright notice, this list
+ * of conditions and the following disclaimer.
+ *
+ * o Redistributions in binary form must reproduce the above copyright notice, this
+ * list of conditions and the following disclaimer in the documentation and/or
+ * other materials provided with the distribution.
+ *
+ * o Neither the name of Freescale Semiconductor, Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _USB_HOST_MSD_H_
+#define _USB_HOST_MSD_H_
+
+/*******************************************************************************
+ * MSD class private structure, enumeration, macro
+ ******************************************************************************/
+
+/*******************************************************************************
+ * Definitions
+ ******************************************************************************/
+
+/* CBW and CSW Macros */
+#define USB_HOST_MSD_CBW_FLAGS_DIRECTION_OUT (0x00U)
+#define USB_HOST_MSD_CBW_FLAGS_DIRECTION_IN (0x80U)
+#define USB_HOST_MSD_CBW_SIGNATURE (0x43425355U)
+#define USB_HOST_MSD_CSW_SIGNATURE (0x53425355U)
+
+/* UFI data bit macro */
+#define USB_HOST_UFI_BLOCK_DATA_VALID_LENGTH (10U)
+#define USB_HOST_UFI_LOGICAL_UNIT_POSITION (5U)
+#define USB_HOST_UFI_CBW_LENGTH (31U)
+#define USB_HOST_UFI_MODE_SENSE_PAGE_CONTROL_SHIFT (6U)
+#define USB_HOST_UFI_MODE_SENSE_PAGE_CODE_SHIFT (0U)
+#define USB_HOST_UFI_START_STOP_UNIT_LOEJ_SHIFT (1U)
+#define USB_HOST_UFI_START_STOP_UNIT_START_SHIFT (0U)
+#define USB_HOST_UFI_SEND_DIAGNOSTIC_SELF_TEST_SHIFT (2U)
+
+/*******************************************************************************
+ * MSD class public structure, enumeration, macro, function
+ ******************************************************************************/
+/*!
+ * @addtogroup usb_host_msc_drv
+ * @{
+ */
+
+/*! @brief retry time when transfer fail, when all the retries fail the transfer callback with error status */
+#define USB_HOST_MSD_RETRY_MAX_TIME (1U)
+/*! @brief mass storage block size */
+#define USB_HOST_MSD_BLOCK_SIZE (512U)
+
+/*! @brief MSD class code */
+#define USB_HOST_MSD_CLASS_CODE (8U)
+/*! @brief MSD sub-class code */
+#define USB_HOST_MSD_SUBCLASS_CODE_UFI (4U)
+/*! @brief MSD sub-class code */
+#define USB_HOST_MSD_SUBCLASS_CODE_SCSI (6U)
+/*! @brief MSD protocol code */
+#define USB_HOST_MSD_PROTOCOL_BULK (0x50U)
+
+/*! @brief MSD class-specific request (mass storage reset) */
+#define USB_HOST_HID_MASS_STORAGE_RESET (0xFFU)
+/*! @brief MSD class-specific request (get maximum logical unit number) */
+#define USB_HOST_HID_GET_MAX_LUN (0xFEU)
+
+/*! @brief UFI command process status */
+typedef enum _usb_host_msd_command_status
+{
+ kMSD_CommandIdle = 0,
+ kMSD_CommandTransferCBW,
+ kMSD_CommandTransferData,
+ kMSD_CommandTransferCSW,
+ kMSD_CommandDone,
+ kMSD_CommandCancel,
+ kMSD_CommandErrorDone,
+} usb_host_msd_command_status_t;
+
+/*! @brief MSC Bulk-Only command block wrapper (CBW) */
+typedef struct _usb_host_cbw
+{
+ uint32_t CBWSignature; /*!< Signature that helps identify this data packet as a CBW. The signature field shall
+ contain the value 43425355h (little endian), indicating a CBW */
+ uint32_t
+ CBWTag; /*!< A Command Block Tag sent by the host. The device shall echo the contents of this field back to the
+ host in the dCSWTag field of the associated CSW */
+ uint32_t CBWDataTransferLength; /*!< The number of bytes of data that the host expects to transfer on the Bulk-In or
+ Bulk-Out endpoint during the execution of this command */
+ uint8_t CBWFlags; /*!<
+ Bit 7 Direction - the device shall ignore this bit if the dCBWDataTransferLength field is
+ zero, otherwise:
+ 0 = Data-Out from host to the device,
+ 1 = Data-In from the device to the host.
+ Bit 6 Obsolete. The host shall set this bit to zero.
+ Bits 5..0 Reserved - the host shall set these bits to zero.
+ */
+ uint8_t CBWLun; /*!< The device Logical Unit Number (LUN) to which the command block is being sent */
+ uint8_t CBWCBLength; /*!< The valid length of the CBWCB in bytes. This defines the valid length of the command
+ block. The only legal values are 1 through 16 (01h through 10h).*/
+ uint8_t CBWCB[16]; /*!< The command block to be executed by the device*/
+} usb_host_cbw_t;
+
+/*! @brief MSC Bulk-Only command status wrapper (CSW) */
+typedef struct _usb_host_csw
+{
+ uint32_t CSWSignature; /*!< Signature that helps identify this data packet as a CSW. The signature field shall
+ contain the value 53425355h (little endian), indicating CSW.*/
+ uint32_t CSWTag; /*!< The device shall set this field to the value received in the dCBWTag of the associated CBW*/
+ uint32_t CSWDataResidue; /*!< the difference between the amount of data expected as stated in the
+ dCBWDataTransferLength and the actual amount of relevant data processed by the device.*/
+ uint8_t CSWStatus; /*!<
+ bCSWStatus indicates the success or failure of the command.
+ 00h - Command passed.
+ 01h - Command Failed.
+ 02h - Phase error.
+ others - Reserved.
+ */
+} usb_host_csw_t;
+
+/*! @brief MSC UFI command information structure */
+typedef struct _usb_host_msd_command
+{
+ usb_host_cbw_t cbwBlock; /*!< CBW data block*/
+ usb_host_csw_t cswBlock; /*!< CSW data block*/
+ uint8_t *dataBuffer; /*!< Data buffer pointer*/
+ uint32_t dataLength; /*!< Data buffer length*/
+ uint32_t dataSofar; /*!< Successful transfer data length*/
+ usb_host_transfer_t *transfer; /*!< The transfer is used for processing the UFI command*/
+ uint8_t retryTime; /*!< The UFI command residual retry time, when it reduce to zero the UFI command fail */
+ uint8_t dataDirection; /*!< The data direction, its value is USB_OUT or USB_IN*/
+} usb_host_msd_command_t;
+
+/*! @brief MSD instance structure, MSD usb_host_class_handle pointer to this structure */
+typedef struct _usb_host_msd_instance
+{
+ usb_host_handle hostHandle; /*!< This instance's related host handle*/
+ usb_device_handle deviceHandle; /*!< This instance's related device handle*/
+ usb_host_interface_handle interfaceHandle; /*!< This instance's related interface handle*/
+ usb_host_pipe_handle controlPipe; /*!< This instance's related device control pipe*/
+ usb_host_pipe_handle outPipe; /*!< MSD bulk out pipe*/
+ usb_host_pipe_handle inPipe; /*!< MSD bulk in pipe*/
+ transfer_callback_t commandCallbackFn; /*!< MSD UFI command callback function pointer*/
+ void *commandCallbackParam; /*!< MSD UFI command callback parameter*/
+ transfer_callback_t controlCallbackFn; /*!< MSD control transfer callback function pointer*/
+ void *controlCallbackParam; /*!< MSD control transfer callback parameter*/
+ usb_host_transfer_t *controlTransfer; /*!< Ongoing control transfer*/
+ usb_host_msd_command_t msdCommand; /*!< Ongoing MSD UFI command information*/
+ uint8_t commandStatus; /*!< UFI command process status, see command_status_t*/
+ uint8_t internalResetRecovery; /*!< 1 - class driver internal mass storage reset recovery is on-going; 0 -
+ application call USB_HostMsdMassStorageReset to reset or there is no reset*/
+} usb_host_msd_instance_t;
+
+/*! @brief UFI standard sense data structure */
+typedef struct _usb_host_ufi_sense_data
+{
+ uint8_t errorCode; /*!< This field shall contain a value of 70h to indicate current errors*/
+ uint8_t reserved1; /*!< Reserved field*/
+ uint8_t senseKey; /*!< Provide a hierarchy of error or command result information*/
+ uint8_t information[4]; /*!< This field is command-specific; it is typically used by some commands to return a
+ logical block address denoting where an error occurred*/
+ uint8_t additionalSenseLength; /*!< The UFI device sets the value of this field to ten, to indicate that ten more
+ bytes of sense data follow this field*/
+ uint8_t reserved2[4]; /*!< Reserved field*/
+ uint8_t additionalSenseCode; /*!< Provide a hierarchy of error or command result information*/
+ uint8_t additionalSenseCodeQualifier; /*!< Provide a hierarchy of error or command result information*/
+ uint8_t reserved3[4]; /*!< Reserved field*/
+} usb_host_ufi_sense_data_t;
+
+/*! @brief UFI standard inquiry data structure */
+typedef struct _usb_host_ufi_inquiry_data
+{
+ uint8_t peripheralDeviceType; /*!< Identifies the device currently connected to the requested logical unit*/
+ uint8_t removableMediaBit; /*!< This shall be set to one to indicate removable media*/
+ uint8_t version; /*!< Version*/
+ uint8_t responseDataFormat; /*!< A value of 01h shall be used for UFI device*/
+ uint8_t additionalLength; /*!< Specify the length in bytes of the parameters*/
+ uint8_t reserved1[3]; /*!< Reserved field*/
+ uint8_t vendorInformation[8]; /*!< Contains 8 bytes of ASCII data identifying the vendor of the product*/
+ uint8_t productIdentification[16]; /*!< Contains 16 bytes of ASCII data as defined by the vendor*/
+ uint8_t productRevisionLevel[4]; /*!< Contains 4 bytes of ASCII data as defined by the vendor*/
+} usb_host_ufi_inquiry_data_t;
+
+/*! @brief UFI read capacity data structure */
+typedef struct _usb_host_ufi_read_capacity
+{
+ uint8_t lastLogicalBlockAddress[4]; /*!< The logical block number*/
+ uint8_t blockLengthInBytes[4]; /*!< Block size*/
+} usb_host_ufi_read_capacity_t;
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*******************************************************************************
+ * API
+ ******************************************************************************/
+
+/*!
+ * @name USB host MSD class APIs
+ * @{
+ */
+
+/*!
+ * @brief Initializes the MSD instance.
+ *
+ * This function allocates the resources for the MSD instance.
+ *
+ * @param[in] deviceHandle The device handle.
+ * @param[out] classHandle Return class handle.
+ *
+ * @retval kStatus_USB_Success The device is initialized successfully.
+ * @retval kStatus_USB_AllocFail Allocate memory fail.
+ */
+extern usb_status_t USB_HostMsdInit(usb_device_handle deviceHandle, usb_host_class_handle *classHandle);
+
+/*!
+ * @brief Sets the interface.
+ *
+ * This function binds the interface with the MSD instance.
+ *
+ * @param[in] classHandle The class handle.
+ * @param[in] interfaceHandle The interface handle.
+ * @param[in] alternateSetting The alternate setting value.
+ * @param[in] callbackFn This callback is called after this function completes.
+ * @param[in] callbackParam The first parameter in the callback function.
+ *
+ * @retval kStatus_USB_Success The device is initialized successfully.
+ * @retval kStatus_USB_InvalidHandle The classHandle is NULL pointer.
+ * @retval kStatus_USB_Busy There is no idle transfer.
+ * @retval kStatus_USB_Error Send transfer fail. See the USB_HostSendSetup.
+ * @retval kStatus_USB_Success Callback return status, the command succeeded.
+ * @retval kStatus_USB_Busy Callback return status, there is no idle pipe.
+ * @retval kStatus_USB_TransferStall Callback return status, the transfer is stalled by the device.
+ * @retval kStatus_USB_Error Callback return status, open pipe fail. See the USB_HostOpenPipe.
+ */
+extern usb_status_t USB_HostMsdSetInterface(usb_host_class_handle classHandle,
+ usb_host_interface_handle interfaceHandle,
+ uint8_t alternateSetting,
+ transfer_callback_t callbackFn,
+ void *callbackParam);
+
+/*!
+ * @brief Deinitializes the MSD instance.
+ *
+ * This function frees the resource for the MSD instance.
+ *
+ * @param[in] deviceHandle The device handle.
+ * @param[in] classHandle The class handle.
+ *
+ * @retval kStatus_USB_Success The device is de-initialized successfully.
+ */
+extern usb_status_t USB_HostMsdDeinit(usb_device_handle deviceHandle, usb_host_class_handle classHandle);
+
+/*!
+ * @brief Mass storage reset.
+ *
+ * This function implements the mass storage reset request.
+ *
+ * @param[in] classHandle The class handle.
+ * @param[in] callbackFn This callback is called after this function completes.
+ * @param[in] callbackParam The first parameter in the callback function.
+ *
+ * @retval kStatus_USB_Success The device is initialized successfully.
+ * @retval kStatus_USB_InvalidHandle The classHandle is NULL pointer.
+ * @retval kStatus_USB_Busy There is no idle transfer.
+ * @retval kStatus_USB_Error Send transfer fail. See the USB_HostSendSetup.
+ */
+extern usb_status_t USB_HostMsdMassStorageReset(usb_host_class_handle classHandle,
+ transfer_callback_t callbackFn,
+ void *callbackParam);
+
+/*!
+ * @brief Gets the maximum logical unit number.
+ *
+ * This function implements the get maximum LUN request.
+ *
+ * @param[in] classHandle The class handle.
+ * @param[out] logicalUnitNumber Return logical unit number value.
+ * @param[in] callbackFn This callback is called after this function completes.
+ * @param[in] callbackParam The first parameter in the callback function.
+ *
+ * @retval kStatus_USB_Success The device is initialized successfully.
+ * @retval kStatus_USB_InvalidHandle The classHandle is NULL pointer.
+ * @retval kStatus_USB_Busy There is no idle transfer.
+ * @retval kStatus_USB_Error Send transfer fail. See the USB_HostSendSetup.
+ * @retval kStatus_USB_Success Callback return status, the command succeed.
+ * @retval kStatus_USB_MSDStatusFail Callback return status, the CSW status indicate this command fail.
+ * @retval kStatus_USB_Error Callback return status, the command fail.
+ */
+extern usb_status_t USB_HostMsdGetMaxLun(usb_host_class_handle classHandle,
+ uint8_t *logicalUnitNumber,
+ transfer_callback_t callbackFn,
+ void *callbackParam);
+
+/*!
+ * @brief Mass storage read (10).
+ *
+ * This function implements the UFI READ(10) command. This command requests that the UFI
+ * device transfer data to the host.
+ *
+ * @param[in] classHandle The class MSD handle.
+ * @param[in] logicalUnit Logical unit number.
+ * @param[in] blockAddress The start block address.
+ * @param[out] buffer Buffer pointer.
+ * @param[in] bufferLength The buffer length.
+ * @param[in] blockNumber Read block number.
+ * @param[in] callbackFn This callback is called after this command completes.
+ * @param[in] callbackParam The first parameter in the callback function.
+ *
+ * @retval kStatus_USB_Success The device is initialized successfully.
+ * @retval kStatus_USB_InvalidHandle The classHandle is NULL pointer.
+ * @retval kStatus_USB_Busy The previous command is executing or there is no idle transfer.
+ * @retval kStatus_USB_Error Send transfer fail. See the USB_HostSend/USB_HostRecv.
+ * @retval kStatus_USB_Success Callback return status, the command succeed.
+ * @retval kStatus_USB_MSDStatusFail Callback return status, the CSW status indicate this command fail.
+ * @retval kStatus_USB_Error Callback return status, the command fail.
+ */
+extern usb_status_t USB_HostMsdRead10(usb_host_class_handle classHandle,
+ uint8_t logicalUnit,
+ uint32_t blockAddress,
+ uint8_t *buffer,
+ uint32_t bufferLength,
+ uint32_t blockNumber,
+ transfer_callback_t callbackFn,
+ void *callbackParam);
+
+/*!
+ * @brief Mass storage read (12).
+ *
+ * This function implements the UFI READ(12) command and requests that the UFI
+ * device transfer data to the host.
+ *
+ * @param[in] classHandle The class MSD handle.
+ * @param[in] logicalUnit Logical unit number.
+ * @param[in] blockAddress The start block address.
+ * @param[out] buffer Buffer pointer.
+ * @param[in] bufferLength The buffer length.
+ * @param[in] blockNumber Read block number.
+ * @param[in] callbackFn This callback is called after this command completes.
+ * @param[in] callbackParam The first parameter in the callback function.
+ *
+ * @retval kStatus_USB_Success The device is initialized successfully.
+ * @retval kStatus_USB_InvalidHandle The classHandle is NULL pointer.
+ * @retval kStatus_USB_Busy The previous command is executing or there is no idle transfer.
+ * @retval kStatus_USB_Error Send transfer fail. See the USB_HostSend/USB_HostRecv.
+ * @retval kStatus_USB_Success Callback return status, the command succeed.
+ * @retval kStatus_USB_MSDStatusFail Callback return status, the CSW status indicate this command fail.
+ * @retval kStatus_USB_Error Callback return status, the command fail.
+ */
+extern usb_status_t USB_HostMsdRead12(usb_host_class_handle classHandle,
+ uint8_t logicalUnit,
+ uint32_t blockAddress,
+ uint8_t *buffer,
+ uint32_t bufferLength,
+ uint32_t blockNumber,
+ transfer_callback_t callbackFn,
+ void *callbackParam);
+
+/*!
+ * @brief Mass storage write (10).
+ *
+ * This function implements the UFI WRITE(10) command and requests that the UFI device
+ * write the data transferred by the host to the medium.
+ *
+ * @param[in] classHandle The class MSD handle.
+ * @param[in] logicalUnit Logical unit number.
+ * @param[in] blockAddress The start block address.
+ * @param[in] buffer Buffer pointer.
+ * @param[in] bufferLength The buffer length.
+ * @param[in] blockNumber Write block number.
+ * @param[in] callbackFn This callback is called after this command completes.
+ * @param[in] callbackParam The first parameter in the callback function.
+ *
+ * @retval kStatus_USB_Success The device is initialized successfully.
+ * @retval kStatus_USB_InvalidHandle The classHandle is NULL pointer.
+ * @retval kStatus_USB_Busy The previous command is executing or there is no idle transfer.
+ * @retval kStatus_USB_Error Send transfer fail. See the USB_HostSend/USB_HostRecv.
+ * @retval kStatus_USB_Success Callback return status, the command succeed.
+ * @retval kStatus_USB_MSDStatusFail Callback return status, the CSW status indicate this command fail.
+ * @retval kStatus_USB_Error Callback return status, the command fail.
+ */
+extern usb_status_t USB_HostMsdWrite10(usb_host_class_handle classHandle,
+ uint8_t logicalUnit,
+ uint32_t blockAddress,
+ uint8_t *buffer,
+ uint32_t bufferLength,
+ uint32_t blockNumber,
+ transfer_callback_t callbackFn,
+ void *callbackParam);
+
+/*!
+ * @brief Mass storage write (12).
+ *
+ * This function implements the UFI WRITE(12) command and requests that the UFI device
+ * write the data transferred by the host to the medium.
+ *
+ * @param[in] classHandle The class MSD handle.
+ * @param[in] logicalUnit Logical unit number.
+ * @param[in] blockAddress The start block address.
+ * @param[in] buffer Buffer pointer.
+ * @param[in] bufferLength The buffer length.
+ * @param[in] blockNumber Write block number.
+ * @param[in] callbackFn This callback is called after this command completes.
+ * @param[in] callbackParam The first parameter in the callback function.
+ *
+ * @retval kStatus_USB_Success The device is initialized successfully.
+ * @retval kStatus_USB_InvalidHandle The classHandle is NULL pointer.
+ * @retval kStatus_USB_Busy The previous command is executing or there is no idle transfer.
+ * @retval kStatus_USB_Error Send transfer fail. See the USB_HostSend/USB_HostRecv.
+ * @retval kStatus_USB_Success Callback return status, the command succeed.
+ * @retval kStatus_USB_MSDStatusFail Callback return status, the CSW status indicate this command fail.
+ * @retval kStatus_USB_Error Callback return status, the command fail.
+ */
+extern usb_status_t USB_HostMsdWrite12(usb_host_class_handle classHandle,
+ uint8_t logicalUnit,
+ uint32_t blockAddress,
+ uint8_t *buffer,
+ uint32_t bufferLength,
+ uint32_t blockNumber,
+ transfer_callback_t callbackFn,
+ void *callbackParam);
+
+/*!
+ * @brief Mass storage read capacity.
+ *
+ * This function implements the UFI READ CAPACITY command and allows the host to request
+ * capacities of the currently installed medium.
+ *
+ * @param[in] classHandle The class MSD handle.
+ * @param[in] logicalUnit Logical unit number.
+ * @param[out] buffer Buffer pointer.
+ * @param[in] bufferLength The buffer length.
+ * @param[in] callbackFn This callback is called after this command completes.
+ * @param[in] callbackParam The first parameter in the callback function.
+ *
+ * @retval kStatus_USB_Success The device is initialized successfully.
+ * @retval kStatus_USB_InvalidHandle The classHandle is NULL pointer.
+ * @retval kStatus_USB_Busy The previous command is executing or there is no idle transfer.
+ * @retval kStatus_USB_Error Send transfer fail. See the USB_HostSend/USB_HostRecv.
+ * @retval kStatus_USB_Success Callback return status, the command succeed.
+ * @retval kStatus_USB_MSDStatusFail Callback return status, the CSW status indicate this command fail.
+ * @retval kStatus_USB_Error Callback return status, the command fail.
+ */
+extern usb_status_t USB_HostMsdReadCapacity(usb_host_class_handle classHandle,
+ uint8_t logicalUnit,
+ uint8_t *buffer,
+ uint32_t bufferLength,
+ transfer_callback_t callbackFn,
+ void *callbackParam);
+
+/*!
+ * @brief Mass storage test unit ready.
+ *
+ * This function implements the UFI TEST UNIT READY command and
+ * checks if the UFI device is ready.
+ *
+ * @param[in] classHandle The class MSD handle.
+ * @param[in] logicalUnit Logical unit number.
+ * @param[in] callbackFn This callback is called after this command completes.
+ * @param[in] callbackParam The first parameter in the callback function.
+ *
+ * @retval kStatus_USB_Success The device is initialized successfully.
+ * @retval kStatus_USB_InvalidHandle The classHandle is NULL pointer.
+ * @retval kStatus_USB_Busy The previous command is executing or there is no idle transfer.
+ * @retval kStatus_USB_Error Send transfer fail. See the USB_HostSend/USB_HostRecv.
+ * @retval kStatus_USB_Success Callback return status, the command succeed.
+ * @retval kStatus_USB_MSDStatusFail Callback return status, the CSW status indicate this command fail.
+ * @retval kStatus_USB_Error Callback return status, the command fail.
+ */
+extern usb_status_t USB_HostMsdTestUnitReady(usb_host_class_handle classHandle,
+ uint8_t logicalUnit,
+ transfer_callback_t callbackFn,
+ void *callbackParam);
+
+/*!
+ * @brief mass storage request sense.
+ *
+ * This function implements the UFI REQUEST SENSE command, this command instructs
+ * the UFI device to transfer sense data to the host for the specified logical unit.
+ *
+ * @param[in] classHandle The class MSD handle.
+ * @param[in] logicalUnit Logical unit number.
+ * @param[out] buffer Buffer pointer.
+ * @param[in] bufferLength The buffer length.
+ * @param[in] callbackFn This callback is called after this command completes.
+ * @param[in] callbackParam The first parameter in the callback function.
+ *
+ * @retval kStatus_USB_Success The device is initialized successfully.
+ * @retval kStatus_USB_InvalidHandle The classHandle is NULL pointer.
+ * @retval kStatus_USB_Busy The previous command is executing or there is no idle transfer.
+ * @retval kStatus_USB_Error Send transfer fail. See the USB_HostSend/USB_HostRecv.
+ * @retval kStatus_USB_Success Callback return status, the command succeed.
+ * @retval kStatus_USB_MSDStatusFail Callback return status, the CSW status indicate this command fail.
+ * @retval kStatus_USB_Error Callback return status, the command fail.
+ */
+extern usb_status_t USB_HostMsdRequestSense(usb_host_class_handle classHandle,
+ uint8_t logicalUnit,
+ uint8_t *buffer,
+ uint32_t bufferLength,
+ transfer_callback_t callbackFn,
+ void *callbackParam);
+
+/*!
+ * @brief Mass storage mode select.
+ *
+ * This function implements the UFI MODE SELECT command and allows the host
+ * to specify medium or device parameters to the UFI device.
+ *
+ * @param[in] classHandle The class MSD handle.
+ * @param[in] logicalUnit Logical unit number.
+ * @param[in] buffer Buffer pointer.
+ * @param[in] bufferLength The buffer length.
+ * @param[in] callbackFn This callback is called after this command completes.
+ * @param[in] callbackParam The first parameter in the callback function.
+ *
+ * @retval kStatus_USB_Success The device is initialized successfully.
+ * @retval kStatus_USB_InvalidHandle The classHandle is NULL pointer.
+ * @retval kStatus_USB_Busy The previous command is executing or there is no idle transfer.
+ * @retval kStatus_USB_Error Send transfer fail. See the USB_HostSend/USB_HostRecv.
+ * @retval kStatus_USB_Success Callback return status, the command succeed.
+ * @retval kStatus_USB_MSDStatusFail Callback return status, the CSW status indicate this command fail.
+ * @retval kStatus_USB_Error Callback return status, the command fail.
+ */
+extern usb_status_t USB_HostMsdModeSelect(usb_host_class_handle classHandle,
+ uint8_t logicalUnit,
+ uint8_t *buffer,
+ uint32_t bufferLength,
+ transfer_callback_t callbackFn,
+ void *callbackParam);
+
+/*!
+ * @brief Mass storage mode sense.
+ *
+ * This function implements the UFI MODE SENSE command and allows the UFI
+ * device to report medium or device parameters to the host.
+ *
+ * @param[in] classHandle The class MSD handle.
+ * @param[in] logicalUnit Logical unit number.
+ * @param[in] pageControl The page control field specifies the type of mode parameters to return.
+ * @param[in] pageCode Buffer pointer.
+ * @param[out] buffer Buffer pointer.
+ * @param[in] bufferLength The buffer length.
+ * @param[in] callbackFn This callback is called after this command completes.
+ * @param[in] callbackParam The first parameter in the callback function.
+ *
+ * @retval kStatus_USB_Success The device is initialized successfully.
+ * @retval kStatus_USB_InvalidHandle The classHandle is NULL pointer.
+ * @retval kStatus_USB_Busy The previous command is executing or there is no idle transfer.
+ * @retval kStatus_USB_Error Send transfer fail. See the USB_HostSend/USB_HostRecv.
+ * @retval kStatus_USB_Success Callback return status, the command succeed.
+ * @retval kStatus_USB_MSDStatusFail Callback return status, the CSW status indicate this command fail.
+ * @retval kStatus_USB_Error Callback return status, the command fail.
+ */
+extern usb_status_t USB_HostMsdModeSense(usb_host_class_handle classHandle,
+ uint8_t logicalUnit,
+ uint8_t pageControl,
+ uint8_t pageCode,
+ uint8_t *buffer,
+ uint32_t bufferLength,
+ transfer_callback_t callbackFn,
+ void *callbackParam);
+
+/*!
+ * @brief Mass storage inquiry.
+ *
+ * This function implements the UFI INQUIRY command and requests that information regarding
+ * parameters of the UFI device itself be sent to the host.
+ *
+ * @param[in] classHandle The class MSD handle.
+ * @param[in] logicalUnit Logical unit number.
+ * @param[out] buffer Buffer pointer.
+ * @param[in] bufferLength The buffer length.
+ * @param[in] callbackFn This callback is called after this command completes.
+ * @param[in] callbackParam The first parameter in the callback function.
+ *
+ * @retval kStatus_USB_Success The device is initialized successfully.
+ * @retval kStatus_USB_InvalidHandle The classHandle is NULL pointer.
+ * @retval kStatus_USB_Busy The previous command is executing or there is no idle transfer.
+ * @retval kStatus_USB_Error Send transfer fail. See the USB_HostSend/USB_HostRecv.
+ * @retval kStatus_USB_Success Callback return status, the command succeed.
+ * @retval kStatus_USB_MSDStatusFail Callback return status, the CSW status indicate this command fail.
+ * @retval kStatus_USB_Error Callback return status, the command fail.
+ */
+extern usb_status_t USB_HostMsdInquiry(usb_host_class_handle classHandle,
+ uint8_t logicalUnit,
+ uint8_t *buffer,
+ uint32_t bufferLength,
+ transfer_callback_t callbackFn,
+ void *callbackParam);
+
+/*!
+ * @brief Mass storage read format capacities.
+ *
+ * This function implements the UFI READ FORMAT CAPACITIES command and allows the host to request
+ * a list of the possible capacities that can be formatted on the currently installed medium.
+ *
+ * @param[in] classHandle The class MSD handle.
+ * @param[in] logicalUnit Logical unit number.
+ * @param[out] buffer Buffer pointer.
+ * @param[in] bufferLength The buffer length.
+ * @param[in] callbackFn This callback is called after this command completes.
+ * @param[in] callbackParam The first parameter in the callback function.
+ *
+ * @retval kStatus_USB_Success The device is initialized successfully.
+ * @retval kStatus_USB_InvalidHandle The classHandle is NULL pointer.
+ * @retval kStatus_USB_Busy The previous command is executing or there is no idle transfer.
+ * @retval kStatus_USB_Error Send transfer fail. See the USB_HostSend/USB_HostRecv.
+ * @retval kStatus_USB_Success Callback return status, the command succeed.
+ * @retval kStatus_USB_MSDStatusFail Callback return status, the CSW status indicate this command fail.
+ * @retval kStatus_USB_Error Callback return status, the command fail.
+ */
+extern usb_status_t USB_HostMsdReadFormatCapacities(usb_host_class_handle classHandle,
+ uint8_t logicalUnit,
+ uint8_t *buffer,
+ uint32_t bufferLength,
+ transfer_callback_t callbackFn,
+ void *callbackParam);
+
+/*!
+ * @brief Mass storage format unit.
+ *
+ * This function implements the UFI FORMAT UNIT command and the host sends this command to physically format one
+ * track of a diskette according to the selected options.
+ *
+ * @param[in] classHandle The class MSD handle.
+ * @param[in] logicalUnit Logical unit number.
+ * @param[in] trackNumber This specifies which track is to be formatted.
+ * @param[in] interLeave This specifies the interleave that shall be used for formatting.
+ * @param[in] buffer Buffer pointer.
+ * @param[in] bufferLength The buffer length.
+ * @param[in] callbackFn This callback is called after this command completes.
+ * @param[in] callbackParam The first parameter in the callback function.
+ *
+ * @retval kStatus_USB_Success The device is initialized successfully.
+ * @retval kStatus_USB_InvalidHandle The classHandle is NULL pointer.
+ * @retval kStatus_USB_Busy The previous command is executing or there is no idle transfer.
+ * @retval kStatus_USB_Error Send transfer fail. See the USB_HostSend/USB_HostRecv.
+ * @retval kStatus_USB_Success Callback return status, the command succeed.
+ * @retval kStatus_USB_MSDStatusFail Callback return status, the CSW status indicate this command fail.
+ * @retval kStatus_USB_Error Callback return status, the command fail.
+ */
+extern usb_status_t USB_HostMsdFormatUnit(usb_host_class_handle classHandle,
+ uint8_t logicalUnit,
+ uint8_t trackNumber,
+ uint16_t interLeave,
+ uint8_t *buffer,
+ uint32_t bufferLength,
+ transfer_callback_t callbackFn,
+ void *callbackParam);
+
+/*!
+ * @brief Mass storage prevents/allows a medium removal.
+ *
+ * This function implements the UFI PREVENT-ALLOW MEDIUM REMOVAL command and notifies the FUI device
+ * to enable or disable the removal of the medium in the logical unit.
+ *
+ * @param[in] classHandle The class MSD handle.
+ * @param[in] logicalUnit Logical unit number.
+ * @param[in] prevent Prevent or allow
+ * - 0: enable (allow) the removal of the medium
+ * - 1: disable (prevent) removal of the medium
+ * @param[in] callbackFn This callback is called after this command completes.
+ * @param[in] callbackParam The first parameter in the callback function.
+ *
+ * @retval kStatus_USB_Success The device is initialized successfully.
+ * @retval kStatus_USB_InvalidHandle The classHandle is NULL pointer.
+ * @retval kStatus_USB_Busy The previous command is executing or there is no idle transfer.
+ * @retval kStatus_USB_Error Send transfer fail. See the USB_HostSend/USB_HostRecv.
+ * @retval kStatus_USB_Success Callback return status, the command succeed.
+ * @retval kStatus_USB_MSDStatusFail Callback return status, the CSW status indicate this command fail.
+ * @retval kStatus_USB_Error Callback return status, the command fail.
+ */
+extern usb_status_t USB_HostMsdPreventAllowRemoval(usb_host_class_handle classHandle,
+ uint8_t logicalUnit,
+ uint8_t prevent,
+ transfer_callback_t callbackFn,
+ void *callbackParam);
+
+/*!
+ * @brief Mass storage write and verify.
+ *
+ * This function implements the UFI WRITE AND VERIFY command and requests that the UFI device
+ * writes the data transferred by the host to the medium, then verifies the data on the medium.
+ *
+ * @param[in] classHandle The class MSD handle.
+ * @param[in] logicalUnit Logical unit number.
+ * @param[in] blockAddress The start block address.
+ * @param[in] buffer Buffer pointer.
+ * @param[in] bufferLength The buffer length.
+ * @param[in] blockNumber Write and verify block number.
+ * @param[in] callbackFn This callback is called after this command completes.
+ * @param[in] callbackParam The first parameter in the callback function.
+ *
+ * @retval kStatus_USB_Success The device is initialized successfully.
+ * @retval kStatus_USB_InvalidHandle The classHandle is NULL pointer.
+ * @retval kStatus_USB_Busy The previous command is executing or there is no idle transfer.
+ * @retval kStatus_USB_Error Send transfer fail. See the USB_HostSend/USB_HostRecv.
+ * @retval kStatus_USB_Success Callback return status, the command succeed.
+ * @retval kStatus_USB_MSDStatusFail Callback return status, the CSW status indicate this command fail.
+ * @retval kStatus_USB_Error Callback return status, the command fail.
+ */
+extern usb_status_t USB_HostMsdWriteAndVerify(usb_host_class_handle classHandle,
+ uint8_t logicalUnit,
+ uint32_t blockAddress,
+ uint8_t *buffer,
+ uint32_t bufferLength,
+ uint32_t blockNumber,
+ transfer_callback_t callbackFn,
+ void *callbackParam);
+
+/*!
+ * @brief Mass storage start stop unit.
+ *
+ * This function implements the UFI START-STOP UNIT command and instructs the UFI device
+ * to enable or disable media access operations .
+ *
+ * @param[in] classHandle The class MSD handle.
+ * @param[in] logicalUnit Logical unit number.
+ * @param[in] loadEject A Load Eject (LoEj) bit of zero requests that no eject action be performed. A LoEj bit of
+ * one, with the
+ * Start bit cleared to zero, which instructs the UFI device to eject the media.
+ * @param[in] start A Start bit of one instructs the UFI device to enable media access operations. A Start bit
+ * of zero instructs the UFI device to disable media access operations.
+ * @param[in] callbackFn This callback is called after this command completes.
+ * @param[in] callbackParam The first parameter in the callback function.
+ *
+ * @retval kStatus_USB_Success The device is initialized successfully.
+ * @retval kStatus_USB_InvalidHandle The classHandle is NULL pointer.
+ * @retval kStatus_USB_Busy The previous command is executing or there is no idle transfer.
+ * @retval kStatus_USB_Error Send transfer fail. See the USB_HostSend/USB_HostRecv.
+ * @retval kStatus_USB_Success Callback return status, the command succeed.
+ * @retval kStatus_USB_MSDStatusFail Callback return status, the CSW status indicate this command fail.
+ * @retval kStatus_USB_Error Callback return status, the command fail.
+ */
+extern usb_status_t USB_HostMsdStartStopUnit(usb_host_class_handle classHandle,
+ uint8_t logicalUnit,
+ uint8_t loadEject,
+ uint8_t start,
+ transfer_callback_t callbackFn,
+ void *callbackParam);
+
+/*!
+ * @brief Mass storage verify.
+ *
+ * This function implements the UFI VERIFY command and requests that the UFI device
+ * verify the data on the medium.
+ *
+ * @param[in] classHandle The class MSD handle.
+ * @param[in] logicalUnit Logical unit number.
+ * @param[in] blockAddress The start block address.
+ * @param[in] verificationLength The data length that need to be verified.
+ * @param[in] callbackFn This callback is called after this command completes.
+ * @param[in] callbackParam The first parameter in the callback function.
+ *
+ * @retval kStatus_USB_Success The device is initialized successfully.
+ * @retval kStatus_USB_InvalidHandle The classHandle is NULL pointer.
+ * @retval kStatus_USB_Busy The previous command is executing or there is no idle transfer.
+ * @retval kStatus_USB_Error Send transfer fail. See the USB_HostSend/USB_HostRecv.
+ * @retval kStatus_USB_Success Callback return status, the command succeed.
+ * @retval kStatus_USB_MSDStatusFail Callback return status, the CSW status indicate this command fail.
+ * @retval kStatus_USB_Error Callback return status, the command fail.
+ */
+extern usb_status_t USB_HostMsdVerify(usb_host_class_handle classHandle,
+ uint8_t logicalUnit,
+ uint32_t blockAddress,
+ uint16_t verificationLength,
+ transfer_callback_t callbackFn,
+ void *callbackParam);
+
+/*!
+ * @brief Mass storage rezero.
+ *
+ * This function implements the UFI REZERO UNIT command. This command positions the head of
+ * the drive to the cylinder 0.
+ *
+ * @param[in] classHandle The class MSD handle.
+ * @param[in] logicalUnit Logical unit number.
+ * @param[in] callbackFn This callback is called after this command completes.
+ * @param[in] callbackParam The first parameter in the callback function.
+ *
+ * @retval kStatus_USB_Success The device is initialized successfully.
+ * @retval kStatus_USB_InvalidHandle The classHandle is NULL pointer.
+ * @retval kStatus_USB_Busy The previous command is executing or there is no idle transfer.
+ * @retval kStatus_USB_Error Send transfer fail. See the USB_HostSend/USB_HostRecv.
+ * @retval kStatus_USB_Success Callback return status, the command succeed.
+ * @retval kStatus_USB_MSDStatusFail Callback return status, the CSW status indicate this command fail.
+ * @retval kStatus_USB_Error Callback return status, the command fail.
+ */
+extern usb_status_t USB_HostMsdRezeroUnit(usb_host_class_handle classHandle,
+ uint8_t logicalUnit,
+ transfer_callback_t callbackFn,
+ void *callbackParam);
+
+/*!
+ * @brief Mass storage seek(10).
+ *
+ * This function implements the UFI SEEK(10) command and requests that the UFI device
+ * seek to the specified Logical Block Address.
+ *
+ * @param[in] classHandle The class MSD handle.
+ * @param[in] logicalUnit Logical unit number.
+ * @param[in] blockAddress The start block address.
+ * @param[in] callbackFn This callback is called after this command completes.
+ * @param[in] callbackParam The first parameter in the callback function.
+ *
+ * @retval kStatus_USB_Success The device is initialized successfully.
+ * @retval kStatus_USB_InvalidHandle The classHandle is NULL pointer.
+ * @retval kStatus_USB_Busy The previous command is executing or there is no idle transfer.
+ * @retval kStatus_USB_Error Send transfer fail. See the USB_HostSend/USB_HostRecv.
+ * @retval kStatus_USB_Success Callback return status, the command succeed.
+ * @retval kStatus_USB_MSDStatusFail Callback return status, the CSW status indicate this command fail.
+ * @retval kStatus_USB_Error Callback return status, the command fail.
+ */
+extern usb_status_t USB_HostMsdSeek10(usb_host_class_handle classHandle,
+ uint8_t logicalUnit,
+ uint32_t blockAddress,
+ transfer_callback_t callbackFn,
+ void *callbackParam);
+
+/*!
+ * @brief Mass storage send diagnostic.
+ *
+ * This function implements the UFI SEND DIAGNOSTIC command. This command requests the UFI device
+ * to do a reset or perform a self-test.
+ *
+ * @param[in] classHandle The class MSD handle.
+ * @param[in] logicalUnit Logical unit number.
+ * @param[in] selfTest 0 = perform special diagnostic test; 1 = perform default self-test.
+ * @param[in] callbackFn This callback is called after this command completes.
+ * @param[in] callbackParam The first parameter in the callback function.
+ *
+ * @retval kStatus_USB_Success The device is initialized successfully.
+ * @retval kStatus_USB_InvalidHandle The classHandle is NULL pointer.
+ * @retval kStatus_USB_Busy The previous command is executing or there is no idle transfer.
+ * @retval kStatus_USB_Error Send transfer fail. See the USB_HostSend/USB_HostRecv.
+ * @retval kStatus_USB_Success Callback return status, the command succeed.
+ * @retval kStatus_USB_MSDStatusFail Callback return status, the CSW status indicate this command fail.
+ * @retval kStatus_USB_Error Callback return status, the command fail.
+ */
+extern usb_status_t USB_HostMsdSendDiagnostic(usb_host_class_handle classHandle,
+ uint8_t logicalUnit,
+ uint8_t selfTest,
+ transfer_callback_t callbackFn,
+ void *callbackParam);
+
+/*! @}*/
+
+#ifdef __cplusplus
+}
+#endif
+
+/*! @}*/
+
+#endif /* _USB_HOST_MSD_H_ */
diff --git a/usb_1.1.0/host/class/usb_host_msd_ufi.c b/usb_1.1.0/host/class/usb_host_msd_ufi.c
new file mode 100644
index 0000000..0e47e79
--- /dev/null
+++ b/usb_1.1.0/host/class/usb_host_msd_ufi.c
@@ -0,0 +1,473 @@
+/*
+ * Copyright (c) 2015, Freescale Semiconductor, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * o Redistributions of source code must retain the above copyright notice, this list
+ * of conditions and the following disclaimer.
+ *
+ * o Redistributions in binary form must reproduce the above copyright notice, this
+ * list of conditions and the following disclaimer in the documentation and/or
+ * other materials provided with the distribution.
+ *
+ * o Neither the name of Freescale Semiconductor, Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "usb_host_config.h"
+#if ((defined USB_HOST_CONFIG_MSD) && (USB_HOST_CONFIG_MSD))
+#include "usb_host.h"
+#include "usb_host_msd.h"
+
+/*******************************************************************************
+ * Definitions
+ ******************************************************************************/
+
+/* UFI command code */
+#define UFI_FORMAT_UNIT (0x04U)
+#define UFI_INQUIRY (0x12U)
+#define UFI_START_STOP (0x1BU)
+#define UFI_MODE_SELECT (0x55U)
+#define UFI_MODE_SENSE (0x5AU)
+#define UFI_MEDIUM_REMOVAL (0x1EU)
+#define UFI_READ10 (0x28U)
+#define UFI_READ12 (0xA8U)
+#define UFI_READ_CAPACITY (0x25U)
+#define UFI_READ_FORMAT_CAPACITY (0x23U)
+#define UFI_REQUEST_SENSE (0x03U)
+#define UFI_REZERO_UINT (0x01U)
+#define UFI_SEEK (0x2BU)
+#define UFI_SEND_DIAGNOSTIC (0x1DU)
+#define UFI_TEST_UNIT_READY (0x00U)
+#define UFI_VERIFY (0x2FU)
+#define UFI_WRITE10 (0x2AU)
+#define UFI_WRITE12 (0xAAU)
+#define UFI_WRITE_VERIFY (0x2EU)
+
+#define GET_BYTE_FROM_LE_LONG(b, n) \
+ ((uint8_t)((USB_LONG_TO_LITTLE_ENDIAN(b)) >> (n * 8))) /* get the byte from the long value */
+
+/*******************************************************************************
+ * Prototypes
+ ******************************************************************************/
+
+extern usb_status_t USB_HostMsdCommand(usb_host_class_handle classHandle,
+ uint8_t *buffer,
+ uint32_t bufferLength,
+ transfer_callback_t callbackFn,
+ void *callbackParam,
+ uint8_t direction,
+ uint8_t byteValues[10]);
+
+/*******************************************************************************
+ * Variables
+ ******************************************************************************/
+
+/*******************************************************************************
+ * Code
+ ******************************************************************************/
+
+usb_status_t USB_HostMsdRead10(usb_host_class_handle classHandle,
+ uint8_t logicalUnit,
+ uint32_t blockAddress,
+ uint8_t *buffer,
+ uint32_t bufferLength,
+ uint32_t blockNumber,
+ transfer_callback_t callbackFn,
+ void *callbackParam)
+{
+ uint8_t ufiBytes[] = {UFI_READ10,
+ (uint8_t)(logicalUnit << USB_HOST_UFI_LOGICAL_UNIT_POSITION),
+ GET_BYTE_FROM_LE_LONG(blockAddress, 3),
+ GET_BYTE_FROM_LE_LONG(blockAddress, 2),
+ GET_BYTE_FROM_LE_LONG(blockAddress, 1),
+ GET_BYTE_FROM_LE_LONG(blockAddress, 0),
+ 0x00,
+ GET_BYTE_FROM_LE_LONG(blockNumber, 1),
+ GET_BYTE_FROM_LE_LONG(blockNumber, 0),
+ 0x00};
+ return USB_HostMsdCommand(classHandle, buffer, bufferLength, callbackFn, callbackParam,
+ USB_HOST_MSD_CBW_FLAGS_DIRECTION_IN, ufiBytes);
+}
+
+usb_status_t USB_HostMsdRead12(usb_host_class_handle classHandle,
+ uint8_t logicalUnit,
+ uint32_t blockAddress,
+ uint8_t *buffer,
+ uint32_t bufferLength,
+ uint32_t blockNumber,
+ transfer_callback_t callbackFn,
+ void *callbackParam)
+{
+ uint8_t ufiBytes[] = {UFI_READ12,
+ (uint8_t)(logicalUnit << USB_HOST_UFI_LOGICAL_UNIT_POSITION),
+ GET_BYTE_FROM_LE_LONG(blockAddress, 3),
+ GET_BYTE_FROM_LE_LONG(blockAddress, 2),
+ GET_BYTE_FROM_LE_LONG(blockAddress, 1),
+ GET_BYTE_FROM_LE_LONG(blockAddress, 0),
+ GET_BYTE_FROM_LE_LONG(blockNumber, 3),
+ GET_BYTE_FROM_LE_LONG(blockNumber, 2),
+ GET_BYTE_FROM_LE_LONG(blockNumber, 1),
+ GET_BYTE_FROM_LE_LONG(blockNumber, 0)};
+ return USB_HostMsdCommand(classHandle, buffer, bufferLength, callbackFn, callbackParam,
+ USB_HOST_MSD_CBW_FLAGS_DIRECTION_IN, ufiBytes);
+}
+
+usb_status_t USB_HostMsdWrite10(usb_host_class_handle classHandle,
+ uint8_t logicalUnit,
+ uint32_t blockAddress,
+ uint8_t *buffer,
+ uint32_t bufferLength,
+ uint32_t blockNumber,
+ transfer_callback_t callbackFn,
+ void *callbackParam)
+{
+ uint8_t ufiBytes[] = {UFI_WRITE10,
+ (uint8_t)(logicalUnit << USB_HOST_UFI_LOGICAL_UNIT_POSITION),
+ GET_BYTE_FROM_LE_LONG(blockAddress, 3),
+ GET_BYTE_FROM_LE_LONG(blockAddress, 2),
+ GET_BYTE_FROM_LE_LONG(blockAddress, 1),
+ GET_BYTE_FROM_LE_LONG(blockAddress, 0),
+ 0x00,
+ GET_BYTE_FROM_LE_LONG(blockNumber, 1),
+ GET_BYTE_FROM_LE_LONG(blockNumber, 0),
+ 0x00};
+ return USB_HostMsdCommand(classHandle, buffer, bufferLength, callbackFn, callbackParam,
+ USB_HOST_MSD_CBW_FLAGS_DIRECTION_OUT, ufiBytes);
+}
+
+usb_status_t USB_HostMsdWrite12(usb_host_class_handle classHandle,
+ uint8_t logicalUnit,
+ uint32_t blockAddress,
+ uint8_t *buffer,
+ uint32_t bufferLength,
+ uint32_t blockNumber,
+ transfer_callback_t callbackFn,
+ void *callbackParam)
+{
+ uint8_t ufiBytes[] = {UFI_WRITE12,
+ (uint8_t)(logicalUnit << USB_HOST_UFI_LOGICAL_UNIT_POSITION),
+ GET_BYTE_FROM_LE_LONG(blockAddress, 3),
+ GET_BYTE_FROM_LE_LONG(blockAddress, 2),
+ GET_BYTE_FROM_LE_LONG(blockAddress, 1),
+ GET_BYTE_FROM_LE_LONG(blockAddress, 0),
+ GET_BYTE_FROM_LE_LONG(blockNumber, 3),
+ GET_BYTE_FROM_LE_LONG(blockNumber, 2),
+ GET_BYTE_FROM_LE_LONG(blockNumber, 1),
+ GET_BYTE_FROM_LE_LONG(blockNumber, 0)};
+ return USB_HostMsdCommand(classHandle, buffer, bufferLength, callbackFn, callbackParam,
+ USB_HOST_MSD_CBW_FLAGS_DIRECTION_OUT, ufiBytes);
+}
+
+usb_status_t USB_HostMsdReadCapacity(usb_host_class_handle classHandle,
+ uint8_t logicalUnit,
+ uint8_t *buffer,
+ uint32_t bufferLength,
+ transfer_callback_t callbackFn,
+ void *callbackParam)
+{
+ uint8_t ufiBytes[] = {UFI_READ_CAPACITY,
+ (uint8_t)(logicalUnit << USB_HOST_UFI_LOGICAL_UNIT_POSITION),
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00};
+ return USB_HostMsdCommand(classHandle, buffer, bufferLength, callbackFn, callbackParam,
+ USB_HOST_MSD_CBW_FLAGS_DIRECTION_IN, ufiBytes);
+}
+
+usb_status_t USB_HostMsdTestUnitReady(usb_host_class_handle classHandle,
+ uint8_t logicalUnit,
+ transfer_callback_t callbackFn,
+ void *callbackParam)
+{
+ uint8_t ufiBytes[] = {UFI_TEST_UNIT_READY,
+ (uint8_t)(logicalUnit << USB_HOST_UFI_LOGICAL_UNIT_POSITION),
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00};
+ return USB_HostMsdCommand(classHandle, NULL, 0, callbackFn, callbackParam, USB_HOST_MSD_CBW_FLAGS_DIRECTION_OUT,
+ ufiBytes);
+}
+
+usb_status_t USB_HostMsdRequestSense(usb_host_class_handle classHandle,
+ uint8_t logicalUnit,
+ uint8_t *buffer,
+ uint32_t bufferLength,
+ transfer_callback_t callbackFn,
+ void *callbackParam)
+{
+ uint8_t ufiBytes[] = {UFI_REQUEST_SENSE,
+ (uint8_t)(logicalUnit << USB_HOST_UFI_LOGICAL_UNIT_POSITION),
+ 0x00,
+ 0x00,
+ (uint8_t)bufferLength,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00};
+ return USB_HostMsdCommand(classHandle, buffer, bufferLength, callbackFn, callbackParam,
+ USB_HOST_MSD_CBW_FLAGS_DIRECTION_IN, ufiBytes);
+}
+
+usb_status_t USB_HostMsdModeSelect(usb_host_class_handle classHandle,
+ uint8_t logicalUnit,
+ uint8_t *buffer,
+ uint32_t bufferLength,
+ transfer_callback_t callbackFn,
+ void *callbackParam)
+{
+ uint8_t ufiBytes[] = {UFI_MODE_SELECT,
+ (uint8_t)(logicalUnit << USB_HOST_UFI_LOGICAL_UNIT_POSITION),
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ GET_BYTE_FROM_LE_LONG(bufferLength, 1),
+ GET_BYTE_FROM_LE_LONG(bufferLength, 0),
+ 0x00};
+ return USB_HostMsdCommand(classHandle, buffer, bufferLength, callbackFn, callbackParam,
+ USB_HOST_MSD_CBW_FLAGS_DIRECTION_OUT, ufiBytes);
+}
+
+usb_status_t USB_HostMsdModeSense(usb_host_class_handle classHandle,
+ uint8_t logicalUnit,
+ uint8_t pageControl,
+ uint8_t pageCode,
+ uint8_t *buffer,
+ uint32_t bufferLength,
+ transfer_callback_t callbackFn,
+ void *callbackParam)
+{
+ uint8_t ufiBytes[] = {UFI_MODE_SENSE, (uint8_t)(logicalUnit << USB_HOST_UFI_LOGICAL_UNIT_POSITION),
+ (uint8_t)(((uint32_t)pageCode << USB_HOST_UFI_MODE_SENSE_PAGE_CONTROL_SHIFT) |
+ ((uint32_t)pageCode << USB_HOST_UFI_MODE_SENSE_PAGE_CODE_SHIFT)),
+ 0x00, 0x00, 0x00, 0x00, GET_BYTE_FROM_LE_LONG(bufferLength, 1),
+ GET_BYTE_FROM_LE_LONG(bufferLength, 0), 0x00};
+ return USB_HostMsdCommand(classHandle, buffer, bufferLength, callbackFn, callbackParam,
+ USB_HOST_MSD_CBW_FLAGS_DIRECTION_IN, ufiBytes);
+}
+
+usb_status_t USB_HostMsdInquiry(usb_host_class_handle classHandle,
+ uint8_t logicalUnit,
+ uint8_t *buffer,
+ uint32_t bufferLength,
+ transfer_callback_t callbackFn,
+ void *callbackParam)
+{
+ uint8_t ufiBytes[] = {UFI_INQUIRY,
+ (uint8_t)(logicalUnit << USB_HOST_UFI_LOGICAL_UNIT_POSITION),
+ 0x00,
+ 0x00,
+ (uint8_t)bufferLength,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00};
+ return USB_HostMsdCommand(classHandle, buffer, bufferLength, callbackFn, callbackParam,
+ USB_HOST_MSD_CBW_FLAGS_DIRECTION_IN, ufiBytes);
+}
+
+usb_status_t USB_HostMsdReadFormatCapacities(usb_host_class_handle classHandle,
+ uint8_t logicalUnit,
+ uint8_t *buffer,
+ uint32_t bufferLength,
+ transfer_callback_t callbackFn,
+ void *callbackParam)
+{
+ uint8_t ufiBytes[] = {UFI_READ_FORMAT_CAPACITY,
+ (uint8_t)(logicalUnit << USB_HOST_UFI_LOGICAL_UNIT_POSITION),
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ GET_BYTE_FROM_LE_LONG(bufferLength, 1),
+ GET_BYTE_FROM_LE_LONG(bufferLength, 0),
+ 0x00};
+ return USB_HostMsdCommand(classHandle, buffer, bufferLength, callbackFn, callbackParam,
+ USB_HOST_MSD_CBW_FLAGS_DIRECTION_IN, ufiBytes);
+}
+
+usb_status_t USB_HostMsdFormatUnit(usb_host_class_handle classHandle,
+ uint8_t logicalUnit,
+ uint8_t trackNumber,
+ uint16_t interLeave,
+ uint8_t *buffer,
+ uint32_t bufferLength,
+ transfer_callback_t callbackFn,
+ void *callbackParam)
+{
+ uint8_t ufiBytes[] = {UFI_FORMAT_UNIT,
+ (uint8_t)(logicalUnit << USB_HOST_UFI_LOGICAL_UNIT_POSITION),
+ trackNumber,
+ GET_BYTE_FROM_LE_LONG(interLeave, 1),
+ GET_BYTE_FROM_LE_LONG(interLeave, 0),
+ 0x00,
+ 0x00,
+ GET_BYTE_FROM_LE_LONG(bufferLength, 1),
+ GET_BYTE_FROM_LE_LONG(bufferLength, 0),
+ 0x00};
+ return USB_HostMsdCommand(classHandle, buffer, bufferLength, callbackFn, callbackParam,
+ USB_HOST_MSD_CBW_FLAGS_DIRECTION_OUT, ufiBytes);
+}
+
+usb_status_t USB_HostMsdPreventAllowRemoval(usb_host_class_handle classHandle,
+ uint8_t logicalUnit,
+ uint8_t prevent,
+ transfer_callback_t callbackFn,
+ void *callbackParam)
+{
+ uint8_t ufiBytes[] = {UFI_MEDIUM_REMOVAL,
+ (uint8_t)(logicalUnit << USB_HOST_UFI_LOGICAL_UNIT_POSITION),
+ 0x00,
+ 0x00,
+ prevent,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00};
+ return USB_HostMsdCommand(classHandle, NULL, 0, callbackFn, callbackParam, USB_HOST_MSD_CBW_FLAGS_DIRECTION_OUT,
+ ufiBytes);
+}
+
+usb_status_t USB_HostMsdWriteAndVerify(usb_host_class_handle classHandle,
+ uint8_t logicalUnit,
+ uint32_t blockAddress,
+ uint8_t *buffer,
+ uint32_t bufferLength,
+ uint32_t blockNumber,
+ transfer_callback_t callbackFn,
+ void *callbackParam)
+{
+ uint8_t ufiBytes[] = {UFI_WRITE_VERIFY,
+ (uint8_t)(logicalUnit << USB_HOST_UFI_LOGICAL_UNIT_POSITION),
+ GET_BYTE_FROM_LE_LONG(blockAddress, 3),
+ GET_BYTE_FROM_LE_LONG(blockAddress, 2),
+ GET_BYTE_FROM_LE_LONG(blockAddress, 1),
+ GET_BYTE_FROM_LE_LONG(blockAddress, 0),
+ 0x00,
+ GET_BYTE_FROM_LE_LONG(blockNumber, 1),
+ GET_BYTE_FROM_LE_LONG(blockNumber, 0),
+ 0x00};
+ return USB_HostMsdCommand(classHandle, buffer, bufferLength, callbackFn, callbackParam,
+ USB_HOST_MSD_CBW_FLAGS_DIRECTION_OUT, ufiBytes);
+}
+
+usb_status_t USB_HostMsdStartStopUnit(usb_host_class_handle classHandle,
+ uint8_t logicalUnit,
+ uint8_t loadEject,
+ uint8_t start,
+ transfer_callback_t callbackFn,
+ void *callbackParam)
+{
+ uint8_t ufiBytes[] = {UFI_START_STOP, (uint8_t)(logicalUnit << USB_HOST_UFI_LOGICAL_UNIT_POSITION), 0x00, 0x00,
+ (uint8_t)(((uint32_t)loadEject << USB_HOST_UFI_START_STOP_UNIT_LOEJ_SHIFT) |
+ ((uint32_t)start << USB_HOST_UFI_START_STOP_UNIT_START_SHIFT)),
+ 0x00, 0x00, 0x00, 0x00, 0x00};
+ return USB_HostMsdCommand(classHandle, NULL, 0, callbackFn, callbackParam, USB_HOST_MSD_CBW_FLAGS_DIRECTION_OUT,
+ ufiBytes);
+}
+
+usb_status_t USB_HostMsdVerify(usb_host_class_handle classHandle,
+ uint8_t logicalUnit,
+ uint32_t blockAddress,
+ uint16_t verificationLength,
+ transfer_callback_t callbackFn,
+ void *callbackParam)
+{
+ uint8_t ufiBytes[] = {UFI_VERIFY,
+ (uint8_t)(logicalUnit << USB_HOST_UFI_LOGICAL_UNIT_POSITION),
+ GET_BYTE_FROM_LE_LONG(blockAddress, 3),
+ GET_BYTE_FROM_LE_LONG(blockAddress, 2),
+ GET_BYTE_FROM_LE_LONG(blockAddress, 1),
+ GET_BYTE_FROM_LE_LONG(blockAddress, 0),
+ 0x00,
+ GET_BYTE_FROM_LE_LONG(verificationLength, 1),
+ GET_BYTE_FROM_LE_LONG(verificationLength, 0),
+ 0x00};
+ return USB_HostMsdCommand(classHandle, NULL, 0, callbackFn, callbackParam, USB_HOST_MSD_CBW_FLAGS_DIRECTION_OUT,
+ ufiBytes);
+}
+
+usb_status_t USB_HostMsdRezeroUnit(usb_host_class_handle classHandle,
+ uint8_t logicalUnit,
+ transfer_callback_t callbackFn,
+ void *callbackParam)
+{
+ uint8_t ufiBytes[] = {UFI_REZERO_UINT,
+ (uint8_t)(logicalUnit << USB_HOST_UFI_LOGICAL_UNIT_POSITION),
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00};
+ return USB_HostMsdCommand(classHandle, NULL, 0, callbackFn, callbackParam, USB_HOST_MSD_CBW_FLAGS_DIRECTION_OUT,
+ ufiBytes);
+}
+
+usb_status_t USB_HostMsdSeek10(usb_host_class_handle classHandle,
+ uint8_t logicalUnit,
+ uint32_t blockAddress,
+ transfer_callback_t callbackFn,
+ void *callbackParam)
+{
+ uint8_t ufiBytes[] = {UFI_SEEK,
+ (uint8_t)(logicalUnit << USB_HOST_UFI_LOGICAL_UNIT_POSITION),
+ GET_BYTE_FROM_LE_LONG(blockAddress, 3),
+ GET_BYTE_FROM_LE_LONG(blockAddress, 2),
+ GET_BYTE_FROM_LE_LONG(blockAddress, 1),
+ GET_BYTE_FROM_LE_LONG(blockAddress, 0),
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00};
+ return USB_HostMsdCommand(classHandle, NULL, 0, callbackFn, callbackParam, USB_HOST_MSD_CBW_FLAGS_DIRECTION_OUT,
+ ufiBytes);
+}
+
+usb_status_t USB_HostMsdSendDiagnostic(usb_host_class_handle classHandle,
+ uint8_t logicalUnit,
+ uint8_t selfTest,
+ transfer_callback_t callbackFn,
+ void *callbackParam)
+{
+ uint8_t ufiBytes[] = {UFI_REZERO_UINT,
+ (uint8_t)(((uint32_t)logicalUnit << USB_HOST_UFI_LOGICAL_UNIT_POSITION) |
+ ((uint32_t)selfTest << USB_HOST_UFI_SEND_DIAGNOSTIC_SELF_TEST_SHIFT)),
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
+ return USB_HostMsdCommand(classHandle, NULL, 0, callbackFn, callbackParam, USB_HOST_MSD_CBW_FLAGS_DIRECTION_OUT,
+ ufiBytes);
+}
+
+#endif /* USB_HOST_CONFIG_MSD */
diff --git a/usb_1.1.0/host/class/usb_host_phdc.c b/usb_1.1.0/host/class/usb_host_phdc.c
new file mode 100644
index 0000000..e740487
--- /dev/null
+++ b/usb_1.1.0/host/class/usb_host_phdc.c
@@ -0,0 +1,1272 @@
+/*
+ * Copyright (c) 2015 - 2016, Freescale Semiconductor, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * o Redistributions of source code must retain the above copyright notice, this list
+ * of conditions and the following disclaimer.
+ *
+ * o Redistributions in binary form must reproduce the above copyright notice, this
+ * list of conditions and the following disclaimer in the documentation and/or
+ * other materials provided with the distribution.
+ *
+ * o Neither the name of Freescale Semiconductor, Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "usb_host_config.h"
+#if ((defined USB_HOST_CONFIG_PHDC) && (USB_HOST_CONFIG_PHDC))
+#include "usb_host.h"
+#include "usb_host_phdc.h"
+
+/*******************************************************************************
+ * Definitions
+ ******************************************************************************/
+
+/*******************************************************************************
+ * Prototypes
+ ******************************************************************************/
+
+/*!
+ * @brief phdc control pipe transfer callback.
+ *
+ * @param param callback parameter.
+ * @param transfer callback transfer.
+ * @param status transfer status.
+ */
+static void USB_HostPhdcControlPipeCallback(void *param, usb_host_transfer_t *transfer, usb_status_t status);
+
+/*!
+ * @brief phdc set and clear feature endpoint halt callback.
+ *
+ * @param param callback parameter.
+ * @param transfer callback transfer.
+ * @param status transfer status.
+ */
+static void USB_HostPhdcSetClearFeatureEndpointHaltCallback(void *param,
+ usb_host_transfer_t *transfer,
+ usb_status_t status);
+
+/*!
+ * @brief phdc interrupt pipe transfer callback.
+ *
+ * @param param callback parameter.
+ * @param transfer callback transfer.
+ * @param status transfer status.
+ */
+static void USB_HostPhdcInterruptPipeCallback(void *param, usb_host_transfer_t *transfer, usb_status_t status);
+
+/*!
+ * @brief phdc bulk in pipe transfer callback.
+ *
+ * @param param callback parameter.
+ * @param transfer callback transfer.
+ * @param status transfer status.
+ */
+static void USB_HostPhdcBulkInPipeCallback(void *param, usb_host_transfer_t *transfer, usb_status_t status);
+
+/*!
+ * @brief phdc bulk out pipe transfer callback.
+ *
+ * @param param callback parameter.
+ * @param transfer callback transfer.
+ * @param status transfer status.
+ */
+static void USB_HostPhdcBulkOutPipeCallback(void *param, usb_host_transfer_t *transfer, usb_status_t status);
+
+/*!
+ * @brief phdc set interface callback, open pipes.
+ *
+ * @param param callback parameter.
+ * @param transfer callback transfer.
+ * @param status transfer status.
+ */
+static void USB_HostPhdcSetInterfaceCallback(void *param, usb_host_transfer_t *transfer, usb_status_t status);
+
+/*******************************************************************************
+ * Variables
+ ******************************************************************************/
+
+/*! @brief meta-data message preamble signature string */
+static char const metaDataMsgPreambleSignature[] = "PhdcQoSSignature";
+
+/*******************************************************************************
+ * Code
+ ******************************************************************************/
+
+#if ((defined USB_HOST_CONFIG_CLASS_AUTO_CLEAR_STALL) && USB_HOST_CONFIG_CLASS_AUTO_CLEAR_STALL)
+
+static void USB_HostPhdcClearInHaltCallback(void *param, usb_host_transfer_t *transfer, usb_status_t status)
+{
+ usb_host_phdc_instance_t *phdcInstance = (usb_host_phdc_instance_t *)param;
+
+ phdcInstance->controlTransfer = NULL;
+ /* Reduces the number of bulk transfer to 0 to expect new message preamble transfer */
+ phdcInstance->numberTransferBulkIn = 0U;
+ if (phdcInstance->inCallbackFn != NULL)
+ {
+ /* callback to application */
+ phdcInstance->inCallbackFn(phdcInstance->inCallbackParam, phdcInstance->stallDataBuffer,
+ phdcInstance->stallDataLength, kStatus_USB_TransferStall);
+ }
+ USB_HostFreeTransfer(phdcInstance->hostHandle, transfer);
+}
+
+static void USB_HostPhdcClearOutHaltCallback(void *param, usb_host_transfer_t *transfer, usb_status_t status)
+{
+ usb_host_phdc_instance_t *phdcInstance = (usb_host_phdc_instance_t *)param;
+
+ phdcInstance->controlTransfer = NULL;
+ if (phdcInstance->outCallbackFn != NULL)
+ {
+ /* callback to application */
+ phdcInstance->outCallbackFn(phdcInstance->outCallbackParam, phdcInstance->stallDataBuffer,
+ phdcInstance->stallDataLength, kStatus_USB_TransferStall);
+ }
+ USB_HostFreeTransfer(phdcInstance->hostHandle, transfer);
+}
+
+static usb_status_t USB_HostPhdcClearHalt(usb_host_phdc_instance_t *phdcInstance,
+ usb_host_transfer_t *stallTransfer,
+ host_inner_transfer_callback_t callbackFn,
+ uint8_t endpoint)
+{
+ usb_status_t status;
+ usb_host_transfer_t *transfer;
+
+ /* malloc one transfer */
+ status = USB_HostMallocTransfer(phdcInstance->hostHandle, &transfer);
+ if (status != kStatus_USB_Success)
+ {
+#ifdef HOST_ECHO
+ usb_echo("allocate transfer error\r\n");
+#endif
+ return status;
+ }
+ phdcInstance->stallDataBuffer = stallTransfer->transferBuffer;
+ phdcInstance->stallDataLength = stallTransfer->transferSofar;
+ /* save the application callback function */
+ phdcInstance->controlCallbackFn = NULL;
+ phdcInstance->controlCallbackParam = NULL;
+ /* initialize transfer */
+ transfer->callbackFn = callbackFn;
+ transfer->callbackParam = phdcInstance;
+ transfer->transferBuffer = NULL;
+ transfer->transferLength = 0;
+ transfer->setupPacket.bRequest = USB_REQUEST_STANDARD_CLEAR_FEATURE;
+ transfer->setupPacket.bmRequestType = USB_REQUEST_TYPE_RECIPIENT_ENDPOINT;
+ transfer->setupPacket.wValue = USB_SHORT_TO_LITTLE_ENDIAN(USB_REQUEST_STANDARD_FEATURE_SELECTOR_ENDPOINT_HALT);
+ transfer->setupPacket.wIndex = USB_SHORT_TO_LITTLE_ENDIAN(endpoint);
+ transfer->setupPacket.wLength = 0;
+ status = USB_HostSendSetup(phdcInstance->hostHandle, phdcInstance->controlPipe, transfer);
+
+ if (status != kStatus_USB_Success)
+ {
+ USB_HostFreeTransfer(phdcInstance->hostHandle, transfer);
+ }
+ phdcInstance->controlTransfer = transfer;
+
+ return status;
+}
+
+#endif
+
+/*!
+ * @brief phdc control pipe transfer callback.
+ *
+ * @param param callback parameter.
+ * @param transfer callback transfer.
+ * @param status transfer status.
+ */
+static void USB_HostPhdcControlPipeCallback(void *param, usb_host_transfer_t *transfer, usb_status_t status)
+{
+ usb_host_phdc_instance_t *phdcInstance = (usb_host_phdc_instance_t *)param;
+ phdcInstance->controlTransfer = NULL;
+ if (kStatus_USB_Success == status)
+ {
+ if (USB_HOST_PHDC_SET_FEATURE_REQUEST == transfer->setupPacket.bRequest)
+ {
+ /* Meta-data message preamble feature is enabled */
+ phdcInstance->isMessagePreambleEnabled = 1U;
+ }
+ else if (USB_HOST_PHDC_CLEAR_FEATURE_REQUEST == transfer->setupPacket.bRequest)
+ {
+ /* Meta-data message preamble feature is disable */
+ phdcInstance->isMessagePreambleEnabled = 0U;
+ }
+ else
+ {
+ }
+ }
+ if (NULL != phdcInstance->controlCallbackFn)
+ {
+ phdcInstance->controlCallbackFn(phdcInstance->controlCallbackParam, transfer->transferBuffer,
+ transfer->transferSofar, status);
+ }
+ USB_HostFreeTransfer(phdcInstance->hostHandle, transfer);
+}
+
+/*!
+ * @brief phdc set and clear feature endpoint halt callback for meta-data message preamble error.
+ *
+ * @param param callback parameter.
+ * @param transfer callback transfer.
+ * @param status transfer status.
+ */
+static void USB_HostPhdcSetClearFeatureEndpointHaltCallback(void *param,
+ usb_host_transfer_t *transfer,
+ usb_status_t status)
+{
+ usb_host_phdc_instance_t *phdcInstance = (usb_host_phdc_instance_t *)param;
+ phdcInstance->controlTransfer = NULL;
+ if (kStatus_USB_Success == status)
+ {
+ if ((transfer->setupPacket.bRequest == USB_REQUEST_STANDARD_SET_FEATURE) &&
+ (transfer->setupPacket.bmRequestType == USB_REQUEST_TYPE_RECIPIENT_ENDPOINT) &&
+ (transfer->setupPacket.wValue ==
+ USB_SHORT_TO_LITTLE_ENDIAN(USB_REQUEST_STANDARD_FEATURE_SELECTOR_ENDPOINT_HALT)) &&
+ (transfer->setupPacket.wIndex ==
+ USB_SHORT_TO_LITTLE_ENDIAN(phdcInstance->bulkInEndpointInformation.epDesc->bEndpointAddress)))
+ {
+ /* The host shall issue CLEAR_FEATURE ENDPOINT_HALT request to the device */
+ usb_host_process_feature_param_t featureParam;
+ featureParam.requestType = kRequestEndpoint;
+ featureParam.featureSelector = USB_REQUEST_STANDARD_FEATURE_SELECTOR_ENDPOINT_HALT;
+ featureParam.interfaceOrEndpoint = phdcInstance->bulkInEndpointInformation.epDesc->bEndpointAddress;
+ if (kStatus_USB_Success != USB_HostPhdcSetClearFeatureEndpointHalt(phdcInstance->hostHandle,
+ USB_REQUEST_STANDARD_CLEAR_FEATURE,
+ &featureParam, NULL, NULL))
+ {
+#ifdef HOST_ECHO
+ usb_echo("Error for USB_HostPhdcSetClearFeatureEndpointHalt\r\n");
+#endif
+ }
+ }
+ if ((transfer->setupPacket.bRequest == USB_REQUEST_STANDARD_CLEAR_FEATURE) &&
+ (transfer->setupPacket.bmRequestType == USB_REQUEST_TYPE_RECIPIENT_ENDPOINT) &&
+ (transfer->setupPacket.wValue ==
+ USB_SHORT_TO_LITTLE_ENDIAN(USB_REQUEST_STANDARD_FEATURE_SELECTOR_ENDPOINT_HALT)) &&
+ (transfer->setupPacket.wIndex ==
+ USB_SHORT_TO_LITTLE_ENDIAN(phdcInstance->bulkInEndpointInformation.epDesc->bEndpointAddress)))
+ {
+ /* Reduces the number of bulk transfer to 0 to expect new message preamble transfer */
+ phdcInstance->numberTransferBulkIn = 0U;
+ }
+ }
+ if (NULL != phdcInstance->controlCallbackFn)
+ {
+ /* Notify to application the status of request */
+ phdcInstance->controlCallbackFn(phdcInstance->controlCallbackParam, transfer->transferBuffer,
+ transfer->transferSofar, status);
+ }
+ USB_HostFreeTransfer(phdcInstance->hostHandle, transfer);
+}
+
+/*!
+ * @brief phdc interrupt pipe transfer callback.
+ *
+ * @param param callback parameter.
+ * @param transfer callback transfer.
+ * @param status transfer status.
+ */
+static void USB_HostPhdcInterruptPipeCallback(void *param, usb_host_transfer_t *transfer, usb_status_t status)
+{
+ usb_host_phdc_instance_t *phdcInstance = (usb_host_phdc_instance_t *)param;
+
+#if ((defined USB_HOST_CONFIG_CLASS_AUTO_CLEAR_STALL) && USB_HOST_CONFIG_CLASS_AUTO_CLEAR_STALL)
+ if (status == kStatus_USB_TransferStall)
+ {
+ if (USB_HostPhdcClearHalt(
+ phdcInstance, transfer, USB_HostPhdcClearInHaltCallback,
+ (USB_REQUEST_TYPE_DIR_IN | ((usb_host_pipe_t *)phdcInstance->interruptPipe)->endpointAddress)) ==
+ kStatus_USB_Success)
+ {
+ USB_HostFreeTransfer(phdcInstance->hostHandle, transfer);
+ return;
+ }
+ }
+#endif
+ if (NULL != phdcInstance->inCallbackFn)
+ {
+ phdcInstance->inCallbackFn(phdcInstance->inCallbackParam, transfer->transferBuffer, transfer->transferSofar,
+ status);
+ }
+ USB_HostFreeTransfer(phdcInstance->hostHandle, transfer);
+}
+
+/*!
+ * @brief phdc bulk in pipe transfer callback.
+ *
+ * @param param callback parameter.
+ * @param transfer callback transfer.
+ * @param status transfer status.
+ */
+static void USB_HostPhdcBulkInPipeCallback(void *param, usb_host_transfer_t *transfer, usb_status_t status)
+{
+ usb_host_phdc_instance_t *phdcInstance = (usb_host_phdc_instance_t *)param;
+
+#if ((defined USB_HOST_CONFIG_CLASS_AUTO_CLEAR_STALL) && USB_HOST_CONFIG_CLASS_AUTO_CLEAR_STALL)
+ if (status == kStatus_USB_TransferStall)
+ {
+ if (USB_HostPhdcClearHalt(
+ phdcInstance, transfer, USB_HostPhdcClearInHaltCallback,
+ (USB_REQUEST_TYPE_DIR_IN | ((usb_host_pipe_t *)phdcInstance->bulkInPipe)->endpointAddress)) ==
+ kStatus_USB_Success)
+ {
+ USB_HostFreeTransfer(phdcInstance->hostHandle, transfer);
+ return;
+ }
+ }
+#endif
+ if (status == kStatus_USB_Success)
+ {
+ /* The meta-data message preamble is implemented and enabled */
+ if (phdcInstance->isMessagePreambleEnabled == 1U)
+ {
+ /* The meta-data message preamble feature is enabled, then all data transfers or sets
+ of data transfers shall be preceded by a meta-data message preamble transfer. The
+ numberTransferBulkIn is initialized as zero for receiving this message preamble data,
+ then it is updated to the value of bNumTransfers field of message preamble data */
+ if (phdcInstance->numberTransferBulkIn)
+ {
+ /* When numberTransferBulkIn reduces to 0, a new meta-data message preamble shall
+ be transferred */
+ phdcInstance->numberTransferBulkIn--;
+ }
+ else
+ {
+ uint8_t preambleSignatureChecking = 1U;
+ /* The received packet is meta-data message preamble */
+ usb_host_phdc_metadata_preamble_t *metaDataMsgPreamble =
+ (usb_host_phdc_metadata_preamble_t *)transfer->transferBuffer;
+ /* Meta-data message preamble signature checking */
+ for (uint8_t i = 0U; i < USB_HOST_PHDC_MESSAGE_PREAMBLE_SIGNATURE_SIZE; i++)
+ {
+ if (*(transfer->transferBuffer + i) != metaDataMsgPreambleSignature[i])
+ {
+ preambleSignatureChecking = 0U;
+ break;
+ }
+ }
+ if (preambleSignatureChecking)
+ {
+ /* Checks if the meta-data message preamble contains an invalid bmLatencyReliability value
+ or bNumTransfers value */
+ if ((!(metaDataMsgPreamble->bNumberTransfers)) || /* bNumTransfers shall never equal zero */
+ (metaDataMsgPreamble->bQosEncodingVersion != 0x01U) || /* Encoding version should be 0x01 */
+ ((metaDataMsgPreamble->bmLatencyReliability !=
+ 0x02U) && /* Medium.Good latency, reliability bin */
+ (metaDataMsgPreamble->bmLatencyReliability !=
+ 0x04U) && /* Medium.Better latency, reliability bin */
+ (metaDataMsgPreamble->bmLatencyReliability !=
+ 0x08U) && /* Medium.Best latency, reliability bin */
+ (metaDataMsgPreamble->bmLatencyReliability !=
+ 0x10U) && /* High.Best latency, reliability bin */
+ (metaDataMsgPreamble->bmLatencyReliability !=
+ 0x20U) /* VeryHigh.Best latency, reliability bin */))
+ {
+ /* The host shall issue SET_FEATURE ENDPOINT_HALT request to the device */
+ usb_host_process_feature_param_t featureParam;
+ featureParam.requestType = kRequestEndpoint;
+ featureParam.featureSelector = USB_REQUEST_STANDARD_FEATURE_SELECTOR_ENDPOINT_HALT;
+ featureParam.interfaceOrEndpoint =
+ phdcInstance->bulkInEndpointInformation.epDesc->bEndpointAddress;
+ if (kStatus_USB_Success !=
+ USB_HostPhdcSetClearFeatureEndpointHalt(
+ phdcInstance->hostHandle, USB_REQUEST_STANDARD_SET_FEATURE, &featureParam, NULL, NULL))
+ {
+#ifdef HOST_ECHO
+ usb_echo(
+ "USB_HostPhdcBulkInPipeCallback: Error for "
+ "USB_HostPhdcSetClearFeatureEndpointHalt\r\n");
+#endif
+ }
+ }
+ else
+ {
+ /* The meta-data message preamble data is correct, update the phdc status and
+ * numberTransferBulkIn value */
+ phdcInstance->numberTransferBulkIn = metaDataMsgPreamble->bNumberTransfers;
+ }
+ }
+ }
+ }
+ }
+ if (NULL != phdcInstance->inCallbackFn)
+ {
+ phdcInstance->inCallbackFn(phdcInstance->inCallbackParam, transfer->transferBuffer, transfer->transferSofar,
+ status);
+ }
+ USB_HostFreeTransfer(phdcInstance->hostHandle, transfer);
+}
+
+/*!
+ * @brief phdc bulk out pipe transfer callback.
+ *
+ * @param param callback parameter.
+ * @param transfer callback transfer.
+ * @param status transfer status.
+ */
+static void USB_HostPhdcBulkOutPipeCallback(void *param, usb_host_transfer_t *transfer, usb_status_t status)
+{
+ usb_host_phdc_instance_t *phdcInstance = (usb_host_phdc_instance_t *)param;
+
+#if ((defined USB_HOST_CONFIG_CLASS_AUTO_CLEAR_STALL) && USB_HOST_CONFIG_CLASS_AUTO_CLEAR_STALL)
+ if (status == kStatus_USB_TransferStall)
+ {
+ if (USB_HostPhdcClearHalt(
+ phdcInstance, transfer, USB_HostPhdcClearOutHaltCallback,
+ (USB_REQUEST_TYPE_DIR_OUT | ((usb_host_pipe_t *)phdcInstance->bulkOutPipe)->endpointAddress)) ==
+ kStatus_USB_Success)
+ {
+ USB_HostFreeTransfer(phdcInstance->hostHandle, transfer);
+ return;
+ }
+ }
+#endif
+ if (NULL != phdcInstance->outCallbackFn)
+ {
+ phdcInstance->outCallbackFn(phdcInstance->outCallbackParam, transfer->transferBuffer, transfer->transferSofar,
+ status);
+ }
+ USB_HostFreeTransfer(phdcInstance->hostHandle, transfer);
+}
+
+/*!
+ * @brief phdc open interface.
+ *
+ * @param phdcInstance phdc instance pointer.
+ *
+ * @return kStatus_USB_Success or error codes.
+ */
+static usb_status_t USB_HostPhdcOpenInterface(usb_host_phdc_instance_t *phdcInstance)
+{
+ usb_status_t status;
+ uint8_t epIndex = 0U;
+ usb_host_pipe_init_t pipeInit;
+ usb_descriptor_endpoint_t *epDesc = NULL;
+ usb_host_interface_t *interface;
+ if (NULL != phdcInstance->interruptPipe)
+ {
+ /* Close the PHDC interrupt pipe if it is opening */
+ status = USB_HostClosePipe(phdcInstance->hostHandle, phdcInstance->interruptPipe);
+
+ if (status != kStatus_USB_Success)
+ {
+#ifdef HOST_ECHO
+ usb_echo("USB_HostPhdcOpenInterface: Error when close pipe\r\n");
+#endif
+ }
+ phdcInstance->interruptPipe = NULL;
+ }
+
+ if (NULL != phdcInstance->bulkInPipe)
+ {
+ /* Close the PHDC bulk in pipe if it is opening */
+ status = USB_HostClosePipe(phdcInstance->hostHandle, phdcInstance->bulkInPipe);
+
+ if (status != kStatus_USB_Success)
+ {
+#ifdef HOST_ECHO
+ usb_echo("USB_HostPhdcOpenInterface: Error when close pipe\r\n");
+#endif
+ }
+ phdcInstance->bulkInPipe = NULL;
+ }
+
+ if (NULL != phdcInstance->bulkOutPipe)
+ {
+ /* Close the PHDC bulk out pipe if it is opening */
+ status = USB_HostClosePipe(phdcInstance->hostHandle, phdcInstance->bulkOutPipe);
+
+ if (status != kStatus_USB_Success)
+ {
+#ifdef HOST_ECHO
+ usb_echo("USB_HostPhdcOpenInterface: Error when close pipe\r\n");
+#endif
+ }
+ phdcInstance->bulkOutPipe = NULL;
+ }
+
+ /* open interface pipes */
+ interface = (usb_host_interface_t *)phdcInstance->interfaceHandle;
+ for (epIndex = 0U; epIndex < interface->epCount; ++epIndex)
+ {
+ epDesc = interface->epList[epIndex].epDesc;
+ if (((epDesc->bEndpointAddress & USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_MASK) ==
+ USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_IN) &&
+ ((epDesc->bmAttributes & USB_DESCRIPTOR_ENDPOINT_ATTRIBUTE_TYPE_MASK) == USB_ENDPOINT_INTERRUPT))
+ {
+ /* Initialize the interrupt pipe */
+ pipeInit.devInstance = phdcInstance->deviceHandle;
+ pipeInit.pipeType = USB_ENDPOINT_INTERRUPT;
+ pipeInit.direction = USB_IN;
+ pipeInit.endpointAddress = (epDesc->bEndpointAddress & USB_DESCRIPTOR_ENDPOINT_ADDRESS_NUMBER_MASK);
+ pipeInit.interval = epDesc->bInterval;
+ pipeInit.maxPacketSize = (uint16_t)(USB_SHORT_FROM_LITTLE_ENDIAN_ADDRESS(epDesc->wMaxPacketSize) &
+ USB_DESCRIPTOR_ENDPOINT_MAXPACKETSIZE_SIZE_MASK);
+ pipeInit.numberPerUframe = (USB_SHORT_FROM_LITTLE_ENDIAN_ADDRESS(epDesc->wMaxPacketSize) &
+ USB_DESCRIPTOR_ENDPOINT_MAXPACKETSIZE_MULT_TRANSACTIONS_MASK);
+ pipeInit.nakCount = USB_HOST_CONFIG_MAX_NAK;
+ status = USB_HostOpenPipe(phdcInstance->hostHandle, &phdcInstance->interruptPipe, &pipeInit);
+ if (status != kStatus_USB_Success)
+ {
+#ifdef HOST_ECHO
+ usb_echo("USB_HostPhdcOpenInterface: Error when open pipe\r\n");
+#endif
+ return kStatus_USB_Error;
+ }
+ /* save interrupt in endpoint information */
+ phdcInstance->interruptInEndpointInformation = interface->epList[epIndex];
+ }
+ else if (((epDesc->bEndpointAddress & USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_MASK) ==
+ USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_IN) &&
+ ((epDesc->bmAttributes & USB_DESCRIPTOR_ENDPOINT_ATTRIBUTE_TYPE_MASK) == USB_ENDPOINT_BULK))
+ {
+ /* Initialize bulk in pipe */
+ pipeInit.devInstance = phdcInstance->deviceHandle;
+ pipeInit.pipeType = USB_ENDPOINT_BULK;
+ pipeInit.direction = USB_IN;
+ pipeInit.endpointAddress = (epDesc->bEndpointAddress & USB_DESCRIPTOR_ENDPOINT_ADDRESS_NUMBER_MASK);
+ pipeInit.maxPacketSize = (uint16_t)(USB_SHORT_FROM_LITTLE_ENDIAN_ADDRESS(epDesc->wMaxPacketSize) &
+ USB_DESCRIPTOR_ENDPOINT_MAXPACKETSIZE_SIZE_MASK);
+ pipeInit.numberPerUframe = (USB_SHORT_FROM_LITTLE_ENDIAN_ADDRESS(epDesc->wMaxPacketSize) &
+ USB_DESCRIPTOR_ENDPOINT_MAXPACKETSIZE_MULT_TRANSACTIONS_MASK);
+ pipeInit.nakCount = USB_HOST_CONFIG_MAX_NAK;
+ status = USB_HostOpenPipe(phdcInstance->hostHandle, &phdcInstance->bulkInPipe, &pipeInit);
+ if (status != kStatus_USB_Success)
+ {
+#ifdef HOST_ECHO
+ usb_echo("USB_HostPhdcOpenInterface: Error when open pipe\r\n");
+#endif
+ return kStatus_USB_Error;
+ }
+ /* save bulk in endpoint information */
+ phdcInstance->bulkInEndpointInformation = interface->epList[epIndex];
+ }
+ else if (((epDesc->bEndpointAddress & USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_MASK) ==
+ USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_OUT) &&
+ ((epDesc->bmAttributes & USB_DESCRIPTOR_ENDPOINT_ATTRIBUTE_TYPE_MASK) == USB_ENDPOINT_BULK))
+ {
+ /* Initialize bulk out pipe */
+ pipeInit.devInstance = phdcInstance->deviceHandle;
+ pipeInit.pipeType = USB_ENDPOINT_BULK;
+ pipeInit.direction = USB_OUT;
+ pipeInit.endpointAddress = (epDesc->bEndpointAddress & USB_DESCRIPTOR_ENDPOINT_ADDRESS_NUMBER_MASK);
+ pipeInit.maxPacketSize = (uint16_t)(USB_SHORT_FROM_LITTLE_ENDIAN_ADDRESS(epDesc->wMaxPacketSize) &
+ USB_DESCRIPTOR_ENDPOINT_MAXPACKETSIZE_SIZE_MASK);
+ pipeInit.numberPerUframe = (USB_SHORT_FROM_LITTLE_ENDIAN_ADDRESS(epDesc->wMaxPacketSize) &
+ USB_DESCRIPTOR_ENDPOINT_MAXPACKETSIZE_MULT_TRANSACTIONS_MASK);
+ pipeInit.nakCount = USB_HOST_CONFIG_MAX_NAK;
+ status = USB_HostOpenPipe(phdcInstance->hostHandle, &phdcInstance->bulkOutPipe, &pipeInit);
+ if (status != kStatus_USB_Success)
+ {
+#ifdef HOST_ECHO
+ usb_echo("USB_HostPhdcOpenInterface: Error when open pipe\r\n");
+#endif
+ return kStatus_USB_Error;
+ }
+ /* save bulk out endpoint information */
+ phdcInstance->bulkOutEndpointInformation = interface->epList[epIndex];
+ }
+ else
+ {
+ }
+ }
+ return kStatus_USB_Success;
+}
+
+/*!
+ * @brief phdc set interface callback, open pipes.
+ *
+ * @param param callback parameter.
+ * @param transfer callback transfer.
+ * @param status transfer status.
+ */
+static void USB_HostPhdcSetInterfaceCallback(void *param, usb_host_transfer_t *transfer, usb_status_t status)
+{
+ usb_host_phdc_instance_t *phdcInstance = (usb_host_phdc_instance_t *)param;
+
+ phdcInstance->controlTransfer = NULL;
+ if (status == kStatus_USB_Success)
+ {
+ /* set interface is done, open the interface */
+ status = USB_HostPhdcOpenInterface(phdcInstance);
+ }
+
+ if (NULL != phdcInstance->controlCallbackFn)
+ {
+ /* Notify to application the status of set interface request */
+ phdcInstance->controlCallbackFn(phdcInstance->controlCallbackParam, NULL, 0U, status);
+ }
+ USB_HostFreeTransfer(phdcInstance->hostHandle, transfer);
+}
+
+/*!
+ * @brief set interface.
+ *
+ * This function binds the interface with the phdc instance.
+ *
+ * @param classHandle the class handle.
+ * @param interfaceHandle the interface handle.
+ * @param alternateSetting the alternate setting value.
+ * @param callbackFn this callback is called after this function completes.
+ * @param callbackParam the first parameter in the callback function.
+ *
+ * @retval kStatus_USB_Success The device is initialized successfully.
+ * @retval kStatus_USB_InvalidHandle The classHandle is NULL pointer.
+ * @retval kStatus_USB_Busy There is no idle transfer.
+ * @retval kStatus_USB_Error send transfer fail, please reference to USB_HostSendSetup.
+ * @retval kStatus_USB_Busy callback return status, there is no idle pipe.
+ * @retval kStatus_USB_TransferStall callback return status, the transfer is stall by device.
+ * @retval kStatus_USB_Error callback return status, open pipe fail, please reference to USB_HostOpenPipe.
+ */
+usb_status_t USB_HostPhdcSetInterface(usb_host_class_handle classHandle,
+ usb_host_interface_handle interfaceHandle,
+ uint8_t alternateSetting,
+ transfer_callback_t callbackFn,
+ void *callbackParam)
+{
+ usb_status_t status;
+ usb_host_phdc_instance_t *phdcInstance = (usb_host_phdc_instance_t *)classHandle;
+ usb_host_transfer_t *transfer;
+
+ if (NULL == classHandle)
+ {
+ return kStatus_USB_InvalidParameter;
+ }
+
+ phdcInstance->interfaceHandle = interfaceHandle;
+
+ status = USB_HostOpenDeviceInterface(phdcInstance->deviceHandle, interfaceHandle);
+ if (status != kStatus_USB_Success)
+ {
+ return status;
+ }
+
+ /* Cancel interrupt transfers */
+ if (NULL != phdcInstance->interruptPipe)
+ {
+ status = USB_HostCancelTransfer(phdcInstance->hostHandle, phdcInstance->interruptPipe, NULL);
+ if (status != kStatus_USB_Success)
+ {
+#ifdef HOST_ECHO
+ usb_echo("USB_HostPhdcSetInterface: Error when cancel pipe\r\n");
+#endif
+ }
+ }
+ /* Cancel bulk in transfers */
+ if (NULL != phdcInstance->bulkInPipe)
+ {
+ status = USB_HostCancelTransfer(phdcInstance->hostHandle, phdcInstance->bulkInPipe, NULL);
+ if (status != kStatus_USB_Success)
+ {
+#ifdef HOST_ECHO
+ usb_echo("USB_HostPhdcSetInterface: Error when cancel pipe\r\n");
+#endif
+ }
+ }
+ /* Cancel bulk out transfers */
+ if (NULL != phdcInstance->bulkOutPipe)
+ {
+ status = USB_HostCancelTransfer(phdcInstance->hostHandle, phdcInstance->bulkOutPipe, NULL);
+ if (status != kStatus_USB_Success)
+ {
+#ifdef HOST_ECHO
+ usb_echo("USB_HostPhdcSetInterface: Error when cancel pipe\r\n");
+#endif
+ }
+ phdcInstance->bulkOutPipe = NULL;
+ }
+ if (0U == alternateSetting)
+ {
+ if (NULL != callbackFn)
+ {
+ status = USB_HostPhdcOpenInterface(phdcInstance);
+ callbackFn(callbackParam, NULL, 0U, status);
+ }
+ }
+ else
+ {
+ /* Create transfer buffer */
+ if (USB_HostMallocTransfer(phdcInstance->hostHandle, &transfer) != kStatus_USB_Success)
+ {
+#ifdef HOST_ECHO
+ usb_echo("USB_HostPhdcSetInterface: Error to get transfer\r\n");
+#endif
+ return kStatus_USB_Error;
+ }
+ /* Save application callback function and parameter */
+ phdcInstance->controlCallbackFn = callbackFn;
+ phdcInstance->controlCallbackParam = callbackParam;
+ /* Initialize transfer */
+ transfer->callbackFn = USB_HostPhdcSetInterfaceCallback;
+ transfer->callbackParam = phdcInstance;
+ transfer->setupPacket.bRequest = USB_REQUEST_STANDARD_SET_INTERFACE;
+ transfer->setupPacket.bmRequestType = USB_REQUEST_TYPE_RECIPIENT_INTERFACE;
+ transfer->setupPacket.wIndex = USB_SHORT_TO_LITTLE_ENDIAN(
+ ((usb_host_interface_t *)phdcInstance->interfaceHandle)->interfaceDesc->bInterfaceNumber);
+ transfer->setupPacket.wValue = USB_SHORT_TO_LITTLE_ENDIAN(alternateSetting);
+ transfer->setupPacket.wLength = 0;
+ transfer->transferBuffer = NULL;
+ transfer->transferLength = 0;
+ /* Send set interface request to device */
+ status = USB_HostSendSetup(phdcInstance->hostHandle, phdcInstance->controlPipe, transfer);
+ if (status == kStatus_USB_Success)
+ {
+ phdcInstance->controlTransfer = transfer;
+ }
+ else
+ {
+ USB_HostFreeTransfer(phdcInstance->hostHandle, transfer);
+ }
+ }
+ return status;
+}
+
+/*!
+ * @brief initialize the phdc instance.
+ *
+ * This function allocates the resource for phdc instance.
+ *
+ * @param deviceHandle the device handle.
+ * @param classHandle return class handle.
+ *
+ * @retval kStatus_USB_Success The device is initialized successfully.
+ * @retval kStatus_USB_AllocFail Allocate memory fail.
+ */
+usb_status_t USB_HostPhdcInit(usb_host_handle deviceHandle, usb_host_class_handle *classHandle)
+{
+ usb_host_phdc_instance_t *phdcInstance =
+ (usb_host_phdc_instance_t *)USB_OsaMemoryAllocate(sizeof(usb_host_phdc_instance_t));
+ uint32_t infoValue;
+
+ if (NULL == phdcInstance)
+ {
+ return kStatus_USB_AllocFail;
+ }
+ /* Initialize PHDC instance */
+ phdcInstance->deviceHandle = deviceHandle;
+ phdcInstance->interfaceHandle = NULL;
+ USB_HostHelperGetPeripheralInformation(deviceHandle, kUSB_HostGetHostHandle, &infoValue);
+ phdcInstance->hostHandle = (usb_host_handle)infoValue;
+ USB_HostHelperGetPeripheralInformation(deviceHandle, kUSB_HostGetDeviceControlPipe, &infoValue);
+ phdcInstance->controlPipe = (usb_host_pipe_handle)infoValue;
+
+ *classHandle = phdcInstance;
+ return kStatus_USB_Success;
+}
+
+/*!
+ * @brief de-initialize the phdc instance.
+ *
+ * This function release the resource for phdc instance.
+ *
+ * @param deviceHandle the device handle.
+ * @param classHandle the class handle.
+ *
+ * @retval kStatus_USB_Success The device is de-initialized successfully.
+ */
+usb_status_t USB_HostPhdcDeinit(usb_host_handle deviceHandle, usb_host_class_handle classHandle)
+{
+ usb_status_t status;
+ usb_host_phdc_instance_t *phdcInstance = (usb_host_phdc_instance_t *)classHandle;
+
+ if (NULL == deviceHandle)
+ {
+ return kStatus_USB_InvalidHandle;
+ }
+
+ if (NULL != classHandle)
+ {
+ if (NULL != phdcInstance->interruptPipe)
+ {
+ /* Cancel/close interrupt transfers/pipe */
+ status = USB_HostCancelTransfer(phdcInstance->hostHandle, phdcInstance->interruptPipe, NULL);
+ status = USB_HostClosePipe(phdcInstance->hostHandle, phdcInstance->interruptPipe);
+
+ if (status != kStatus_USB_Success)
+ {
+#ifdef HOST_ECHO
+ usb_echo("USB_HostPhdcDeinit: Error when close pipe\r\n");
+#endif
+ }
+ phdcInstance->interruptPipe = NULL;
+ }
+ if (NULL != phdcInstance->bulkInPipe)
+ {
+ /* Cancel/close bulk in transfers/pipe */
+ status = USB_HostCancelTransfer(phdcInstance->hostHandle, phdcInstance->bulkInPipe, NULL);
+ status = USB_HostClosePipe(phdcInstance->hostHandle, phdcInstance->bulkInPipe);
+
+ if (status != kStatus_USB_Success)
+ {
+#ifdef HOST_ECHO
+ usb_echo("USB_HostPhdcDeinit: Error when close pipe\r\n");
+#endif
+ }
+ phdcInstance->bulkInPipe = NULL;
+ }
+ if (NULL != phdcInstance->bulkOutPipe)
+ {
+ /* Cancel/close bulk out transfers/pipe */
+ status = USB_HostCancelTransfer(phdcInstance->hostHandle, phdcInstance->bulkOutPipe, NULL);
+ status = USB_HostClosePipe(phdcInstance->hostHandle, phdcInstance->bulkOutPipe);
+
+ if (status != kStatus_USB_Success)
+ {
+#ifdef HOST_ECHO
+ usb_echo("USB_HostPhdcDeinit: Error when close pipe\r\n");
+#endif
+ }
+ phdcInstance->bulkOutPipe = NULL;
+ }
+ if ((NULL != phdcInstance->controlPipe) && (NULL != phdcInstance->controlTransfer))
+ {
+ /* Cancel control transfers */
+ status = USB_HostCancelTransfer(phdcInstance->hostHandle, phdcInstance->controlPipe,
+ phdcInstance->controlTransfer);
+ }
+ /* Close device interface */
+ USB_HostCloseDeviceInterface(deviceHandle, phdcInstance->interfaceHandle);
+ /* Release PHDC instance */
+ USB_OsaMemoryFree(phdcInstance);
+ }
+ else
+ {
+ USB_HostCloseDeviceInterface(deviceHandle, NULL);
+ }
+ return kStatus_USB_Success;
+}
+
+/*!
+ * @brief receive data.
+ *
+ * This function implements phdc receiving data.
+ *
+ * @param classHandle the class handle.
+ * @param qos QoS of the data being received.
+ * @param buffer the buffer pointer.
+ * @param bufferLength the buffer length.
+ * @param callbackFn this callback is called after this function completes.
+ * @param callbackParam the first parameter in the callback function.
+ *
+ * @retval kStatus_USB_Success receive request successfully.
+ * @retval kStatus_USB_InvalidHandle The classHandle is NULL pointer.
+ * @retval kStatus_USB_Busy There is no idle transfer.
+ * @retval kStatus_USB_Error pipe is not initialized.
+ * Or, send transfer fail, please reference to USB_HostRecv.
+ */
+usb_status_t USB_HostPhdcRecv(usb_host_class_handle classHandle,
+ uint8_t qos,
+ uint8_t *buffer,
+ uint32_t bufferLength,
+ transfer_callback_t callbackFn,
+ void *callbackParam)
+{
+ usb_host_phdc_instance_t *phdcInstance = (usb_host_phdc_instance_t *)classHandle;
+ usb_host_transfer_t *transfer;
+ usb_host_pipe_handle pipe;
+ usb_host_phdc_qos_descriptor_t *qosDesc = NULL;
+
+ if (NULL == classHandle)
+ {
+ return kStatus_USB_InvalidHandle;
+ }
+
+ if ((NULL == phdcInstance->interruptPipe) && (NULL == phdcInstance->bulkInPipe))
+ {
+ return kStatus_USB_Error;
+ }
+ /* Allocate the transfer buffer */
+ if (USB_HostMallocTransfer(phdcInstance->hostHandle, &transfer) != kStatus_USB_Success)
+ {
+#ifdef HOST_ECHO
+ usb_echo("error to get transfer\r\n");
+#endif
+ return kStatus_USB_Error;
+ }
+ /* Save application callback function and parameter */
+ phdcInstance->inCallbackFn = callbackFn;
+ phdcInstance->inCallbackParam = callbackParam;
+ /* Initialize the transfer pointer */
+ transfer->transferBuffer = buffer;
+ transfer->transferLength = bufferLength;
+ transfer->callbackParam = phdcInstance;
+ /* The on can receive the data on interrupt pipe or bulk in pipe depends on the QoS value */
+ pipe = (qos & 0x01U) ? (phdcInstance->interruptPipe) : (phdcInstance->bulkInPipe);
+ if (pipe == phdcInstance->bulkInPipe)
+ {
+ /* get bulk in QoS descriptor */
+ qosDesc = (usb_host_phdc_qos_descriptor_t *)phdcInstance->bulkInEndpointInformation.epExtension;
+ transfer->callbackFn = USB_HostPhdcBulkInPipeCallback;
+ }
+ else
+ {
+ /* get interrupt in QoS descriptor */
+ qosDesc = (usb_host_phdc_qos_descriptor_t *)phdcInstance->interruptInEndpointInformation.epExtension;
+ transfer->callbackFn = USB_HostPhdcInterruptPipeCallback;
+ }
+ /* Latency and reliability checking */
+ if (!(qos & qosDesc->bmLatencyReliability))
+ {
+#ifdef HOST_ECHO
+ usb_echo("USB_HostPhdcRecv, ERROR: invalid QoS bin");
+#endif
+ return kStatus_USB_Error;
+ }
+ /* The previous control transfer is pending */
+ if (NULL != phdcInstance->controlTransfer)
+ {
+#ifdef HOST_ECHO
+ usb_echo("USB_HostPhdcRecv, ERROR: Control transfer is in progress");
+#endif
+ return kStatus_USB_Busy;
+ }
+ if (USB_HostRecv(phdcInstance->hostHandle, pipe, transfer) != kStatus_USB_Success)
+ {
+#ifdef HOST_ECHO
+ usb_echo("fail to USB_HostRecv\r\n");
+#endif
+ USB_HostFreeTransfer(phdcInstance->hostHandle, transfer);
+ return kStatus_USB_Error;
+ }
+
+ return kStatus_USB_Success;
+}
+
+/*!
+ * @brief send data.
+ *
+ * This function implements phdc sending data.
+ *
+ * @param classHandle the class handle.
+ * @param buffer the buffer pointer.
+ * @param bufferLength the buffer length.
+ * @param callbackFn this callback is called after this function completes.
+ * @param callbackParam the first parameter in the callback function.
+ *
+ * @retval kStatus_USB_Success send request successfully.
+ * @retval kStatus_USB_InvalidHandle The classHandle is NULL pointer.
+ * @retval kStatus_USB_Busy There is no idle transfer.
+ * @retval kStatus_USB_Error pipe is not initialized.
+ * Or, send transfer fail, please reference to USB_HostSend.
+ */
+usb_status_t USB_HostPhdcSend(usb_host_class_handle classHandle,
+ uint8_t *buffer,
+ uint32_t bufferLength,
+ transfer_callback_t callbackFn,
+ void *callbackParam)
+{
+ usb_host_phdc_instance_t *phdcInstance = (usb_host_phdc_instance_t *)classHandle;
+ usb_host_transfer_t *transfer;
+ usb_status_t status;
+ if (classHandle == NULL)
+ {
+ return kStatus_USB_InvalidHandle;
+ }
+
+ if (NULL == phdcInstance->bulkOutPipe)
+ {
+ return kStatus_USB_Error;
+ }
+ if (NULL != phdcInstance->controlTransfer)
+ {
+ status = kStatus_USB_Busy;
+#ifdef HOST_ECHO
+ usb_echo("USB_HostPhdcSend, Error: control transfer is in progress");
+#endif
+ return status;
+ }
+ /* The meta-data message preamble is implemented and enabled */
+ if (phdcInstance->isMessagePreambleEnabled == 1U)
+ {
+ /* The meta-data message preamble feature is enabled, then all data transfers or sets
+ of data transfers shall be preceded by a meta-data message preamble transfer. The
+ numberTransferBulkOut is initialized as zero for sending this message preamble data,
+ then it is updated to the value of bNumTransfers field of message preamble data */
+ if (phdcInstance->numberTransferBulkOut)
+ {
+ /* When numberTransferBulkOut reduces to 0, a new meta-data message preamble shall
+ be transferred */
+ phdcInstance->numberTransferBulkOut--;
+ }
+ else
+ {
+ usb_host_phdc_qos_descriptor_t *qosDesc =
+ (usb_host_phdc_qos_descriptor_t *)phdcInstance->bulkOutEndpointInformation.epExtension;
+ ;
+ uint8_t latencyReliability = ((usb_host_phdc_metadata_preamble_t *)buffer)->bmLatencyReliability;
+ /* Latency reliability validity checking */
+ if ((latencyReliability != 0x02U) && /* Medium.Good latency, reliability bin */
+ (latencyReliability != 0x04U) && /* Medium.Better latency, reliability bin */
+ (latencyReliability != 0x08U) && /* Medium.Best latency, reliability bin */
+ (latencyReliability != 0x10U) && /* High.Best latency, reliability bin */
+ (latencyReliability != 0x20U) /* VeryHigh.Best latency, reliability bin */)
+ {
+ status = kStatus_USB_InvalidRequest;
+#ifdef HOST_ECHO
+ usb_echo("USB_HostPhdcSend, Error: invalid LatencyReliability");
+#endif
+ return status;
+ }
+ /* LatencyReliablity checking */
+ if (0U == (qosDesc->bmLatencyReliability & latencyReliability))
+ {
+ status = kStatus_USB_Error;
+#ifdef HOST_ECHO
+ usb_echo("USB_HostPhdcSend, Error: the latency reliability is not supported by Bulk OUT endpoint");
+#endif
+ return status;
+ }
+ if (0U == ((usb_host_phdc_metadata_preamble_t *)buffer)->bNumberTransfers)
+ {
+ status = kStatus_USB_Error;
+#ifdef HOST_ECHO
+ usb_echo("USB_HostPhdcSend, Error: the numTransfer should never zero");
+#endif
+ return status;
+ }
+ /* Update the number of bulk out transfer */
+ phdcInstance->numberTransferBulkOut = ((usb_host_phdc_metadata_preamble_t *)buffer)->bNumberTransfers;
+ }
+ }
+ /* Allocate the transfer pointer */
+ if (USB_HostMallocTransfer(phdcInstance->hostHandle, &transfer) != kStatus_USB_Success)
+ {
+#ifdef HOST_ECHO
+ usb_echo("error to get transfer\r\n");
+#endif
+ return kStatus_USB_Error;
+ }
+ /* Save the application callback function and parameter */
+ phdcInstance->outCallbackFn = callbackFn;
+ phdcInstance->outCallbackParam = callbackParam;
+ /* Initialize the transfer pointer */
+ transfer->transferBuffer = buffer;
+ transfer->transferLength = bufferLength;
+ transfer->callbackFn = USB_HostPhdcBulkOutPipeCallback;
+ transfer->callbackParam = phdcInstance;
+ if (USB_HostSend(phdcInstance->hostHandle, phdcInstance->bulkOutPipe, transfer) != kStatus_USB_Success)
+ {
+#ifdef HOST_ECHO
+ usb_echo("fail to USB_HostSend\r\n");
+#endif
+ USB_HostFreeTransfer(phdcInstance->hostHandle, transfer);
+ return kStatus_USB_Error;
+ }
+ return kStatus_USB_Success;
+}
+
+/*!
+ * @brief phdc sends control request.
+ *
+ * @param classHandle the class handle.
+ * @param request_type setup packet request.
+ * @param callbackFn this callback is called after this function completes.
+ * @param callbackParam the first parameter in the callback function.
+ *
+ * @retval kStatus_USB_Success send request successfully.
+ * @retval kStatus_USB_InvalidHandle The classHandle is NULL pointer.
+ * @retval kStatus_USB_Busy There is no idle transfer.
+ * @retval kStatus_USB_Error pipe is not initialized.
+ * Or, send transfer fail, please reference to USB_HostSend.
+ */
+usb_status_t USB_HostPhdcSendControlRequest(usb_host_class_handle classHandle,
+ uint8_t request,
+ transfer_callback_t callbackFn,
+ void *callbackParam)
+{
+ usb_host_phdc_instance_t *phdcInstance = (usb_host_phdc_instance_t *)classHandle;
+ usb_status_t status = kStatus_USB_Success;
+ usb_host_transfer_t *transfer;
+
+ if (NULL == classHandle)
+ {
+ return kStatus_USB_InvalidHandle;
+ }
+
+ if (NULL == phdcInstance->controlPipe)
+ {
+ return kStatus_USB_Error;
+ }
+
+ if (NULL != phdcInstance->controlTransfer)
+ {
+ return kStatus_USB_Busy;
+ }
+ /* Allocate the transfer pointer */
+ if (USB_HostMallocTransfer(phdcInstance->hostHandle, &transfer) != kStatus_USB_Success)
+ {
+#ifdef HOST_ECHO
+ usb_echo("error to get transfer\r\n");
+#endif
+ return kStatus_USB_Error;
+ }
+ /* Save the callback function and parameter */
+ phdcInstance->controlCallbackFn = callbackFn;
+ phdcInstance->controlCallbackParam = callbackParam;
+ /* Initialize the transfer pointer */
+ transfer->callbackFn = USB_HostPhdcControlPipeCallback;
+ transfer->callbackParam = phdcInstance;
+ transfer->setupPacket.bRequest = request;
+ transfer->setupPacket.wIndex = USB_SHORT_TO_LITTLE_ENDIAN(
+ ((usb_host_interface_t *)phdcInstance->interfaceHandle)->interfaceDesc->bInterfaceNumber);
+ switch (request)
+ {
+ case USB_HOST_PHDC_GET_STATUS_REQUEST:
+ /* Initialize the PHDC get status request */
+ transfer->setupPacket.wValue = 0U;
+ transfer->setupPacket.bmRequestType =
+ USB_REQUEST_TYPE_DIR_IN | USB_REQUEST_TYPE_TYPE_CLASS | USB_REQUEST_TYPE_RECIPIENT_INTERFACE;
+ transfer->setupPacket.wLength = 2U;
+ break;
+ case USB_HOST_PHDC_SET_FEATURE_REQUEST:
+ case USB_HOST_PHDC_CLEAR_FEATURE_REQUEST:
+ /* Initialize the PHDC set/clear feature request */
+ transfer->setupPacket.bmRequestType =
+ USB_REQUEST_TYPE_DIR_OUT | USB_REQUEST_TYPE_TYPE_CLASS | USB_REQUEST_TYPE_RECIPIENT_INTERFACE;
+ transfer->setupPacket.wValue =
+ (USB_HOST_PHDC_FEATURE_METADATA | (uint16_t)((uint16_t)USB_HOST_PHDC_QOS_ENCODING_VERSION << 8U));
+ transfer->setupPacket.wLength = 0U;
+ break;
+ default:
+ status = kStatus_USB_InvalidRequest;
+ break;
+ }
+ if (USB_HostSendSetup(phdcInstance->hostHandle, phdcInstance->controlPipe, transfer) != kStatus_USB_Success)
+ {
+#ifdef HOST_ECHO
+ usb_echo("fail for USB_HostSendSetup\r\n");
+#endif
+ USB_HostFreeTransfer(phdcInstance->hostHandle, transfer);
+ return kStatus_USB_Error;
+ }
+ phdcInstance->controlTransfer = transfer;
+
+ return status;
+}
+
+/*!
+ * @brief phdc set and clear feature endpoint halt request for meta-data message preamble error.
+ *
+ * @param classHandle the class handle.
+ * @param request setup packet request.
+ * @param param request parameter
+ * @param callbackFn this callback is called after this function completes.
+ * @param callbackParam the first parameter in the callback function.
+ *
+ * @retval kStatus_USB_Success send request successfully.
+ * @retval kStatus_USB_InvalidHandle The classHandle is NULL pointer.
+ * @retval kStatus_USB_Busy There is no idle transfer.
+ * @retval kStatus_USB_Error pipe is not initialized.
+ * Or, send transfer fail, please reference to USB_HostSend.
+ */
+usb_status_t USB_HostPhdcSetClearFeatureEndpointHalt(usb_host_class_handle classHandle,
+ uint8_t request,
+ void *param,
+ transfer_callback_t callbackFn,
+ void *callbackParam)
+{
+ usb_host_phdc_instance_t *phdcInstance = (usb_host_phdc_instance_t *)classHandle;
+ usb_host_transfer_t *transfer;
+ if (NULL == classHandle)
+ {
+ return kStatus_USB_InvalidHandle;
+ }
+
+ if (NULL == phdcInstance->controlPipe)
+ {
+ return kStatus_USB_Error;
+ }
+
+ if (NULL != phdcInstance->controlTransfer)
+ {
+ return kStatus_USB_Busy;
+ }
+ /* Allocate the transfer pointer */
+ if (USB_HostMallocTransfer(phdcInstance->hostHandle, &transfer) != kStatus_USB_Success)
+ {
+#ifdef HOST_ECHO
+ usb_echo("error to get transfer\r\n");
+#endif
+ return kStatus_USB_Error;
+ }
+ /* Save application callback function and parameter */
+ phdcInstance->controlCallbackFn = callbackFn;
+ phdcInstance->controlCallbackParam = callbackParam;
+ /* Initialize the transfer request */
+ transfer->callbackFn = USB_HostPhdcSetClearFeatureEndpointHaltCallback;
+ transfer->callbackParam = phdcInstance;
+ if (USB_HostRequestControl(phdcInstance->hostHandle, request, transfer, param))
+ {
+#ifdef HOST_ECHO
+ usb_echo("fail for USB_HostRequestControl\r\n");
+#endif
+ USB_HostFreeTransfer(phdcInstance->hostHandle, transfer);
+ return kStatus_USB_Error;
+ }
+ phdcInstance->controlTransfer = transfer;
+
+ return kStatus_USB_Success;
+}
+
+/*!
+ * @brief USB_HostPhdcGetEndpointInformation.
+ * This function returns the PHDC endpoint information structure contains endpoint
+ * descriptor and endpoint extended descriptor.
+ *
+ * @param classHandle the class handle.
+ * @param pipeType pipe type.
+ * @param direction pipe direction.
+ *
+ * @retval endpointReturn All input parameters are valid.
+ * @retval NULL One or more input parameters are invalid.
+ */
+usb_host_ep_t *USB_HostPhdcGetEndpointInformation(usb_host_class_handle classHandle,
+ uint8_t pipeType,
+ uint8_t direction)
+{
+ usb_host_phdc_instance_t *phdcInstance = (usb_host_phdc_instance_t *)classHandle;
+ usb_host_ep_t *endpointReturn = NULL;
+ if (NULL != classHandle)
+ {
+ if (pipeType == USB_ENDPOINT_BULK)
+ {
+ if (direction == USB_IN)
+ {
+ /* bulk in endpoint information */
+ endpointReturn = (usb_host_ep_t *)&phdcInstance->bulkInEndpointInformation;
+ }
+ else
+ {
+ /* bulk out endpoint information */
+ endpointReturn = (usb_host_ep_t *)&phdcInstance->bulkOutEndpointInformation;
+ }
+ }
+ else if (pipeType == USB_ENDPOINT_INTERRUPT)
+ {
+ /* interrupt in endpoint information */
+ endpointReturn = (usb_host_ep_t *)&phdcInstance->interruptInEndpointInformation;
+ }
+ else
+ {
+ }
+ }
+ return endpointReturn;
+}
+#endif
diff --git a/usb_1.1.0/host/class/usb_host_phdc.h b/usb_1.1.0/host/class/usb_host_phdc.h
new file mode 100644
index 0000000..4b62b6b
--- /dev/null
+++ b/usb_1.1.0/host/class/usb_host_phdc.h
@@ -0,0 +1,329 @@
+/*
+ * Copyright (c) 2015, Freescale Semiconductor, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * o Redistributions of source code must retain the above copyright notice, this list
+ * of conditions and the following disclaimer.
+ *
+ * o Redistributions in binary form must reproduce the above copyright notice, this
+ * list of conditions and the following disclaimer in the documentation and/or
+ * other materials provided with the distribution.
+ *
+ * o Neither the name of Freescale Semiconductor, Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __USB_HOST_PHDC_H__
+#define __USB_HOST_PHDC_H__
+
+/*******************************************************************************
+ * PHDC class public structure, enumeration, macro, function
+ ******************************************************************************/
+/*!
+ * @addtogroup usb_host_phdc_drv
+ * @{
+ */
+
+/*******************************************************************************
+ * Definitions
+ ******************************************************************************/
+
+/*! @brief PHDC class code */
+#define USB_HOST_PHDC_CLASS_CODE (0x0FU)
+/*! @brief PHDC sub class code */
+#define USB_HOST_PHDC_SUBCLASS_CODE (0x00U)
+/*! @brief PHDC protocol */
+#define USB_HOST_PHDC_PROTOCOL (0x00U)
+/*! @brief PHDC get status request */
+#define USB_HOST_PHDC_GET_STATUS_REQUEST (0x00U)
+/*! @brief PHDC set feature request */
+#define USB_HOST_PHDC_SET_FEATURE_REQUEST (0x03U)
+/*! @brief PHDC clear feature request */
+#define USB_HOST_PHDC_CLEAR_FEATURE_REQUEST (0x01U)
+/*! @brief PHDC meta-data feature */
+#define USB_HOST_PHDC_FEATURE_METADATA (0x01U)
+/*! @brief PHDC QoS information encoding feature */
+#define USB_HOST_PHDC_QOS_ENCODING_VERSION (0x01U)
+
+/*! @brief meta-data message preamble signature size */
+#define USB_HOST_PHDC_MESSAGE_PREAMBLE_SIGNATURE_SIZE (0x10U)
+
+/*! @brief PHDC class function descriptor type */
+#define USB_HOST_PHDC_CLASSFUNCTION_DESCRIPTOR (0x20U)
+/*! @brief PHDC QoS descriptor type */
+#define USB_HOST_PHDC_QOS_DESCRIPTOR (0x21U)
+/*! @brief PHDC function extension descriptor type */
+#define USB_HOST_PHDC_11073PHD_FUNCTION_DESCRIPTOR (0x30U)
+/*! @brief PHDC meta-data descriptor type */
+#define USB_HOST_PHDC_METADATA_DESCRIPTOR (0x22U)
+
+/*! @brief PHDC class function descriptor structure as defined by the PHDC class specification */
+typedef struct _usb_host_phdc_class_function_desciptor
+{
+ uint8_t bLength; /*!< Class function descriptor length */
+ uint8_t bDescriptortype; /*!< PHDC_CLASSFUNCTION_DESCRIPTOR type */
+ uint8_t bPhdcDataCode; /*!< Data/Messaging format code */
+ uint8_t bmCapability; /*!< If bit 0 is 1 the meta-data message preamble is implemented and 0 if it is not */
+} usb_host_phdc_class_function_desciptor_t;
+
+/*! @brief Function extension descriptor (device specialization) structure as defined by the PHDC class specification.
+ */
+typedef struct _usb_host_phdc_function_extension_descriptor
+{
+ uint8_t bLength; /*!< Function extension descriptor length */
+ uint8_t bDescriptortype; /*!< PHDC_CLASSFUNCTION_DESCRIPTOR type */
+ uint8_t bReserved; /*!< Reserved for future use */
+ uint8_t bNumDevSpecs; /*!< Number of wDevSpecializations */
+ uint16_t *wDevSpecializations; /*!< Variable length list that defines the device specialization */
+} usb_host_phdc_function_extension_descriptor_t;
+
+/*! @brief QoS descriptor structure as defined by the PHDC class specification. */
+typedef struct _usb_host_phdc_qos_descriptor
+{
+ uint8_t bLength; /*!< QoS descriptor length */
+ uint8_t bDescriptortype; /*!< PHDC_QOS_DESCRIPTOR type */
+ uint8_t bQosEncodingVersion; /*!< Version of QoS information encoding */
+ uint8_t bmLatencyReliability; /*!< Latency/reliability bin for the QoS data */
+} usb_host_phdc_qos_descriptor_t;
+
+/*! @brief Metadata descriptor structure as defined by the PHDC class specification. */
+typedef struct _usb_host_phdc_metadata_descriptor
+{
+ uint8_t bLength; /*!< Metadata descriptor length */
+ uint8_t bDescriptortype; /*!< Descriptor type */
+ uint8_t *bOpaqueData; /*!< Opaque metadata */
+} usb_host_phdc_metadata_descriptor_t;
+
+/*! @brief Metadata message preamble structure as defined by the PHDC class specification. */
+typedef struct _usb_host_phdc_metadata_preamble
+{
+ uint8_t
+ aSignature[USB_HOST_PHDC_MESSAGE_PREAMBLE_SIGNATURE_SIZE]; /*!< Constant used to give preamble verifiability */
+ uint8_t bNumberTransfers; /*!< Count of following transfer to which the QoS setting applies */
+ uint8_t bQosEncodingVersion; /*!< Version of QoS information encoding */
+ uint8_t bmLatencyReliability; /*!< See latency/reliability bin for the QoS data */
+ uint8_t bOpaqueDataSize; /*!< Opaque QoS data or meta-data size */
+ uint8_t *bOpaqueData; /*!< Opaque metadata */
+} usb_host_phdc_metadata_preamble_t;
+
+/*! @brief PHDC instance structure */
+typedef struct _usb_host_phdc_instance
+{
+ usb_host_handle hostHandle; /*!< The host handle */
+ usb_device_handle deviceHandle; /*!< The device handle */
+ usb_host_interface_handle interfaceHandle; /*!< The interface handle */
+ usb_host_pipe_handle controlPipe; /*!< The control pipe */
+ usb_host_pipe_handle interruptPipe; /*!< The interrupt pipe */
+ usb_host_pipe_handle bulkInPipe; /*!< The bulk in pipe */
+ usb_host_pipe_handle bulkOutPipe; /*!< The bulk out pipe */
+ transfer_callback_t inCallbackFn; /*!< The callback function is called when the PHDC receives complete */
+ void *inCallbackParam; /*!< The first parameter of the in callback function */
+ transfer_callback_t outCallbackFn; /*!< The callback function is called when the PHDC sends complete */
+ void *outCallbackParam; /*!< The first parameter of the out callback function */
+ transfer_callback_t controlCallbackFn; /*!< The control callback function */
+ void *controlCallbackParam; /*!< The first parameter of the control callback function */
+ usb_host_transfer_t *controlTransfer; /*!< The control transfer pointer */
+
+#if ((defined USB_HOST_CONFIG_CLASS_AUTO_CLEAR_STALL) && USB_HOST_CONFIG_CLASS_AUTO_CLEAR_STALL)
+ uint8_t *stallDataBuffer; /*!< keep the data buffer for stall transfer's data*/
+ uint32_t stallDataLength; /*!< keep the data length for stall transfer's data*/
+#endif
+
+ usb_host_ep_t interruptInEndpointInformation; /*!< The interrupt in information */
+ usb_host_ep_t bulkInEndpointInformation; /*!< The bulk in information */
+ usb_host_ep_t bulkOutEndpointInformation; /*!< The bulk out information */
+ uint8_t isMessagePreambleEnabled; /*!< The flag is used to check the message preamble feature is enabled or not */
+ uint8_t numberTransferBulkOut; /*!< The number of transfer that follow Meta-data Message Preamble */
+ uint8_t numberTransferBulkIn; /*!< The number of transfer that follow Meta-data Message Preamble */
+} usb_host_phdc_instance_t;
+
+/*******************************************************************************
+ * API
+ ******************************************************************************/
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*!
+ * @name USB host PHDC class APIs
+ * @{
+ */
+
+/*!
+ * @brief Initializes the PHDC instance.
+ *
+ * This function allocates the resource for PHDC instance.
+ *
+ * @param deviceHandle The device handle.
+ * @param classHandle Return class handle.
+ *
+ * @retval kStatus_USB_Success The device is initialized successfully.
+ * @retval kStatus_USB_AllocFail Allocate memory fail.
+ */
+extern usb_status_t USB_HostPhdcInit(usb_host_handle deviceHandle, usb_host_class_handle *classHandle);
+
+/*!
+ * @brief Sets an interface.
+ *
+ * This function binds the interface with the PHDC instance.
+ *
+ * @param classHandle The class handle.
+ * @param interfaceHandle The interface handle.
+ * @param alternateSetting The alternate setting value.
+ * @param callbackFn This callback is called after this function completes.
+ * @param callbackParam The first parameter in the callback function.
+ *
+ * @retval kStatus_USB_Success The device is initialized successfully.
+ * @retval kStatus_USB_InvalidHandle The classHandle is NULL pointer.
+ * @retval kStatus_USB_Busy There is no idle transfer.
+ * @retval kStatus_USB_Error Send transfer fail. See the USB_HostSendSetup.
+ * @retval kStatus_USB_Busy Callback return status, there is no idle pipe.
+ * @retval kStatus_USB_TransferStall Callback return status, the transfer is stalled by the device.
+ * @retval kStatus_USB_Error Callback return status, open pipe fail. See the USB_HostOpenPipe.
+ */
+extern usb_status_t USB_HostPhdcSetInterface(usb_host_class_handle classHandle,
+ usb_host_interface_handle interfaceHandle,
+ uint8_t alternateSetting,
+ transfer_callback_t callbackFn,
+ void *callbackParam);
+
+/*!
+ * @brief Deinitializes the PHDC instance.
+ *
+ * This function frees the resource for the PHDC instance.
+ *
+ * @param deviceHandle The device handle.
+ * @param classHandle The class handle.
+ *
+ * @retval kStatus_USB_Success The device is deinitialized successfully.
+ */
+extern usb_status_t USB_HostPhdcDeinit(usb_host_handle deviceHandle, usb_host_class_handle classHandle);
+
+/*!
+ * @brief Receives data.
+ *
+ * This function implements the PHDC receiving data.
+ *
+ * @param classHandle The class handle.
+ * @param qos QoS of the data being received.
+ * @param buffer The buffer pointer.
+ * @param bufferLength The buffer length.
+ * @param callbackFn This callback is called after this function completes.
+ * @param callbackParam The first parameter in the callback function.
+ *
+ * @retval kStatus_USB_Success Receive request successfully.
+ * @retval kStatus_USB_InvalidHandle The classHandle is NULL pointer.
+ * @retval kStatus_USB_Busy There is no idle transfer.
+ * @retval kStatus_USB_Error Pipe is not initialized.
+ * Or, send transfer fail. See the USB_HostRecv.
+ */
+extern usb_status_t USB_HostPhdcRecv(usb_host_class_handle classHandle,
+ uint8_t qos,
+ uint8_t *buffer,
+ uint32_t bufferLength,
+ transfer_callback_t callbackFn,
+ void *callbackParam);
+
+/*!
+ * @brief Sends data.
+ *
+ * This function implements the PHDC sending data.
+ *
+ * @param classHandle The class handle.
+ * @param buffer The buffer pointer.
+ * @param bufferLength The buffer length.
+ * @param callbackFn This callback is called after this function completes.
+ * @param callbackParam The first parameter in the callback function.
+ *
+ * @retval kStatus_USB_Success Send request successfully.
+ * @retval kStatus_USB_InvalidHandle The classHandle is NULL pointer.
+ * @retval kStatus_USB_Busy There is no idle transfer.
+ * @retval kStatus_USB_Error Pipe is not initialized.
+ * Or, send transfer fail. See the USB_HostSend.
+ */
+extern usb_status_t USB_HostPhdcSend(usb_host_class_handle classHandle,
+ uint8_t *buffer,
+ uint32_t bufferLength,
+ transfer_callback_t callbackFn,
+ void *callbackParam);
+
+/*!
+ * @brief PHDC sends the control request.
+ *
+ * @param classHandle The class handle.
+ * @param request Setup packet request.
+ * @param callbackFn This callback is called after this function completes.
+ * @param callbackParam The first parameter in the callback function.
+ *
+ * @retval kStatus_USB_Success Send request successfully.
+ * @retval kStatus_USB_InvalidHandle The classHandle is NULL pointer.
+ * @retval kStatus_USB_Busy There is no idle transfer.
+ * @retval kStatus_USB_Error Pipe is not initialized.
+ * Or, send transfer fail. See the USB_HostSend.
+ */
+extern usb_status_t USB_HostPhdcSendControlRequest(usb_host_class_handle classHandle,
+ uint8_t request,
+ transfer_callback_t callbackFn,
+ void *callbackParam);
+
+/*!
+ * @brief PHDC set and clear feature endpoint halt request.
+ *
+ * @param classHandle The class handle.
+ * @param request Setup packet request.
+ * @param param Request parameter
+ * @param callbackFn This callback is called after this function completes.
+ * @param callbackParam The first parameter in the callback function.
+ *
+ * @retval kStatus_USB_Success Send request successfully.
+ * @retval kStatus_USB_InvalidHandle The classHandle is NULL pointer.
+ * @retval kStatus_USB_Busy There is no idle transfer.
+ * @retval kStatus_USB_Error Pipe is not initialized.
+ * Or, send transfer fail. See the USB_HostSend.
+ */
+extern usb_status_t USB_HostPhdcSetClearFeatureEndpointHalt(usb_host_class_handle classHandle,
+ uint8_t request,
+ void *param,
+ transfer_callback_t callbackFn,
+ void *callbackParam);
+
+/*!
+ * @brief USB_HostPhdcGetEndpointInformation.
+ * This function returns the PHDC endpoint information structure, which contains an endpoint
+ * descriptor and an endpoint extended descriptor.
+ *
+ * @param classHandle The class handle.
+ * @param pipeType Pipe type.
+ * @param direction Pipe direction.
+ *
+ * @retval endpointReturn All input parameters are valid.
+ * @retval NULL One or more input parameters are invalid.
+ */
+usb_host_ep_t *USB_HostPhdcGetEndpointInformation(usb_host_class_handle classHandle,
+ uint8_t pipeType,
+ uint8_t direction);
+
+/*! @}*/
+
+#ifdef __cplusplus
+}
+#endif
+
+/*! @}*/
+
+#endif /* _USB_HOST_PHDC_H_ */
diff --git a/usb_1.1.0/host/class/usb_host_printer.c b/usb_1.1.0/host/class/usb_host_printer.c
new file mode 100644
index 0000000..5a10038
--- /dev/null
+++ b/usb_1.1.0/host/class/usb_host_printer.c
@@ -0,0 +1,775 @@
+/*
+ * Copyright (c) 2016, Freescale Semiconductor, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * o Redistributions of source code must retain the above copyright notice, this list
+ * of conditions and the following disclaimer.
+ *
+ * o Redistributions in binary form must reproduce the above copyright notice, this
+ * list of conditions and the following disclaimer in the documentation and/or
+ * other materials provided with the distribution.
+ *
+ * o Neither the name of Freescale Semiconductor, Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "usb_host_config.h"
+#if ((defined USB_HOST_CONFIG_PRINTER) && (USB_HOST_CONFIG_PRINTER))
+#include "usb_host.h"
+#include "usb_host_printer.h"
+
+/*******************************************************************************
+ * API
+ ******************************************************************************/
+
+/*!
+ * @brief printer in pipe transfer callback.
+ *
+ * @param param callback parameter.
+ * @param transfer callback transfer.
+ * @param status transfer status.
+ */
+static void USB_HostPrinterInPipeCallback(void *param, usb_host_transfer_t *transfer, usb_status_t status);
+
+/*!
+ * @brief printer out pipe transfer callback.
+ *
+ * @param param callback parameter.
+ * @param transfer callback transfer.
+ * @param status transfer status.
+ */
+static void USB_HostPrinterOutPipeCallback(void *param, usb_host_transfer_t *transfer, usb_status_t status);
+
+/*!
+ * @brief printer control pipe transfer callback.
+ *
+ * @param param callback parameter.
+ * @param transfer callback transfer.
+ * @param status transfer status.
+ */
+static void USB_HostPrinterControlPipeCallback(void *param, usb_host_transfer_t *transfer, usb_status_t status);
+
+/*!
+ * @brief printer open interface. It is called when set interface request success or open alternate setting 0 interface.
+ *
+ * @param printerInstance printer instance pointer.
+ *
+ * @return kStatus_USB_Success or error codes.
+ */
+static usb_status_t USB_HostPrinterOpenInterface(usb_host_printer_instance_t *printerInstance);
+
+/*!
+ * @brief printer set interface callback, open pipes.
+ *
+ * @param param callback parameter.
+ * @param transfer callback transfer.
+ * @param status transfer status.
+ */
+static void USB_HostPrinterSetInterfaceCallback(void *param, usb_host_transfer_t *transfer, usb_status_t status);
+
+/*!
+ * @brief printer send control transfer common code.
+ *
+ * @param classHandle the class handle.
+ * @param requestType setup packet request type.
+ * @param request setup packet request value.
+ * @param wvalue setup packet wValue.
+ * @param windex setup packet wIndex.
+ * @param wlength setup packet wlength value.
+ * @param data data buffer pointer
+ * @param callbackFn this callback is called after this function completes.
+ * @param callbackParam the first parameter in the callback function.
+ *
+ * @return An error code or kStatus_USB_Success.
+ */
+static usb_status_t USB_HostPrinterControl(usb_host_printer_instance_t *printerInstance,
+ uint8_t requestType,
+ uint8_t request,
+ uint16_t wvalue,
+ uint16_t windex,
+ uint16_t wlength,
+ uint8_t *data,
+ transfer_callback_t callbackFn,
+ void *callbackParam);
+
+/*******************************************************************************
+ * Definitions
+ ******************************************************************************/
+/*******************************************************************************
+ * Prototypes
+ ******************************************************************************/
+/*******************************************************************************
+ * Variables
+ ******************************************************************************/
+/*******************************************************************************
+ * Code
+ ******************************************************************************/
+
+#if ((defined USB_HOST_CONFIG_CLASS_AUTO_CLEAR_STALL) && USB_HOST_CONFIG_CLASS_AUTO_CLEAR_STALL)
+static void USB_HostPrinterClearInHaltCallback(void *param, usb_host_transfer_t *transfer, usb_status_t status)
+{
+ usb_host_printer_instance_t *printerInstance = (usb_host_printer_instance_t *)param;
+
+ if (printerInstance->inCallbackFn != NULL)
+ {
+ /* callback to application */
+ printerInstance->inCallbackFn(printerInstance->outCallbackParam, printerInstance->stallDataBuffer,
+ printerInstance->stallDataLength, kStatus_USB_TransferStall);
+ }
+ USB_HostFreeTransfer(printerInstance->hostHandle, transfer);
+}
+
+static void USB_HostPrinterClearOutHaltCallback(void *param, usb_host_transfer_t *transfer, usb_status_t status)
+{
+ usb_host_printer_instance_t *printerInstance = (usb_host_printer_instance_t *)param;
+
+ if (printerInstance->outCallbackFn != NULL)
+ {
+ /* callback to application */
+ printerInstance->outCallbackFn(printerInstance->outCallbackParam, printerInstance->stallDataBuffer,
+ printerInstance->stallDataLength, kStatus_USB_TransferStall);
+ }
+ USB_HostFreeTransfer(printerInstance->hostHandle, transfer);
+}
+
+static void USB_HostPrinterClearHalt(usb_host_printer_instance_t *printerInstance,
+ usb_host_transfer_t *stallTransfer,
+ host_inner_transfer_callback_t callbackFn,
+ uint8_t endpoint)
+{
+ usb_status_t status;
+ usb_host_transfer_t *transfer;
+
+ /* malloc one transfer */
+ status = USB_HostMallocTransfer(printerInstance->hostHandle, &transfer);
+ if (status != kStatus_USB_Success)
+ {
+#ifdef HOST_ECHO
+ usb_echo("allocate transfer error\r\n");
+#endif
+ return status;
+ }
+ printerInstance->stallDataBuffer = stallTransfer->transferBuffer;
+ printerInstance->stallDataLength = stallTransfer->transferSofar;
+ /* save the application callback function */
+ printerInstance->controlCallbackFn = NULL;
+ printerInstance->controlCallbackParam = NULL;
+ /* initialize transfer */
+ transfer->callbackFn = callbackFn;
+ transfer->callbackParam = printerInstance;
+ transfer->transferBuffer = NULL;
+ transfer->transferLength = 0;
+ transfer->setupPacket.bRequest = USB_REQUEST_STANDARD_CLEAR_FEATURE;
+ transfer->setupPacket.bmRequestType = USB_REQUEST_TYPE_RECIPIENT_ENDPOINT;
+ transfer->setupPacket.wValue = USB_SHORT_TO_LITTLE_ENDIAN(USB_REQUEST_STANDARD_FEATURE_SELECTOR_ENDPOINT_HALT);
+ transfer->setupPacket.wIndex = USB_SHORT_TO_LITTLE_ENDIAN(endpoint);
+ transfer->setupPacket.wLength = 0;
+ status = USB_HostSendSetup(printerInstance->hostHandle, printerInstance->controlPipe, transfer);
+
+ if (status != kStatus_USB_Success)
+ {
+ USB_HostFreeTransfer(printerInstance->hostHandle, transfer);
+ }
+ printerInstance->controlTransfer = transfer;
+
+ return status;
+}
+#endif
+
+static void USB_HostPrinterInPipeCallback(void *param, usb_host_transfer_t *transfer, usb_status_t status)
+{
+ usb_host_printer_instance_t *printerInstance = (usb_host_printer_instance_t *)param;
+
+#if ((defined USB_HOST_CONFIG_CLASS_AUTO_CLEAR_STALL) && USB_HOST_CONFIG_CLASS_AUTO_CLEAR_STALL)
+ if (status == kStatus_USB_TransferStall)
+ {
+ if (USB_HostPrinterClearHalt(
+ printerInstance, transfer, USB_HostPrinterClearInHaltCallback,
+ (USB_REQUEST_TYPE_DIR_IN | ((usb_host_pipe_t *)printerInstance->inPipe)->endpointAddress)) ==
+ kStatus_USB_Success)
+ {
+ USB_HostFreeTransfer(printerInstance->hostHandle, transfer);
+ return;
+ }
+ }
+#endif
+
+ if (printerInstance->inCallbackFn != NULL)
+ {
+ /* callback to application */
+ printerInstance->inCallbackFn(printerInstance->inCallbackParam, transfer->transferBuffer,
+ transfer->transferSofar, status);
+ }
+ USB_HostFreeTransfer(printerInstance->hostHandle, transfer);
+}
+
+static void USB_HostPrinterOutPipeCallback(void *param, usb_host_transfer_t *transfer, usb_status_t status)
+{
+ usb_host_printer_instance_t *printerInstance = (usb_host_printer_instance_t *)param;
+
+#if ((defined USB_HOST_CONFIG_CLASS_AUTO_CLEAR_STALL) && USB_HOST_CONFIG_CLASS_AUTO_CLEAR_STALL)
+ if (status == kStatus_USB_TransferStall)
+ {
+ if (USB_HostPrinterClearHalt(
+ printerInstance, transfer, USB_HostPrinterClearOutHaltCallback,
+ (USB_REQUEST_TYPE_DIR_OUT | ((usb_host_pipe_t *)printerInstance->outPipe)->endpointAddress)) ==
+ kStatus_USB_Success)
+ {
+ USB_HostFreeTransfer(printerInstance->hostHandle, transfer);
+ return;
+ }
+ }
+#endif
+ if (printerInstance->outCallbackFn != NULL)
+ {
+ /* callback to application */
+ printerInstance->outCallbackFn(printerInstance->outCallbackParam, transfer->transferBuffer,
+ transfer->transferSofar, status);
+ }
+ USB_HostFreeTransfer(printerInstance->hostHandle, transfer);
+}
+
+static void USB_HostPrinterControlPipeCallback(void *param, usb_host_transfer_t *transfer, usb_status_t status)
+{
+ usb_host_printer_instance_t *printerInstance = (usb_host_printer_instance_t *)param;
+
+ printerInstance->controlTransfer = NULL;
+ if (printerInstance->controlCallbackFn != NULL)
+ {
+ /* callback to application */
+ printerInstance->controlCallbackFn(printerInstance->controlCallbackParam, transfer->transferBuffer,
+ transfer->transferSofar, status);
+ }
+ USB_HostFreeTransfer(printerInstance->hostHandle, transfer);
+}
+
+static usb_status_t USB_HostPrinterOpenInterface(usb_host_printer_instance_t *printerInstance)
+{
+ usb_status_t status;
+ uint8_t epIndex = 0;
+ usb_host_pipe_init_t pipeInit;
+ usb_descriptor_endpoint_t *epDesc = NULL;
+ usb_host_interface_t *interfacePointer;
+
+ if (printerInstance->inPipe != NULL)
+ {
+ status = USB_HostClosePipe(printerInstance->hostHandle, printerInstance->inPipe);
+
+ if (status != kStatus_USB_Success)
+ {
+#ifdef HOST_ECHO
+ usb_echo("error when close pipe\r\n");
+#endif
+ }
+ printerInstance->inPipe = NULL;
+ }
+ if (printerInstance->outPipe != NULL) /* close interrupt out pipe if it is open */
+ {
+ status = USB_HostClosePipe(printerInstance->hostHandle, printerInstance->outPipe);
+
+ if (status != kStatus_USB_Success)
+ {
+#ifdef HOST_ECHO
+ usb_echo("error when close pipe\r\n");
+#endif
+ }
+ printerInstance->outPipe = NULL;
+ }
+
+ /* open interface pipes */
+ interfacePointer = (usb_host_interface_t *)printerInstance->interfaceHandle;
+ for (epIndex = 0; epIndex < interfacePointer->epCount; ++epIndex)
+ {
+ epDesc = interfacePointer->epList[epIndex].epDesc;
+ if (((epDesc->bEndpointAddress & USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_MASK) ==
+ USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_IN) &&
+ ((epDesc->bmAttributes & USB_DESCRIPTOR_ENDPOINT_ATTRIBUTE_TYPE_MASK) == USB_ENDPOINT_BULK))
+ {
+ pipeInit.devInstance = printerInstance->deviceHandle;
+ pipeInit.pipeType = USB_ENDPOINT_BULK;
+ pipeInit.direction = USB_IN;
+ pipeInit.endpointAddress = (epDesc->bEndpointAddress & USB_DESCRIPTOR_ENDPOINT_ADDRESS_NUMBER_MASK);
+ pipeInit.interval = epDesc->bInterval;
+ pipeInit.maxPacketSize = (uint16_t)(USB_SHORT_FROM_LITTLE_ENDIAN_ADDRESS(epDesc->wMaxPacketSize) &
+ USB_DESCRIPTOR_ENDPOINT_MAXPACKETSIZE_SIZE_MASK);
+ pipeInit.numberPerUframe = (USB_SHORT_FROM_LITTLE_ENDIAN_ADDRESS(epDesc->wMaxPacketSize) &
+ USB_DESCRIPTOR_ENDPOINT_MAXPACKETSIZE_MULT_TRANSACTIONS_MASK);
+ pipeInit.nakCount = USB_HOST_CONFIG_MAX_NAK;
+
+ printerInstance->inPacketSize = pipeInit.maxPacketSize;
+
+ status = USB_HostOpenPipe(printerInstance->hostHandle, &printerInstance->inPipe, &pipeInit);
+ if (status != kStatus_USB_Success)
+ {
+#ifdef HOST_ECHO
+ usb_echo("USB_HostPrinterSetInterface fail to open pipe\r\n");
+#endif
+ return kStatus_USB_Error;
+ }
+ }
+ else if (((epDesc->bEndpointAddress & USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_MASK) ==
+ USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_OUT) &&
+ ((epDesc->bmAttributes & USB_DESCRIPTOR_ENDPOINT_ATTRIBUTE_TYPE_MASK) == USB_ENDPOINT_BULK))
+ {
+ pipeInit.devInstance = printerInstance->deviceHandle;
+ pipeInit.pipeType = USB_ENDPOINT_BULK;
+ pipeInit.direction = USB_OUT;
+ pipeInit.endpointAddress = (epDesc->bEndpointAddress & USB_DESCRIPTOR_ENDPOINT_ADDRESS_NUMBER_MASK);
+ pipeInit.interval = epDesc->bInterval;
+ pipeInit.maxPacketSize = (uint16_t)(USB_SHORT_FROM_LITTLE_ENDIAN_ADDRESS(epDesc->wMaxPacketSize) &
+ USB_DESCRIPTOR_ENDPOINT_MAXPACKETSIZE_SIZE_MASK);
+ pipeInit.numberPerUframe = (USB_SHORT_FROM_LITTLE_ENDIAN_ADDRESS(epDesc->wMaxPacketSize) &
+ USB_DESCRIPTOR_ENDPOINT_MAXPACKETSIZE_MULT_TRANSACTIONS_MASK);
+ pipeInit.nakCount = USB_HOST_CONFIG_MAX_NAK;
+
+ printerInstance->outPacketSize = pipeInit.maxPacketSize;
+
+ status = USB_HostOpenPipe(printerInstance->hostHandle, &printerInstance->outPipe, &pipeInit);
+ if (status != kStatus_USB_Success)
+ {
+#ifdef HOST_ECHO
+ usb_echo("USB_HostPrinterSetInterface fail to open pipe\r\n");
+#endif
+ return kStatus_USB_Error;
+ }
+ }
+ else
+ {
+ }
+ }
+
+ return kStatus_USB_Success;
+}
+
+static void USB_HostPrinterSetInterfaceCallback(void *param, usb_host_transfer_t *transfer, usb_status_t status)
+{
+ usb_host_printer_instance_t *printerInstance = (usb_host_printer_instance_t *)param;
+
+ printerInstance->controlTransfer = NULL;
+ if (status == kStatus_USB_Success)
+ {
+ status = USB_HostPrinterOpenInterface(printerInstance); /* printer open interface */
+ }
+
+ if (printerInstance->controlCallbackFn != NULL)
+ {
+ /* callback to application */
+ printerInstance->controlCallbackFn(printerInstance->controlCallbackParam, NULL, 0, status);
+ }
+ USB_HostFreeTransfer(printerInstance->hostHandle, transfer);
+}
+
+usb_status_t USB_HostPrinterInit(usb_device_handle deviceHandle, usb_host_class_handle *classHandle)
+{
+ uint32_t infoValue;
+ /* malloc printer class instance */
+ usb_host_printer_instance_t *printerInstance =
+ (usb_host_printer_instance_t *)USB_OsaMemoryAllocate(sizeof(usb_host_printer_instance_t));
+
+ if (printerInstance == NULL)
+ {
+ return kStatus_USB_AllocFail;
+ }
+
+ /* initialize printer instance */
+ printerInstance->deviceHandle = deviceHandle;
+ printerInstance->interfaceHandle = NULL;
+ USB_HostHelperGetPeripheralInformation(deviceHandle, kUSB_HostGetHostHandle, &infoValue);
+ printerInstance->hostHandle = (usb_host_handle)infoValue;
+ USB_HostHelperGetPeripheralInformation(deviceHandle, kUSB_HostGetDeviceControlPipe, &infoValue);
+ printerInstance->controlPipe = (usb_host_pipe_handle)infoValue;
+
+ *classHandle = printerInstance;
+ return kStatus_USB_Success;
+}
+
+usb_status_t USB_HostPrinterSetInterface(usb_host_class_handle classHandle,
+ usb_host_interface_handle interfaceHandle,
+ uint8_t alternateSetting,
+ transfer_callback_t callbackFn,
+ void *callbackParam)
+{
+ usb_status_t status;
+ usb_host_printer_instance_t *printerInstance = (usb_host_printer_instance_t *)classHandle;
+ usb_host_transfer_t *transfer;
+
+ if (classHandle == NULL)
+ {
+ return kStatus_USB_InvalidParameter;
+ }
+
+ /* notify host driver the interface is open */
+ status = USB_HostOpenDeviceInterface(printerInstance->deviceHandle, interfaceHandle);
+ if (status != kStatus_USB_Success)
+ {
+ return status;
+ }
+ printerInstance->interfaceHandle = interfaceHandle;
+
+ /* cancel transfers */
+ if (printerInstance->inPipe != NULL)
+ {
+ status = USB_HostCancelTransfer(printerInstance->hostHandle, printerInstance->inPipe, NULL);
+
+ if (status != kStatus_USB_Success)
+ {
+#ifdef HOST_ECHO
+ usb_echo("error when cancel pipe\r\n");
+#endif
+ }
+ }
+ if (printerInstance->outPipe != NULL)
+ {
+ status = USB_HostCancelTransfer(printerInstance->hostHandle, printerInstance->outPipe, NULL);
+
+ if (status != kStatus_USB_Success)
+ {
+#ifdef HOST_ECHO
+ usb_echo("error when cancel pipe\r\n");
+#endif
+ }
+ }
+
+ if (alternateSetting == 0) /* open interface directly */
+ {
+ if (callbackFn != NULL)
+ {
+ status = USB_HostPrinterOpenInterface(printerInstance);
+ callbackFn(callbackParam, NULL, 0, status);
+ }
+ }
+ else /* send setup transfer */
+ {
+ /* malloc one transfer */
+ if (USB_HostMallocTransfer(printerInstance->hostHandle, &transfer) != kStatus_USB_Success)
+ {
+#ifdef HOST_ECHO
+ usb_echo("error to get transfer\r\n");
+#endif
+ return kStatus_USB_Error;
+ }
+
+ /* save the application callback function */
+ printerInstance->controlCallbackFn = callbackFn;
+ printerInstance->controlCallbackParam = callbackParam;
+ /* initialize transfer */
+ transfer->callbackFn = USB_HostPrinterSetInterfaceCallback;
+ transfer->callbackParam = printerInstance;
+ transfer->setupPacket.bRequest = USB_REQUEST_STANDARD_SET_INTERFACE;
+ transfer->setupPacket.bmRequestType = USB_REQUEST_TYPE_RECIPIENT_INTERFACE;
+ transfer->setupPacket.wIndex = USB_SHORT_TO_LITTLE_ENDIAN(
+ ((usb_host_interface_t *)printerInstance->interfaceHandle)->interfaceDesc->bInterfaceNumber);
+ transfer->setupPacket.wValue = USB_SHORT_TO_LITTLE_ENDIAN(alternateSetting);
+ transfer->setupPacket.wLength = 0;
+ transfer->transferBuffer = NULL;
+ transfer->transferLength = 0;
+ status = USB_HostSendSetup(printerInstance->hostHandle, printerInstance->controlPipe, transfer);
+
+ if (status == kStatus_USB_Success)
+ {
+ printerInstance->controlTransfer = transfer;
+ }
+ else
+ {
+ USB_HostFreeTransfer(printerInstance->hostHandle, transfer);
+ }
+ }
+
+ return status;
+}
+
+usb_status_t USB_HostPrinterDeinit(usb_device_handle deviceHandle, usb_host_class_handle classHandle)
+{
+ usb_status_t status;
+ usb_host_printer_instance_t *printerInstance = (usb_host_printer_instance_t *)classHandle;
+
+ if (deviceHandle == NULL)
+ {
+ return kStatus_USB_InvalidHandle;
+ }
+
+ if (classHandle != NULL) /* class instance has initialized */
+ {
+ if (printerInstance->inPipe != NULL)
+ {
+ status =
+ USB_HostCancelTransfer(printerInstance->hostHandle, printerInstance->inPipe, NULL); /* cancel pipe */
+ status = USB_HostClosePipe(printerInstance->hostHandle, printerInstance->inPipe); /* close pipe */
+
+ if (status != kStatus_USB_Success)
+ {
+#ifdef HOST_ECHO
+ usb_echo("error when close pipe\r\n");
+#endif
+ }
+ printerInstance->inPipe = NULL;
+ }
+ if (printerInstance->outPipe != NULL)
+ {
+ status =
+ USB_HostCancelTransfer(printerInstance->hostHandle, printerInstance->outPipe, NULL); /* cancel pipe */
+ status = USB_HostClosePipe(printerInstance->hostHandle, printerInstance->outPipe); /* close pipe */
+
+ if (status != kStatus_USB_Success)
+ {
+#ifdef HOST_ECHO
+ usb_echo("error when close pipe\r\n");
+#endif
+ }
+ printerInstance->outPipe = NULL;
+ }
+ if ((printerInstance->controlPipe != NULL) &&
+ (printerInstance->controlTransfer !=
+ NULL)) /* cancel control transfer if there is on-going control transfer */
+ {
+ status = USB_HostCancelTransfer(printerInstance->hostHandle, printerInstance->controlPipe,
+ printerInstance->controlTransfer);
+ }
+ USB_HostCloseDeviceInterface(deviceHandle,
+ printerInstance->interfaceHandle); /* notify host driver the interface is closed */
+ USB_OsaMemoryFree(printerInstance);
+ }
+ else
+ {
+ USB_HostCloseDeviceInterface(deviceHandle, NULL);
+ }
+
+ return kStatus_USB_Success;
+}
+
+usb_status_t USB_HostPrinterRecv(usb_host_class_handle classHandle,
+ uint8_t *buffer,
+ uint32_t bufferLength,
+ transfer_callback_t callbackFn,
+ void *callbackParam)
+{
+ usb_host_printer_instance_t *printerInstance = (usb_host_printer_instance_t *)classHandle;
+ usb_host_transfer_t *transfer;
+
+ if (classHandle == NULL)
+ {
+ return kStatus_USB_InvalidHandle;
+ }
+
+ if (printerInstance->inPipe == NULL)
+ {
+ return kStatus_USB_Error;
+ }
+
+ /* malloc one transfer */
+ if (USB_HostMallocTransfer(printerInstance->hostHandle, &transfer) != kStatus_USB_Success)
+ {
+#ifdef HOST_ECHO
+ usb_echo("error to get transfer\r\n");
+#endif
+ return kStatus_USB_Busy;
+ }
+ /* save the application callback function */
+ printerInstance->inCallbackFn = callbackFn;
+ printerInstance->inCallbackParam = callbackParam;
+ /* initialize transfer */
+ transfer->transferBuffer = buffer;
+ transfer->transferLength = bufferLength;
+ transfer->callbackFn = USB_HostPrinterInPipeCallback;
+ transfer->callbackParam = printerInstance;
+
+ /* call host driver api */
+ if (USB_HostRecv(printerInstance->hostHandle, printerInstance->inPipe, transfer) != kStatus_USB_Success)
+ {
+#ifdef HOST_ECHO
+ usb_echo("fail to USB_HostRecv\r\n");
+#endif
+ USB_HostFreeTransfer(printerInstance->hostHandle, transfer);
+ return kStatus_USB_Error;
+ }
+
+ return kStatus_USB_Success;
+}
+
+uint16_t USB_HostPrinterGetPacketsize(usb_host_class_handle classHandle, uint8_t pipeType, uint8_t direction)
+{
+ usb_host_printer_instance_t *phdcInstance = (usb_host_printer_instance_t *)classHandle;
+ if (classHandle == NULL)
+ {
+ return 0;
+ }
+
+ if (pipeType == USB_ENDPOINT_INTERRUPT)
+ {
+ if (direction == USB_IN)
+ {
+ return phdcInstance->inPacketSize;
+ }
+ else
+ {
+ return phdcInstance->outPacketSize;
+ }
+ }
+
+ return 0;
+}
+
+usb_status_t USB_HostPrinterSend(usb_host_class_handle classHandle,
+ uint8_t *buffer,
+ uint32_t bufferLength,
+ transfer_callback_t callbackFn,
+ void *callbackParam)
+{
+ usb_host_printer_instance_t *printerInstance = (usb_host_printer_instance_t *)classHandle;
+ usb_host_transfer_t *transfer;
+
+ if (classHandle == NULL)
+ {
+ return kStatus_USB_InvalidHandle;
+ }
+
+ if (printerInstance->outPipe == NULL)
+ {
+ return kStatus_USB_Error;
+ }
+
+ /* malloc one transfer */
+ if (USB_HostMallocTransfer(printerInstance->hostHandle, &transfer) != kStatus_USB_Success)
+ {
+#ifdef HOST_ECHO
+ usb_echo("error to get transfer\r\n");
+#endif
+ return kStatus_USB_Error;
+ }
+ /* save the application callback function */
+ printerInstance->outCallbackFn = callbackFn;
+ printerInstance->outCallbackParam = callbackParam;
+ /* initialize transfer */
+ transfer->transferBuffer = buffer;
+ transfer->transferLength = bufferLength;
+ transfer->callbackFn = USB_HostPrinterOutPipeCallback;
+ transfer->callbackParam = printerInstance;
+
+ /* call host driver api */
+ if (USB_HostSend(printerInstance->hostHandle, printerInstance->outPipe, transfer) != kStatus_USB_Success)
+ {
+#ifdef HOST_ECHO
+ usb_echo("fail to USB_HostSend\r\n");
+#endif
+ USB_HostFreeTransfer(printerInstance->hostHandle, transfer);
+ return kStatus_USB_Error;
+ }
+
+ return kStatus_USB_Success;
+}
+
+static usb_status_t USB_HostPrinterControl(usb_host_printer_instance_t *printerInstance,
+ uint8_t requestType,
+ uint8_t request,
+ uint16_t wvalue,
+ uint16_t windex,
+ uint16_t wlength,
+ uint8_t *data,
+ transfer_callback_t callbackFn,
+ void *callbackParam)
+{
+ usb_host_transfer_t *transfer;
+
+ if (printerInstance == NULL)
+ {
+ return kStatus_USB_InvalidHandle;
+ }
+
+ if (USB_HostMallocTransfer(printerInstance->hostHandle, &transfer) != kStatus_USB_Success)
+ {
+#ifdef HOST_ECHO
+ usb_echo("error to get transfer\r\n");
+#endif
+ return kStatus_USB_Busy;
+ }
+ /* save the application callback function */
+ printerInstance->controlCallbackFn = callbackFn;
+ printerInstance->controlCallbackParam = callbackParam;
+ /* initialize transfer */
+ transfer->transferBuffer = data;
+ transfer->transferLength = wlength;
+ transfer->callbackFn = USB_HostPrinterControlPipeCallback;
+ transfer->callbackParam = printerInstance;
+ transfer->setupPacket.bmRequestType = requestType;
+ transfer->setupPacket.bRequest = request;
+ transfer->setupPacket.wValue = wvalue;
+ transfer->setupPacket.wIndex = windex;
+ transfer->setupPacket.wLength = USB_SHORT_TO_LITTLE_ENDIAN(wlength);
+
+ /* call host driver api */
+ if (USB_HostSendSetup(printerInstance->hostHandle, printerInstance->controlPipe, transfer) != kStatus_USB_Success)
+ {
+#ifdef HOST_ECHO
+ usb_echo("fail for USB_HostSendSetup\r\n");
+#endif
+ USB_HostFreeTransfer(printerInstance->hostHandle, transfer);
+ return kStatus_USB_Error;
+ }
+ printerInstance->controlTransfer = transfer;
+
+ return kStatus_USB_Success;
+}
+
+usb_status_t USB_HostPrinterGetDeviceId(usb_host_class_handle classHandle,
+ uint8_t interfaceIndex,
+ uint8_t alternateSetting,
+ uint8_t *buffer,
+ uint32_t length,
+ transfer_callback_t callbackFn,
+ void *callbackParam)
+{
+ usb_host_printer_instance_t *printerInstance = (usb_host_printer_instance_t *)classHandle;
+ uint32_t infoValue;
+
+ USB_HostHelperGetPeripheralInformation(printerInstance->deviceHandle, kUSB_HostGetDeviceConfigIndex, &infoValue);
+
+ return USB_HostPrinterControl(
+ printerInstance, USB_REQUEST_TYPE_DIR_IN | USB_REQUEST_TYPE_TYPE_CLASS | USB_REQUEST_TYPE_RECIPIENT_INTERFACE,
+ USB_HOST_PRINTER_GET_DEVICE_ID, (uint16_t)infoValue,
+ (uint16_t)((uint16_t)((uint16_t)interfaceIndex << 8U) | alternateSetting), length, buffer, callbackFn,
+ callbackParam);
+}
+
+usb_status_t USB_HostPrinterGetPortStatus(usb_host_class_handle classHandle,
+ uint8_t *portStatus,
+ transfer_callback_t callbackFn,
+ void *callbackParam)
+{
+ usb_host_printer_instance_t *printerInstance = (usb_host_printer_instance_t *)classHandle;
+
+ return USB_HostPrinterControl(
+ printerInstance, USB_REQUEST_TYPE_DIR_IN | USB_REQUEST_TYPE_TYPE_CLASS | USB_REQUEST_TYPE_RECIPIENT_INTERFACE,
+ USB_HOST_PRINTER_GET_PORT_STATUS, 0,
+ (uint16_t)(((usb_host_interface_t *)printerInstance->interfaceHandle)->interfaceDesc->bInterfaceNumber), 1,
+ portStatus, callbackFn, callbackParam);
+}
+
+usb_status_t USB_HostPrinterSoftReset(usb_host_class_handle classHandle,
+ transfer_callback_t callbackFn,
+ void *callbackParam)
+{
+ usb_host_printer_instance_t *printerInstance = (usb_host_printer_instance_t *)classHandle;
+
+ return USB_HostPrinterControl(
+ printerInstance, USB_REQUEST_TYPE_TYPE_CLASS | USB_REQUEST_TYPE_RECIPIENT_INTERFACE,
+ USB_HOST_PRINTER_SOFT_RESET, 0,
+ (uint16_t)(((usb_host_interface_t *)printerInstance->interfaceHandle)->interfaceDesc->bInterfaceNumber), 0,
+ NULL, callbackFn, callbackParam);
+}
+
+#endif /* USB_HOST_CONFIG_PRINTER */
diff --git a/usb_1.1.0/host/class/usb_host_printer.h b/usb_1.1.0/host/class/usb_host_printer.h
new file mode 100644
index 0000000..371ea80
--- /dev/null
+++ b/usb_1.1.0/host/class/usb_host_printer.h
@@ -0,0 +1,301 @@
+/*
+ * Copyright (c) 2016, Freescale Semiconductor, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * o Redistributions of source code must retain the above copyright notice, this list
+ * of conditions and the following disclaimer.
+ *
+ * o Redistributions in binary form must reproduce the above copyright notice, this
+ * list of conditions and the following disclaimer in the documentation and/or
+ * other materials provided with the distribution.
+ *
+ * o Neither the name of Freescale Semiconductor, Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __USB_HOST_PRINTER_H__
+#define __USB_HOST_PRINTER_H__
+
+/*******************************************************************************
+ * Definitions
+ ******************************************************************************/
+
+/*!
+ * @addtogroup usb_host_printer_drv
+ * @{
+ */
+
+/*! @brief Printer class code */
+#define USB_HOST_PRINTER_CLASS_CODE (7U)
+/*! @brief Printer sub-class code */
+#define USB_HOST_PRINTER_SUBCLASS_CODE (1U)
+/*! @brief Printer class protocol code (Unidirectional interface) */
+#define USB_HOST_PRINTER_PROTOCOL_UNIDIRECTION (1U)
+/*! @brief Printer class protocol code (Bi-directional interface) */
+#define USB_HOST_PRINTER_PROTOCOL_BIDIRECTION (2U)
+/*! @brief Printer class protocol code (IEEE® 1284.4 compatible bi-directional interface) */
+#define USB_HOST_PRINTER_PROTOCOL_IEEE1284 (3U)
+
+/*! @brief Printer class-specific request (GET_DEVICE_ID) */
+#define USB_HOST_PRINTER_GET_DEVICE_ID (0)
+/*! @brief Printer class-specific request (GET_PORT_STATUS) */
+#define USB_HOST_PRINTER_GET_PORT_STATUS (1)
+/*! @brief Printer class-specific request (SOFT_RESET) */
+#define USB_HOST_PRINTER_SOFT_RESET (2)
+
+/*! @brief Paper empty bit mask for GET_PORT_STATUS */
+#define USB_HOST_PRINTER_PORT_STATUS_PAPER_EMPTRY_MASK (0x20U)
+/*! @brief Select bit mask for GET_PORT_STATUS */
+#define USB_HOST_PRINTER_PORT_STATUS_SELECT_MASK (0x10U)
+/*! @brief Error bit mask for GET_PORT_STATUS */
+#define USB_HOST_PRINTER_PORT_STATUS_NOT_ERROR_MASK (0x08U)
+
+/*! @brief Printer instance structure and printer usb_host_class_handle pointer to this structure */
+typedef struct _usb_host_printer_instance
+{
+ usb_host_handle hostHandle; /*!< This instance's related host handle*/
+ usb_device_handle deviceHandle; /*!< This instance's related device handle*/
+ usb_host_interface_handle interfaceHandle; /*!< This instance's related interface handle*/
+ usb_host_pipe_handle controlPipe; /*!< This instance's related device control pipe*/
+ usb_host_pipe_handle inPipe; /*!< Printer bulk in pipe*/
+ usb_host_pipe_handle outPipe; /*!< Printer bulk out pipe*/
+ transfer_callback_t inCallbackFn; /*!< Printer bulk in transfer callback function pointer*/
+ void *inCallbackParam; /*!< Printer bulk in transfer callback parameter*/
+ transfer_callback_t outCallbackFn; /*!< Printer bulk out transfer callback function pointer*/
+ void *outCallbackParam; /*!< Printer bulk out transfer callback parameter*/
+ transfer_callback_t controlCallbackFn; /*!< Printer control transfer callback function pointer*/
+ void *controlCallbackParam; /*!< Printer control transfer callback parameter*/
+ usb_host_transfer_t *controlTransfer; /*!< Ongoing control transfer*/
+#if ((defined USB_HOST_CONFIG_CLASS_AUTO_CLEAR_STALL) && USB_HOST_CONFIG_CLASS_AUTO_CLEAR_STALL)
+ uint8_t *stallDataBuffer;
+ uint32_t stallDataLength;
+#endif
+
+ uint16_t inPacketSize; /*!< Printer bulk in maximum packet size*/
+ uint16_t outPacketSize; /*!< Printer bulk out maximum packet size*/
+} usb_host_printer_instance_t;
+
+/*******************************************************************************
+ * API
+ ******************************************************************************/
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*!
+ * @name USB host printer class APIs
+ * @{
+ */
+
+/*!
+ * @brief Initializes the printer instance.
+ *
+ * This function allocate the resource for the printer instance.
+ *
+ * @param[in] deviceHandle The device handle.
+ * @param[out] classHandle Return class handle.
+ *
+ * @retval kStatus_USB_Success The device is initialized successfully.
+ * @retval kStatus_USB_AllocFail Allocate memory fail.
+ */
+extern usb_status_t USB_HostPrinterInit(usb_device_handle deviceHandle, usb_host_class_handle *classHandle);
+
+/*!
+ * @brief Sets the interface.
+ *
+ * This function binds the interface with the printer instance.
+ *
+ * @param[in] classHandle The class handle.
+ * @param[in] interfaceHandle The interface handle.
+ * @param[in] alternateSetting The alternate setting value.
+ * @param[in] callbackFn This callback is called after this function completes.
+ * @param[in] callbackParam The first parameter in the callback function.
+ *
+ * @retval kStatus_USB_Success The device is initialized successfully.
+ * @retval kStatus_USB_InvalidHandle The classHandle is NULL pointer.
+ * @retval kStatus_USB_Busy There is no idle transfer.
+ * @retval kStatus_USB_Error Send transfer fail. See the USB_HostSendSetup.
+ * @retval kStatus_USB_Busy Callback return status, there is no idle pipe.
+ * @retval kStatus_USB_TransferStall Callback return status, the transfer is stalled by the device.
+ * @retval kStatus_USB_Error Callback return status, open pipe fail. See the USB_HostOpenPipe.
+ */
+extern usb_status_t USB_HostPrinterSetInterface(usb_host_class_handle classHandle,
+ usb_host_interface_handle interfaceHandle,
+ uint8_t alternateSetting,
+ transfer_callback_t callbackFn,
+ void *callbackParam);
+
+/*!
+ * @brief De-initializes the the printer instance.
+ *
+ * This function frees the resources for the printer instance.
+ *
+ * @param[in] deviceHandle The device handle.
+ * @param[in] classHandle The class handle.
+ *
+ * @retval kStatus_USB_Success The device is de-initialized successfully.
+ */
+extern usb_status_t USB_HostPrinterDeinit(usb_device_handle deviceHandle, usb_host_class_handle classHandle);
+
+/*!
+ * @brief Gets the pipe maximum packet size.
+ *
+ * @param[in] classHandle The class handle.
+ * @param[in] pipeType Its value is USB_ENDPOINT_CONTROL, USB_ENDPOINT_ISOCHRONOUS, USB_ENDPOINT_BULK or
+ * USB_ENDPOINT_INTERRUPT.
+ * See the usb_spec.h
+ * @param[in] direction Pipe direction.
+ *
+ * @retval 0 The classHandle is NULL.
+ * @retval Maximum Packet size.
+ */
+extern uint16_t USB_HostPrinterGetPacketsize(usb_host_class_handle classHandle, uint8_t pipeType, uint8_t direction);
+
+/*!
+ * @brief Receives data.
+ *
+ * This function implements the printer receiving data.
+ *
+ * @param[in] classHandle The class handle.
+ * @param[out] buffer The buffer pointer.
+ * @param[in] bufferLength The buffer length.
+ * @param[in] callbackFn This callback is called after this function completes.
+ * @param[in] callbackParam The first parameter in the callback function.
+ *
+ * @retval kStatus_USB_Success Receive request successfully.
+ * @retval kStatus_USB_InvalidHandle The classHandle is NULL pointer.
+ * @retval kStatus_USB_Busy There is no idle transfer.
+ * @retval kStatus_USB_Error Pipe is not initialized.
+ * Or, send transfer fail. See the USB_HostRecv.
+ */
+extern usb_status_t USB_HostPrinterRecv(usb_host_class_handle classHandle,
+ uint8_t *buffer,
+ uint32_t bufferLength,
+ transfer_callback_t callbackFn,
+ void *callbackParam);
+
+/*!
+ * @brief Sends data.
+ *
+ * This function implements the printer sending data.
+ *
+ * @param[in] classHandle The class handle.
+ * @param[in] buffer The buffer pointer.
+ * @param[in] bufferLength The buffer length.
+ * @param[in] callbackFn This callback is called after this function completes.
+ * @param[in] callbackParam The first parameter in the callback function.
+ *
+ * @retval kStatus_USB_Success Send request successfully.
+ * @retval kStatus_USB_InvalidHandle The classHandle is NULL pointer.
+ * @retval kStatus_USB_Busy There is no idle transfer.
+ * @retval kStatus_USB_Error Pipe is not initialized.
+ * Or, send transfer fail. See the USB_HostSend.
+ */
+extern usb_status_t USB_HostPrinterSend(usb_host_class_handle classHandle,
+ uint8_t *buffer,
+ uint32_t bufferLength,
+ transfer_callback_t callbackFn,
+ void *callbackParam);
+
+/*!
+ * @brief Gets the pipe maximum packet size.
+ *
+ * @param[in] classHandle The class handle.
+ * @param[in] pipeType Its value is USB_ENDPOINT_CONTROL, USB_ENDPOINT_ISOCHRONOUS, USB_ENDPOINT_BULK or
+ * USB_ENDPOINT_INTERRUPT. See the usb_spec.h
+ * @param[in] direction Pipe direction.
+ *
+ * @retval 0 The classHandle is NULL.
+ * @retval Maximum Packet size.
+ */
+extern uint16_t USB_HostPrinterGetPacketsize(usb_host_class_handle classHandle, uint8_t pipeType, uint8_t direction);
+
+/*!
+ * @brief Printer get device ID.
+ *
+ * This function implements the printer class-specific request (GET_DEVICE_ID).
+ *
+ * @param[in] classHandle The class handle.
+ * @param[in] interfaceIndex Interface index.
+ * @param[in] alternateSetting Get the alternateSetting's device ID.
+ * @param[out] buffer The buffer pointer.
+ * @param[in] length The buffer length.
+ * @param[in] callbackFn This callback is called after this function completes.
+ * @param[in] callbackParam The first parameter in the callback function.
+ *
+ * @retval kStatus_USB_Success Request successful.
+ * @retval kStatus_USB_InvalidHandle The classHandle is NULL pointer.
+ * @retval kStatus_USB_Busy There is no idle transfer.
+ * @retval kStatus_USB_Error Send transfer fail. See the USB_HostSendSetup.
+ */
+extern usb_status_t USB_HostPrinterGetDeviceId(usb_host_class_handle classHandle,
+ uint8_t interfaceIndex,
+ uint8_t alternateSetting,
+ uint8_t *buffer,
+ uint32_t length,
+ transfer_callback_t callbackFn,
+ void *callbackParam);
+
+/*!
+ * @brief Printer get port status.
+ *
+ * This function implements the printer class-specific request (GET_PORT_STATUS).
+ *
+ * @param[in] classHandle The class handle.
+ * @param[in] portStatus Port status buffer.
+ * @param[in] callbackFn This callback is called after this function completes.
+ * @param[in] callbackParam The first parameter in the callback function.
+ *
+ * @retval kStatus_USB_Success Request successful.
+ * @retval kStatus_USB_InvalidHandle The classHandle is NULL pointer.
+ * @retval kStatus_USB_Busy There is no idle transfer.
+ * @retval kStatus_USB_Error Send transfer fail. See the USB_HostSendSetup.
+ */
+extern usb_status_t USB_HostPrinterGetPortStatus(usb_host_class_handle classHandle,
+ uint8_t *portStatus,
+ transfer_callback_t callbackFn,
+ void *callbackParam);
+
+/*!
+ * @brief Printer soft reset.
+ *
+ * This function implements the printer class-specific request (SOFT_RESET).
+ *
+ * @param[in] classHandle The class handle.
+ * @param[in] portStatus Port status buffer.
+ * @param[in] callbackFn This callback is called after this function completes.
+ * @param[in] callbackParam The first parameter in the callback function.
+ *
+ * @retval kStatus_USB_Success Request successful.
+ * @retval kStatus_USB_InvalidHandle The classHandle is NULL pointer.
+ * @retval kStatus_USB_Busy There is no idle transfer.
+ * @retval kStatus_USB_Error Send transfer fail. See the USB_HostSendSetup.
+ */
+extern usb_status_t USB_HostPrinterSoftReset(usb_host_class_handle classHandle,
+ transfer_callback_t callbackFn,
+ void *callbackParam);
+/*! @}*/
+
+#ifdef __cplusplus
+}
+#endif
+
+/*! @}*/
+
+#endif /* __USB_HOST_PRINTER_H__ */
diff --git a/usb_1.1.0/host/usb_host.h b/usb_1.1.0/host/usb_host.h
new file mode 100644
index 0000000..6237b21
--- /dev/null
+++ b/usb_1.1.0/host/usb_host.h
@@ -0,0 +1,569 @@
+/*
+ * Copyright (c) 2015, Freescale Semiconductor, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * o Redistributions of source code must retain the above copyright notice, this list
+ * of conditions and the following disclaimer.
+ *
+ * o Redistributions in binary form must reproduce the above copyright notice, this
+ * list of conditions and the following disclaimer in the documentation and/or
+ * other materials provided with the distribution.
+ *
+ * o Neither the name of Freescale Semiconductor, Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _USB_HOST_H_
+#define _USB_HOST_H_
+
+#include "usb.h"
+#include "usb_misc.h"
+#include "usb_spec.h"
+#include "usb_host_framework.h"
+
+/*******************************************************************************
+ * Definitions
+ ******************************************************************************/
+
+struct _usb_host_transfer; /* for cross reference */
+
+/*!
+ * @addtogroup usb_host_drv
+ * @{
+ */
+
+/*! @brief USB host class handle type define */
+typedef void *usb_host_class_handle;
+
+/*! @brief USB host controller handle type define */
+typedef void *usb_host_controller_handle;
+
+/*! @brief USB host configuration handle type define */
+typedef void *usb_host_configuration_handle;
+
+/*! @brief USB host interface handle type define */
+typedef void *usb_host_interface_handle;
+
+/*! @brief USB host pipe handle type define */
+typedef void *usb_host_pipe_handle;
+
+/*! @brief Event codes for device attach/detach */
+typedef enum _usb_host_event
+{
+ kUSB_HostEventAttach = 1U, /*!< Device is attached */
+ kUSB_HostEventDetach, /*!< Device is detached */
+ kUSB_HostEventEnumerationDone, /*!< Device's enumeration is done and the device is supported */
+ kUSB_HostEventNotSupported /*!< Device's enumeration is done and the device is not supported */
+} usb_host_event_t;
+
+/*! @brief USB host device information code */
+typedef enum _usb_host_dev_info
+{
+ kUSB_HostGetDeviceAddress = 1U, /*!< Device's address */
+ kUSB_HostGetDeviceHubNumber, /*!< Device's first hub address */
+ kUSB_HostGetDevicePortNumber, /*!< Device's first hub port number */
+ kUSB_HostGetDeviceSpeed, /*!< Device's speed */
+ kUSB_HostGetDeviceHSHubNumber, /*!< Device's first high-speed hub address */
+ kUSB_HostGetDeviceHSHubPort, /*!< Device's first high-speed hub number */
+ kUSB_HostGetDeviceLevel, /*!< Device's hub level */
+ kUSB_HostGetHostHandle, /*!< Device's host handle */
+ kUSB_HostGetDeviceControlPipe, /*!< Device's control pipe handle */
+ kUSB_HostGetDevicePID, /*!< Device's PID */
+ kUSB_HostGetDeviceVID, /*!< Device's VID */
+ kUSB_HostGetHubThinkTime, /*!< Device's hub total think time */
+ kUSB_HostGetDeviceConfigIndex, /*!< Device's running zero-based config index */
+} usb_host_dev_info_t;
+
+/*!
+ * @brief Host callback function typedef.
+ *
+ * This callback function is used to notify application device attach/detach event.
+ * This callback pointer is passed when initializing the host.
+ *
+ * @param deviceHandle The device handle, which indicates the attached device.
+ * @param configurationHandle The configuration handle contains the attached device's configuration information.
+ * @param event_code The callback event code; See the enumeration host_event_t.
+ *
+ * @return A USB error code or kStatus_USB_Success.
+ * @retval kStatus_USB_Success Application handles the attached device successfully.
+ * @retval kStatus_USB_NotSupported Application don't support the attached device.
+ * @retval kStatus_USB_Error Application handles the attached device falsely.
+ */
+typedef usb_status_t (*host_callback_t)(usb_device_handle deviceHandle,
+ usb_host_configuration_handle configurationHandle,
+ uint32_t eventCode);
+
+/*!
+ * @brief Transfer callback function typedef.
+ *
+ * This callback function is used to notify the upper layer the result of the transfer.
+ * This callback pointer is passed when calling the send/receive APIs.
+ *
+ * @param param The parameter pointer, which is passed when calling the send/receive APIs.
+ * @param data The data buffer pointer.
+ * @param data_len The result data length.
+ * @param status A USB error code or kStatus_USB_Success.
+ */
+typedef void (*transfer_callback_t)(void *param, uint8_t *data, uint32_t dataLen, usb_status_t status);
+
+/*!
+ * @brief Host stack inner transfer callback function typedef.
+ *
+ * This callback function is used to notify the upper layer the result of a transfer.
+ * This callback pointer is passed when initializing the structure usb_host_transfer_t.
+ *
+ * @param param The parameter pointer, which is passed when calling the send/receive APIs.
+ * @param transfer The transfer information; See the structure usb_host_transfer_t.
+ * @param status A USB error code or kStatus_USB_Success.
+ */
+typedef void (*host_inner_transfer_callback_t)(void *param, struct _usb_host_transfer *transfer, usb_status_t status);
+
+/*! @brief USB host endpoint information structure */
+typedef struct _usb_host_ep
+{
+ usb_descriptor_endpoint_t *epDesc; /*!< Endpoint descriptor pointer*/
+ uint8_t *epExtension; /*!< Endpoint extended descriptor pointer*/
+ uint16_t epExtensionLength; /*!< Extended descriptor length*/
+} usb_host_ep_t;
+
+/*! @brief USB host interface information structure */
+typedef struct _usb_host_interface
+{
+ usb_host_ep_t epList[USB_HOST_CONFIG_INTERFACE_MAX_EP]; /*!< Endpoint array*/
+ usb_descriptor_interface_t *interfaceDesc; /*!< Interface descriptor pointer*/
+ uint8_t *interfaceExtension; /*!< Interface extended descriptor pointer*/
+ uint16_t interfaceExtensionLength; /*!< Extended descriptor length*/
+ uint8_t interfaceIndex; /*!< The interface index*/
+ uint8_t alternateSettingNumber; /*!< The interface alternate setting value*/
+ uint8_t epCount; /*!< Interface's endpoint number*/
+} usb_host_interface_t;
+
+/*! @brief USB host configuration information structure */
+typedef struct _usb_host_configuration
+{
+ usb_host_interface_t interfaceList[USB_HOST_CONFIG_CONFIGURATION_MAX_INTERFACE]; /*!< Interface array*/
+ usb_descriptor_configuration_t *configurationDesc; /*!< Configuration descriptor pointer*/
+ uint8_t *configurationExtension; /*!< Configuration extended descriptor pointer*/
+ uint16_t configurationExtensionLength; /*!< Extended descriptor length*/
+ uint8_t interfaceCount; /*!< The configuration's interface number*/
+} usb_host_configuration_t;
+
+/*! @brief USB host pipe common structure */
+typedef struct _usb_host_pipe
+{
+ struct _usb_host_pipe *next; /*!< Link the idle pipes*/
+ usb_device_handle deviceHandle; /*!< This pipe's device's handle*/
+ uint16_t currentCount; /*!< For KHCI transfer*/
+ uint16_t nakCount; /*!< Maximum NAK count*/
+ uint16_t maxPacketSize; /*!< Maximum packet size*/
+ uint16_t interval; /*!< FS/LS: frame unit; HS: micro-frame unit*/
+ uint8_t open; /*!< 0 - closed, 1 - open*/
+ uint8_t nextdata01; /*!< Data toggle*/
+ uint8_t endpointAddress; /*!< Endpoint address*/
+ uint8_t direction; /*!< Pipe direction*/
+ uint8_t pipeType; /*!< Pipe type, for example USB_ENDPOINT_BULK*/
+ uint8_t numberPerUframe; /*!< Transaction number per micro-frame*/
+} usb_host_pipe_t;
+
+/*! @brief USB host transfer structure */
+typedef struct _usb_host_transfer
+{
+ struct _usb_host_transfer *next; /*!< The next transfer structure*/
+#if USB_HOST_CONFIG_EHCI
+ uint32_t ehciUnitHead; /*!< QTD/ITD/SITD head for this transfer*/
+ uint32_t ehciUnitTail; /*!< QTD/ITD/SITD tail for this transfer*/
+#endif
+ uint8_t *transferBuffer; /*!< Transfer data buffer*/
+ uint32_t transferLength; /*!< Transfer data length*/
+ uint32_t transferSofar; /*!< Have transferred length*/
+ host_inner_transfer_callback_t callbackFn; /*!< Transfer callback function*/
+ void *callbackParam; /*!< Transfer callback parameter*/
+ usb_host_pipe_t *transferPipe; /*!< Transfer pipe pointer*/
+ usb_setup_struct_t setupPacket; /*!< Set up packet buffer*/
+ uint8_t direction; /*!< Transfer direction; its values are USB_OUT or USB_IN*/
+ uint8_t setupStatus; /*!< Set up the transfer status*/
+#if USB_HOST_CONFIG_KHCI
+ int32_t transferResult; /*!< KHCI transfer result */
+ uint32_t frame; /*!< KHCI transfer frame number */
+ uint16_t nakTimeout; /*!< KHCI transfer NAK timeout */
+ uint16_t retry; /*!< KHCI transfer retry */
+#endif
+} usb_host_transfer_t;
+
+/*! @brief USB host pipe information structure for opening pipe */
+typedef struct _usb_host_pipe_init
+{
+ void *devInstance; /*!< Device instance handle*/
+ uint16_t nakCount; /*!< Maximum NAK retry count. MUST be zero for interrupt*/
+ uint16_t maxPacketSize; /*!< Pipe's maximum packet size*/
+ uint8_t interval; /*!< Pipe's interval*/
+ uint8_t endpointAddress; /*!< Endpoint address*/
+ uint8_t direction; /*!< Endpoint direction*/
+ uint8_t pipeType; /*!< Endpoint type, the value is USB_ENDPOINT_INTERRUPT, USB_ENDPOINT_CONTROL,
+ USB_ENDPOINT_ISOCHRONOUS, USB_ENDPOINT_BULK*/
+ uint8_t numberPerUframe; /*!< Transaction number for each micro-frame*/
+} usb_host_pipe_init_t;
+
+/*! @brief Cancel transfer parameter structure */
+typedef struct _usb_host_cancel_param
+{
+ usb_host_pipe_handle pipeHandle; /*!< Cancelling pipe handle*/
+ usb_host_transfer_t *transfer; /*!< Cancelling transfer*/
+} usb_host_cancel_param_t;
+
+/*******************************************************************************
+ * API
+ ******************************************************************************/
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*!
+ * @name USB host APIs Part 1
+ * The following APIs are recommended for application use.
+ * @{
+ */
+
+/*!
+ * @brief Initializes the USB host stack.
+ *
+ * This function initializes the USB host module specified by the controllerId.
+ *
+ * @param[in] controllerId The controller ID of the USB IP. See the enumeration usb_controller_index_t.
+ * @param[out] hostHandle Returns the host handle.
+ * @param[in] callbackFn Host callback function notifies device attach/detach.
+ *
+ * @retval kStatus_USB_Success The host is initialized successfully.
+ * @retval kStatus_USB_InvalidHandle The host_handle_ptr is a NULL pointer.
+ * @retval kStatus_USB_ControllerNotFound Cannot find the controller according to the controller ID.
+ * @retval kStatus_USB_AllocFail Allocation memory fail.
+ * @retval kStatus_USB_Error Host mutex create fail; KHCI/EHCI mutex or KHCI/EHCI event create fail,
+ * or, KHCI/EHCI IP initialize fail.
+ */
+extern usb_status_t USB_HostInit(uint8_t controllerId, usb_host_handle *hostHandle, host_callback_t callbackFn);
+
+/*!
+ * @brief Deinitializes the USB host stack.
+ *
+ * This function deinitializes the USB host module specified by the hostHandle.
+ *
+ * @param[in] hostHandle The host handle.
+ *
+ * @retval kStatus_USB_Success The host is initialized successfully.
+ * @retval kStatus_USB_InvalidHandle The hostHandle is a NULL pointer.
+ * @retval kStatus_USB_Error Controller deinitialization fail.
+ */
+extern usb_status_t USB_HostDeinit(usb_host_handle hostHandle);
+
+/*!
+ * @brief Gets the device information.
+ *
+ * This function gets the device information.
+ *
+ * @param[in] deviceHandle Removing device handle.
+ * @param[in] infoCode See the enumeration host_dev_info_t.
+ * @param[out] infoValue Return the information value.
+ *
+ * @retval kStatus_USB_Success Close successfully.
+ * @retval kStatus_USB_InvalidParameter The deviceHandle or info_value is a NULL pointer.
+ * @retval kStatus_USB_Error The info_code is not the host_dev_info_t value.
+ */
+extern usb_status_t USB_HostHelperGetPeripheralInformation(usb_device_handle deviceHandle,
+ uint32_t infoCode,
+ uint32_t *infoValue);
+
+/*!
+ * @brief Parses the alternate interface descriptor.
+ *
+ * This function parses the alternate interface descriptor and returns an interface information through the structure
+ * usb_host_interface_t.
+ *
+ * @param[in] interfaceHandle The whole interface handle.
+ * @param[in] alternateSetting Alternate setting value.
+ * @param[out] interface Return interface information.
+ *
+ * @retval kStatus_USB_Success Close successfully.
+ * @retval kStatus_USB_InvalidHandle The interfaceHandle is a NULL pointer.
+ * @retval kStatus_USB_InvalidParameter The alternateSetting is 0.
+ * @retval kStatus_USB_Error The interface descriptor is wrong.
+ */
+extern usb_status_t USB_HostHelperParseAlternateSetting(usb_host_interface_handle interfaceHandle,
+ uint8_t alternateSetting,
+ usb_host_interface_t *interface);
+
+/*!
+ * @brief Removes the attached device.
+ *
+ * This function removes the attached device.
+ *
+ * @param[in] hostHandle The host handle.
+ * @param[in] deviceHandle Removing device handle.
+ *
+ * @retval kStatus_USB_Success Remove successfully.
+ * @retval kStatus_USB_InvalidHandle The hostHandle or deviceHandle is a NULL pointer.
+ * @retval kStatus_USB_InvalidParameter The deviceHandle instance don't belong to hostHandle instance.
+ */
+extern usb_status_t USB_HostRemoveDevice(usb_host_handle hostHandle, usb_device_handle deviceHandle);
+
+/*!
+ * @brief KHCI task function.
+ *
+ * The function is used to handle the KHCI controller message.
+ * In the bare metal environment, this function should be called periodically in the main function.
+ * In the RTOS environment, this function should be used as a function entry to create a task.
+ *
+ * @param[in] hostHandle The host handle.
+ */
+extern void USB_HostKhciTaskFunction(void *hostHandle);
+
+/*!
+ * @brief EHCI task function.
+ *
+ * The function is used to handle the EHCI controller message.
+ * In the bare metal environment, this function should be called periodically in the main function.
+ * In the RTOS environment, this function should be used as a function entry to create a task.
+ *
+ * @param[in] hostHandle The host handle.
+ */
+extern void USB_HostEhciTaskFunction(void *hostHandle);
+
+/*!
+ * @brief Device KHCI ISR function.
+ *
+ * The function is the KHCI interrupt service routine.
+ *
+ * @param[in] hostHandle The host handle.
+ */
+extern void USB_HostKhciIsrFunction(void *hostHandle);
+
+/*!
+ * @brief Device EHCI ISR function.
+ *
+ * The function is the EHCI interrupt service routine.
+ *
+ * @param[in] hostHandle The host handle.
+ */
+extern void USB_HostEhciIsrFunction(void *hostHandle);
+/*! @}*/
+
+/*!
+ * @name USB host APIs Part 2.
+ * The following APIs are not recommended for application use. They are mainly used in the class driver.
+ * @{
+ */
+
+/*!
+ * @brief Opens the USB host pipe.
+ *
+ * This function opens a pipe according to the pipe_init_ptr parameter.
+ *
+ * @param[in] hostHandle The host handle.
+ * @param[out] pipeHandle The pipe handle pointer used to return the pipe handle.
+ * @param[in] pipeInit Used to initialize the pipe.
+ *
+ * @retval kStatus_USB_Success The host is initialized successfully.
+ * @retval kStatus_USB_InvalidHandle The hostHandle or pipe_handle_ptr is a NULL pointer.
+ * @retval kStatus_USB_Error There is no idle pipe.
+ * Or, there is no idle QH for EHCI.
+ * Or, bandwidth allocate fail for EHCI.
+ */
+extern usb_status_t USB_HostOpenPipe(usb_host_handle hostHandle,
+ usb_host_pipe_handle *pipeHandle,
+ usb_host_pipe_init_t *pipeInit);
+
+/*!
+ * @brief Closes the USB host pipe.
+ *
+ * This function closes a pipe and frees the related resources.
+ *
+ * @param[in] hostHandle The host handle.
+ * @param[in] pipeHandle The closing pipe handle.
+ *
+ * @retval kStatus_USB_Success The host is initialized successfully.
+ * @retval kStatus_USB_InvalidHandle The hostHandle or pipeHandle is a NULL pointer.
+ */
+extern usb_status_t USB_HostClosePipe(usb_host_handle hostHandle, usb_host_pipe_handle pipeHandle);
+
+/*!
+ * @brief Sends data to a pipe.
+ *
+ * This function requests to send the transfer to the specified pipe.
+ *
+ * @param[in] hostHandle The host handle.
+ * @param[in] pipeHandle The sending pipe handle.
+ * @param[in] transfer The transfer information.
+ *
+ * @retval kStatus_USB_Success Send successfully.
+ * @retval kStatus_USB_InvalidHandle The hostHandle, pipeHandle or transfer is a NULL pointer.
+ * @retval kStatus_USB_LackSwapBuffer There is no swap buffer for KHCI.
+ * @retval kStatus_USB_Error There is no idle QTD/ITD/SITD for EHCI.
+ */
+extern usb_status_t USB_HostSend(usb_host_handle hostHandle,
+ usb_host_pipe_handle pipeHandle,
+ usb_host_transfer_t *transfer);
+
+/*!
+ * @brief Sends a setup transfer to the pipe.
+ *
+ * This function request to send the setup transfer to the specified pipe.
+ *
+ * @param[in] hostHandle The host handle.
+ * @param[in] pipeHandle The sending pipe handle.
+ * @param[in] transfer The transfer information.
+ *
+ * @retval kStatus_USB_Success Send successfully.
+ * @retval kStatus_USB_InvalidHandle The hostHandle, pipeHandle or transfer is a NULL pointer.
+ * @retval kStatus_USB_LackSwapBuffer There is no swap buffer for KHCI.
+ * @retval kStatus_USB_Error There is no idle QTD/ITD/SITD for EHCI.
+ */
+extern usb_status_t USB_HostSendSetup(usb_host_handle hostHandle,
+ usb_host_pipe_handle pipeHandle,
+ usb_host_transfer_t *transfer);
+
+/*!
+ * @brief Receives the data from the pipe.
+ *
+ * This function requests to receive the transfer from the specified pipe.
+ *
+ * @param[in] hostHandle The host handle.
+ * @param[in] pipeHandle The receiving pipe handle.
+ * @param[in] transfer The transfer information.
+ *
+ * @retval kStatus_USB_Success Receive successfully.
+ * @retval kStatus_USB_InvalidHandle The hostHandle, pipeHandle or transfer is a NULL pointer.
+ * @retval kStatus_USB_LackSwapBuffer There is no swap buffer for KHCI.
+ * @retval kStatus_USB_Error There is no idle QTD/ITD/SITD for EHCI.
+ */
+extern usb_status_t USB_HostRecv(usb_host_handle hostHandle,
+ usb_host_pipe_handle pipeHandle,
+ usb_host_transfer_t *transfer);
+
+/*!
+ * @brief Cancel the pipe's transfers.
+ *
+ * This function cancels all pipe's transfers when the parameter transfer is NULL or cancels the transfers altogether.
+ *
+ * @param[in] hostHandle The host handle.
+ * @param[in] pipeHandle The receiving pipe handle.
+ * @param[in] transfer The transfer information.
+ *
+ * @retval kStatus_USB_Success Cancel successfully.
+ * @retval kStatus_USB_InvalidHandle The hostHandle or pipeHandle is a NULL pointer.
+ */
+extern usb_status_t USB_HostCancelTransfer(usb_host_handle hostHandle,
+ usb_host_pipe_handle pipeHandle,
+ usb_host_transfer_t *transfer);
+
+/*!
+ * @brief Allocates a transfer resource.
+ *
+ * This function allocates a transfer. This transfer is used to pass data information to a low level stack.
+ *
+ * @param[in] hostHandle The host handle.
+ * @param[out] transfer Return the transfer.
+ *
+ * @retval kStatus_USB_Success Allocate successfully.
+ * @retval kStatus_USB_InvalidHandle The hostHandle or transfer is a NULL pointer.
+ * @retval kStatus_USB_Error There is no idle transfer.
+ */
+extern usb_status_t USB_HostMallocTransfer(usb_host_handle hostHandle, usb_host_transfer_t **transfer);
+
+/*!
+ * @brief Frees a transfer resource.
+ *
+ * This function frees a transfer. This transfer is used to pass data information to a low level stack.
+ *
+ * @param[in] hostHandle The host handle.
+ * @param[in] transfer Release the transfer.
+ *
+ * @retval kStatus_USB_Success Free successfully.
+ * @retval kStatus_USB_InvalidHandle The hostHandle or transfer is a NULL pointer.
+ */
+extern usb_status_t USB_HostFreeTransfer(usb_host_handle hostHandle, usb_host_transfer_t *transfer);
+
+/*!
+ * @brief Requests the USB standard request.
+ *
+ * This function sends the USB standard request packet.
+ *
+ * @param[in] deviceHandle The device handle for control transfer.
+ * @param[in] usbRequest A USB standard request code. Se the usb_spec.h.
+ * @param[in] transfer The used transfer.
+ * @param[in] param The parameter structure is different for different request, see
+ * usb_host_framework.h.
+ *
+ * @retval kStatus_USB_Success Send successfully.
+ * @retval kStatus_USB_InvalidHandle The deviceHandle is a NULL pointer.
+ * @retval kStatus_USB_LackSwapBuffer There is no swap buffer for KHCI.
+ * @retval kStatus_USB_Error There is no idle QTD/ITD/SITD for EHCI,
+ * Or, the request is not standard request.
+ */
+extern usb_status_t USB_HostRequestControl(usb_device_handle deviceHandle,
+ uint8_t usbRequest,
+ usb_host_transfer_t *transfer,
+ void *param);
+
+/*!
+ * @brief Opens the interface.
+ *
+ * This function opens the interface. It is used to notify the host driver the interface is used by APP or class driver.
+ *
+ * @param[in] deviceHandle Removing device handle.
+ * @param[in] interfaceHandle Opening interface handle.
+ *
+ * @retval kStatus_USB_Success Open successfully.
+ * @retval kStatus_USB_InvalidHandle The deviceHandle or interfaceHandle is a NULL pointer.
+ */
+extern usb_status_t USB_HostOpenDeviceInterface(usb_device_handle deviceHandle,
+ usb_host_interface_handle interfaceHandle);
+
+/*!
+ * @brief Closes an interface.
+ *
+ * This function opens an interface. It is used to notify the host driver the interface is not used by APP or class
+ * driver.
+ *
+ * @param[in] deviceHandle Removing device handle.
+ * @param[in] interfaceHandle Opening interface handle.
+ *
+ * @retval kStatus_USB_Success Close successfully.
+ * @retval kStatus_USB_InvalidHandle The deviceHandle is a NULL pointer.
+ */
+extern usb_status_t USB_HostCloseDeviceInterface(usb_device_handle deviceHandle,
+ usb_host_interface_handle interfaceHandle);
+
+/*!
+ * @brief Gets a host stack version function.
+ *
+ * The function is used to get the host stack version.
+ *
+ * @param[out] version The version structure pointer to keep the host stack version.
+ *
+ */
+extern void USB_HostGetVersion(uint32_t *version);
+
+/*! @}*/
+
+#ifdef __cplusplus
+}
+#endif
+
+/*! @}*/
+
+#endif /* _USB_HOST_H_ */
diff --git a/usb_1.1.0/host/usb_host_devices.c b/usb_1.1.0/host/usb_host_devices.c
new file mode 100644
index 0000000..f4ec31b
--- /dev/null
+++ b/usb_1.1.0/host/usb_host_devices.c
@@ -0,0 +1,1345 @@
+/*
+ * Copyright (c) 2015 - 2016, Freescale Semiconductor, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * o Redistributions of source code must retain the above copyright notice, this list
+ * of conditions and the following disclaimer.
+ *
+ * o Redistributions in binary form must reproduce the above copyright notice, this
+ * list of conditions and the following disclaimer in the documentation and/or
+ * other materials provided with the distribution.
+ *
+ * o Neither the name of Freescale Semiconductor, Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "usb_host_config.h"
+#include "usb_host.h"
+#include "usb_host_hci.h"
+#include "usb_host_devices.h"
+
+#if ((defined USB_HOST_CONFIG_HUB) && (USB_HOST_CONFIG_HUB))
+#include "usb_host_hub.h"
+#endif /* USB_HOST_CONFIG_HUB */
+
+/*******************************************************************************
+ * Definitions
+ ******************************************************************************/
+
+/*******************************************************************************
+ * Prototypes
+ ******************************************************************************/
+
+/*!
+ * @brief enumeration transfer callback function.
+ *
+ * @param param callback parameter.
+ * @param transfer the transfer.
+ * @param status transfer result status.
+ */
+static void USB_HostEnumerationTransferCallback(void *param, usb_host_transfer_t *transfer, usb_status_t status);
+
+/*!
+ * @brief process the new step state.
+ *
+ * @param deviceInstance device instance pointer.
+ *
+ * @return kStatus_USB_Success or error codes
+ */
+static usb_status_t USB_HostProcessState(usb_host_device_instance_t *deviceInstance);
+
+/*!
+ * @brief process the previous step transfer result.
+ *
+ * @param deviceInstance device instance pointer.
+ *
+ * @return kStatus_USB_Success or error codes
+ */
+static usb_status_t USB_HostProcessCallback(usb_host_device_instance_t *deviceInstance);
+
+/*!
+ * @brief notify the application event, the callback is registered when initializing host.
+ *
+ * @param deviceInstance device instance pointer.
+ * @param eventCode event code.
+ *
+ * @return kStatus_USB_Success or error codes
+ */
+static usb_status_t USB_HostNotifyDevice(usb_host_device_instance_t *deviceInstance, uint32_t eventCode);
+
+/*!
+ * @brief allocate one address.
+ *
+ * @param hostInstance host instance pointer.
+ *
+ * @return address, 0 is invalid.
+ */
+static uint8_t USB_HostAllocateDeviceAddress(usb_host_instance_t *hostInstance);
+
+/*!
+ * @brief release one address.
+ *
+ * @param hostInstance host instance pointer.
+ * @param address releasing address.
+ */
+static void USB_HostReleaseDeviceAddress(usb_host_instance_t *hostInstance, uint8_t address);
+
+/*!
+ * @brief release device resource.
+ *
+ * @param hostInstance host instance pointer.
+ * @param deviceInstance device instance pointer.
+ */
+static void USB_HostReleaseDeviceResource(usb_host_instance_t *hostInstance,
+ usb_host_device_instance_t *deviceInstance);
+
+/*!
+ * @brief parse device configuration descriptor.
+ *
+ * @param deviceHandle device handle.
+ *
+ * @return kStatus_USB_Success or error codes.
+ */
+static usb_status_t USB_HostParseDeviceConfigurationDescriptor(usb_device_handle deviceHandle);
+
+/*!
+ * @brief remove device instance from host device list.
+ *
+ * @param hostHandle host instance handle.
+ * @param deviceHandle device handle.
+ *
+ * @return kStatus_USB_Success or error codes.
+ */
+static usb_status_t USB_HostRemoveDeviceInstance(usb_host_handle hostHandle, usb_device_handle deviceHandle);
+
+/*!
+ * @brief control the bus.
+ *
+ * This function control the host bus.
+ *
+ * @param[in] hostHandle the host handle.
+ * @param[in] controlType the control code, please reference to bus_event_t.
+ *
+ * @retval kStatus_USB_Success control successfully.
+ * @retval kStatus_USB_InvalidHandle The hostHandle is a NULL pointer.
+ */
+static usb_status_t USB_HostControlBus(usb_host_handle hostHandle, uint8_t controlType);
+
+extern usb_status_t USB_HostStandardSetGetDescriptor(usb_host_device_instance_t *deviceInstance,
+ usb_host_transfer_t *transfer,
+ void *param);
+extern usb_status_t USB_HostStandardSetAddress(usb_host_device_instance_t *deviceInstance,
+ usb_host_transfer_t *transfer,
+ void *param);
+extern usb_status_t USB_HostCh9RequestCommon(usb_host_device_instance_t *deviceInstance,
+ usb_host_transfer_t *transfer,
+ uint8_t *buffer,
+ uint32_t bufferLen);
+
+#if ((defined USB_HOST_CONFIG_HUB) && (USB_HOST_CONFIG_HUB))
+
+extern usb_status_t USB_HostHubDeviceEvent(usb_device_handle deviceHandle,
+ usb_host_configuration_handle configurationHandle,
+ uint32_t eventCode);
+
+extern uint32_t USB_HostHubGetHsHubNumber(uint8_t parentHubNo);
+
+extern uint32_t USB_HostHubGetHsHubPort(uint8_t parentHubNo, uint8_t parentPortNo);
+
+extern usb_status_t USB_HostHubRemovePort(uint8_t hubNumber, uint8_t portNumber);
+
+#endif
+
+/*******************************************************************************
+ * Variables
+ ******************************************************************************/
+
+extern usb_host_instance_t g_UsbHostInstance[USB_HOST_CONFIG_MAX_HOST];
+
+/*! @brief enumeration step process array */
+static const usb_host_enum_process_entry_t s_EnumEntries[] = \
+{
+ /* kStatus_dev_initial */
+ {
+ 0, 0, NULL,
+ },
+ /* kStatus_DEV_GetDes8 */
+ {
+ kStatus_DEV_SetAddress, kStatus_DEV_GetDes8, USB_HostProcessCallback,
+ },
+ /* kStatus_DEV_SetAddress */
+ {
+ kStatus_DEV_GetDes, kStatus_DEV_SetAddress, USB_HostProcessCallback,
+ },
+ /* kStatus_DEV_GetDes */
+ {
+ kStatus_DEV_GetCfg9, kStatus_DEV_GetDes, NULL,
+ },
+ /* kStatus_DEV_GetCfg9 */
+ {
+ kStatus_DEV_GetCfg, kStatus_DEV_GetCfg9, USB_HostProcessCallback,
+ },
+ /* kStatus_DEV_GetCfg */
+ {
+ kStatus_DEV_SetCfg, kStatus_DEV_GetCfg9, USB_HostProcessCallback,
+ },
+ /* kStatus_DEV_SetCfg */
+ {
+ kStatus_DEV_EnumDone, kStatus_DEV_SetCfg, NULL,
+ },
+};
+
+/*******************************************************************************
+ * Code
+ ******************************************************************************/
+
+static void USB_HostEnumerationTransferCallback(void *param, usb_host_transfer_t *transfer, usb_status_t status)
+{
+ uint8_t nextStep = 0;
+ usb_host_device_instance_t *deviceInstance = (usb_host_device_instance_t *)param;
+
+ USB_HostFreeTransfer(deviceInstance->hostHandle, transfer); /* free transfer */
+
+ if (status == kStatus_USB_Success)
+ {
+ nextStep = 1;
+ }
+ else if (status == kStatus_USB_TransferStall)
+ {
+#if ((defined USB_HOST_CONFIG_COMPLIANCE_TEST) && (USB_HOST_CONFIG_COMPLIANCE_TEST))
+ usb_echo("no response from device\r\n");
+#endif /* USB_HOST_CONFIG_COMPLIANCE_TEST */
+ if (deviceInstance->stallRetries > 0) /* retry same transfer when stall */
+ {
+ deviceInstance->stallRetries--;
+ }
+ else /* process next state when all retries stall */
+ {
+ nextStep = 1;
+ }
+ }
+ else if (status == kStatus_USB_TransferCancel)
+ {
+ return;
+ }
+ else
+ {
+ if (deviceInstance->enumRetries > 0) /* next whole retry */
+ {
+ deviceInstance->enumRetries--;
+ deviceInstance->stallRetries = USB_HOST_CONFIG_ENUMERATION_MAX_STALL_RETRIES;
+ deviceInstance->configurationValue = 0;
+ deviceInstance->state = kStatus_DEV_GetDes8;
+ }
+ else
+ {
+#if ((defined USB_HOST_CONFIG_COMPLIANCE_TEST) && (USB_HOST_CONFIG_COMPLIANCE_TEST))
+ usb_echo("Device No Response\r\n");
+#endif
+ return;
+ }
+ }
+
+ if (nextStep == 1)
+ {
+ deviceInstance->stallRetries = USB_HOST_CONFIG_ENUMERATION_MAX_STALL_RETRIES;
+ if (s_EnumEntries[deviceInstance->state - 1].process == NULL)
+ {
+ deviceInstance->state = s_EnumEntries[deviceInstance->state - 1].successState; /* next state */
+ }
+ else
+ {
+ status = s_EnumEntries[deviceInstance->state - 1].process(
+ deviceInstance); /* process the previous state result */
+ if (status == kStatus_USB_Success) /* process success */
+ {
+ deviceInstance->state = s_EnumEntries[deviceInstance->state - 1].successState;
+ }
+ else if (status == kStatus_USB_Retry) /* need retry */
+ {
+ deviceInstance->state = s_EnumEntries[deviceInstance->state - 1].retryState;
+ }
+ else if (status == kStatus_USB_NotSupported) /* device don't suport by the application */
+ {
+ return; /* unrecoverable fail */
+ }
+ else /* process error, next retry */
+ {
+ if (deviceInstance->enumRetries > 0) /* next whole retry */
+ {
+ deviceInstance->enumRetries--;
+ deviceInstance->stallRetries = USB_HOST_CONFIG_ENUMERATION_MAX_STALL_RETRIES;
+ deviceInstance->configurationValue = 0;
+ deviceInstance->state = kStatus_DEV_GetDes8;
+ }
+ else
+ {
+#if ((defined USB_HOST_CONFIG_COMPLIANCE_TEST) && (USB_HOST_CONFIG_COMPLIANCE_TEST))
+ usb_echo("Device No Response\r\n");
+#endif
+ return; /* unrecoverable fail */
+ }
+ }
+ }
+ }
+
+ if (USB_HostProcessState(deviceInstance) != kStatus_USB_Success) /* process the new state */
+ {
+#ifdef HOST_ECHO
+ usb_echo("enumation setup error\r\n");
+#endif
+ return;
+ }
+}
+
+static usb_status_t USB_HostProcessState(usb_host_device_instance_t *deviceInstance)
+{
+ usb_status_t status = kStatus_USB_Success;
+ usb_host_process_descriptor_param_t getDescriptorParam;
+ usb_host_transfer_t *transfer;
+
+ /* malloc transfer */
+ if (deviceInstance->state != kStatus_DEV_EnumDone)
+ {
+ if (USB_HostMallocTransfer(deviceInstance->hostHandle, &transfer) != kStatus_USB_Success)
+ {
+#ifdef HOST_ECHO
+ usb_echo("error to get transfer\r\n");
+#endif
+ return kStatus_USB_Error;
+ }
+ transfer->callbackFn = USB_HostEnumerationTransferCallback;
+ transfer->callbackParam = deviceInstance;
+
+ /* reset transfer fields */
+ transfer->setupPacket.bmRequestType = 0x00;
+ transfer->setupPacket.wIndex = 0;
+ transfer->setupPacket.wLength = 0;
+ transfer->setupPacket.wValue = 0;
+ }
+
+ switch (deviceInstance->state)
+ {
+ case kStatus_DEV_GetDes8:
+ case kStatus_DEV_GetDes: /* get descriptor state */
+ getDescriptorParam.descriptorLength = sizeof(usb_descriptor_device_t);
+ if (deviceInstance->state == kStatus_DEV_GetDes8)
+ {
+ getDescriptorParam.descriptorLength = 8;
+ }
+ getDescriptorParam.descriptorBuffer = (uint8_t *)&deviceInstance->deviceDescriptor;
+ getDescriptorParam.descriptorType = USB_DESCRIPTOR_TYPE_DEVICE;
+ getDescriptorParam.descriptorIndex = 0;
+ getDescriptorParam.languageId = 0;
+
+ transfer->setupPacket.bmRequestType |= USB_REQUEST_TYPE_DIR_IN;
+ transfer->setupPacket.bRequest = USB_REQUEST_STANDARD_GET_DESCRIPTOR;
+ status = USB_HostStandardSetGetDescriptor(deviceInstance, transfer, &getDescriptorParam);
+ break;
+ case kStatus_DEV_SetAddress: /* set address state */
+ transfer->setupPacket.bRequest = USB_REQUEST_STANDARD_SET_ADDRESS;
+ status = USB_HostStandardSetAddress(deviceInstance, transfer, &deviceInstance->allocatedAddress);
+ break;
+
+ case kStatus_DEV_GetCfg9: /* get 9 bytes configuration state */
+ getDescriptorParam.descriptorBuffer = deviceInstance->enumBuffer;
+ getDescriptorParam.descriptorType = USB_DESCRIPTOR_TYPE_CONFIGURE;
+ getDescriptorParam.descriptorIndex = deviceInstance->configurationValue;
+ getDescriptorParam.descriptorLength = 9;
+ getDescriptorParam.languageId = 0;
+
+ transfer->setupPacket.bmRequestType |= USB_REQUEST_TYPE_DIR_IN;
+ transfer->setupPacket.bRequest = USB_REQUEST_STANDARD_GET_DESCRIPTOR;
+ status = USB_HostStandardSetGetDescriptor(deviceInstance, transfer, &getDescriptorParam);
+ break;
+
+ case kStatus_DEV_GetCfg: /* get configuration state */
+ getDescriptorParam.descriptorBuffer = deviceInstance->configurationDesc;
+ getDescriptorParam.descriptorType = USB_DESCRIPTOR_TYPE_CONFIGURE;
+ getDescriptorParam.descriptorIndex = deviceInstance->configurationValue;
+ getDescriptorParam.descriptorLength = deviceInstance->configurationLen;
+ getDescriptorParam.languageId = 0;
+
+ transfer->setupPacket.bmRequestType |= USB_REQUEST_TYPE_DIR_IN;
+ transfer->setupPacket.bRequest = USB_REQUEST_STANDARD_GET_DESCRIPTOR;
+ status = USB_HostStandardSetGetDescriptor(deviceInstance, transfer, &getDescriptorParam);
+ break;
+
+ case kStatus_DEV_SetCfg: /* set configuration state */
+ transfer->setupPacket.wValue =
+ USB_SHORT_TO_LITTLE_ENDIAN(deviceInstance->configuration.configurationDesc->bConfigurationValue);
+ transfer->setupPacket.bRequest = USB_REQUEST_STANDARD_SET_CONFIGURATION;
+ status = USB_HostCh9RequestCommon(deviceInstance, transfer, NULL, 0);
+ break;
+
+ case kStatus_DEV_EnumDone: /* enumeration done state */
+ status = USB_HostNotifyDevice(deviceInstance,
+ kUSB_HostEventEnumerationDone); /* notify device enumeration done */
+ if (status == kStatus_USB_Success)
+ {
+ deviceInstance->state = kStatus_DEV_AppUsed;
+ }
+ break;
+
+ default:
+ break;
+ }
+
+ return status;
+}
+
+static usb_status_t USB_HostProcessCallback(usb_host_device_instance_t *deviceInstance)
+{
+ usb_host_pipe_t *pipe = (usb_host_pipe_t *)deviceInstance->controlPipe;
+ usb_status_t status = kStatus_USB_Success;
+ usb_descriptor_configuration_t *configureDesc;
+ usb_host_instance_t *hostInstance = (usb_host_instance_t *)deviceInstance->hostHandle;
+
+ switch (deviceInstance->state)
+ {
+ case kStatus_DEV_GetDes8: /* process get 8 bytes descriptor result */
+ pipe->maxPacketSize = deviceInstance->deviceDescriptor.bMaxPacketSize0;
+ hostInstance->controllerTable->controllerIoctl(
+ hostInstance->controllerHandle, kUSB_HostUpdateControlPacketSize, deviceInstance->controlPipe);
+ break;
+
+ case kStatus_DEV_SetAddress: /* process set address result */
+ deviceInstance->setAddress = deviceInstance->allocatedAddress;
+ hostInstance->controllerTable->controllerIoctl(
+ hostInstance->controllerHandle, kUSB_HostUpdateControlEndpointAddress, deviceInstance->controlPipe);
+ break;
+
+ case kStatus_DEV_GetDes: /* process set address result */
+ /* NULL */
+ break;
+
+ case kStatus_DEV_GetCfg9: /* process get 9 bytes configuration result */
+ configureDesc = (usb_descriptor_configuration_t *)&deviceInstance->enumBuffer[0];
+
+ deviceInstance->configurationLen = USB_SHORT_FROM_LITTLE_ENDIAN_ADDRESS(configureDesc->wTotalLength);
+ if (deviceInstance->configurationDesc != NULL)
+ {
+ USB_OsaMemoryFree(deviceInstance->configurationDesc);
+ deviceInstance->configurationDesc = NULL;
+ }
+ /* for KHCI, the start address and the length should be 4 byte align */
+ if ((deviceInstance->configurationLen & 0x03) != 0)
+ {
+ deviceInstance->configurationDesc =
+ (uint8_t *)USB_OsaMemoryAllocate((deviceInstance->configurationLen & 0xFFFFFFFCu) + 4);
+ }
+ else
+ {
+ deviceInstance->configurationDesc = (uint8_t *)USB_OsaMemoryAllocate(deviceInstance->configurationLen);
+ }
+ if (deviceInstance->configurationDesc == NULL)
+ {
+ return kStatus_USB_Error;
+ }
+ break;
+
+ case kStatus_DEV_GetCfg: /* process get cofiguration result */
+ if (((usb_descriptor_configuration_t *)deviceInstance->configurationDesc)->bMaxPower >
+ USB_HOST_CONFIG_MAX_POWER)
+ {
+ return kStatus_USB_Error;
+ }
+ deviceInstance->configurationValue++;
+ if (USB_HostParseDeviceConfigurationDescriptor(deviceInstance) !=
+ kStatus_USB_Success) /* parse configuration descriptor */
+ {
+ return kStatus_USB_Error;
+ }
+
+ status = USB_HostNotifyDevice(deviceInstance, kUSB_HostEventAttach);
+
+ if (status != kStatus_USB_Success)
+ {
+ /* next configuration */
+ if (deviceInstance->configurationValue < deviceInstance->deviceDescriptor.bNumConfigurations)
+ {
+ return kStatus_USB_Retry;
+ }
+ else
+ {
+ USB_HostNotifyDevice(deviceInstance,
+ kUSB_HostEventNotSupported); /* notify application device is not supported */
+ return kStatus_USB_NotSupported;
+ }
+ }
+ break;
+
+ case kStatus_DEV_SetCfg:
+ /* NULL */
+ break;
+
+ default:
+ break;
+ }
+
+ return status;
+}
+
+static usb_status_t USB_HostNotifyDevice(usb_host_device_instance_t *deviceInstance, uint32_t eventCode)
+{
+ usb_host_instance_t *hostInstance;
+ usb_status_t status1 = kStatus_USB_Error;
+#if ((defined USB_HOST_CONFIG_HUB) && (USB_HOST_CONFIG_HUB))
+ usb_status_t status2 = kStatus_USB_Error;
+ uint8_t haveHub;
+ uint8_t haveNoHub;
+ uint8_t interfaceIndex;
+#endif /* USB_HOST_CONFIG_HUB */
+
+ if (deviceInstance == NULL)
+ {
+ return kStatus_USB_InvalidHandle;
+ }
+ hostInstance = (usb_host_instance_t *)deviceInstance->hostHandle;
+
+#if ((defined USB_HOST_CONFIG_HUB) && (USB_HOST_CONFIG_HUB))
+ haveHub = 0;
+ haveNoHub = 0;
+ for (interfaceIndex = 0; interfaceIndex < deviceInstance->configuration.interfaceCount; ++interfaceIndex)
+ {
+ if (((usb_descriptor_interface_t *)deviceInstance->configuration.interfaceList[interfaceIndex].interfaceDesc)
+ ->bInterfaceClass == USB_HOST_HUB_CLASS_CODE)
+ {
+ haveHub = 1;
+ }
+ else
+ {
+ haveNoHub = 1;
+ }
+ }
+
+ if ((haveNoHub == 1) && (hostInstance->deviceCallback != NULL))
+ {
+ status1 = hostInstance->deviceCallback(deviceInstance, &deviceInstance->configuration,
+ eventCode); /* notify application event */
+ }
+ if (haveHub)
+ {
+ status2 =
+ USB_HostHubDeviceEvent(deviceInstance, &deviceInstance->configuration, eventCode); /* notify hub event */
+ }
+
+ if ((status1 == kStatus_USB_Success) || (status2 == kStatus_USB_Success)) /* the device is supported */
+ {
+ return kStatus_USB_Success;
+ }
+ else if (eventCode == kUSB_HostEventAttach) /* attach event */
+ {
+ status1 = kStatus_USB_NotSupported;
+ }
+ else
+ {
+ status1 = kStatus_USB_Error;
+ }
+#else
+ if (hostInstance->deviceCallback != NULL)
+ {
+ status1 = hostInstance->deviceCallback(deviceInstance, &deviceInstance->configuration,
+ eventCode); /* call host callback function */
+ }
+#endif
+ return status1;
+}
+
+static uint8_t USB_HostAllocateDeviceAddress(usb_host_instance_t *hostInstance)
+{
+ uint8_t address = 0;
+ uint8_t addressIndex;
+ uint8_t addressBitIndex;
+ for (addressIndex = 0; addressIndex < 8; ++addressIndex) /* find the idle address postion byte */
+ {
+ if (hostInstance->addressBitMap[addressIndex] != 0xFF)
+ {
+ break;
+ }
+ }
+ if (addressIndex < 8)
+ {
+ for (addressBitIndex = 0; addressBitIndex < 8; ++addressBitIndex) /* find the idle address position bit */
+ {
+ if (!(hostInstance->addressBitMap[addressIndex] & (0x01u << addressBitIndex)))
+ {
+ hostInstance->addressBitMap[addressIndex] |= (0x01u << addressBitIndex); /* set the allocated bit */
+ address = addressIndex * 8 + addressBitIndex + 1; /* the address minimum is 1 */
+ break;
+ }
+ }
+ }
+ return address;
+}
+
+static void USB_HostReleaseDeviceAddress(usb_host_instance_t *hostInstance, uint8_t address)
+{
+ USB_HostLock();
+ hostInstance->addressBitMap[(uint32_t)(address - 1) >> 3] &=
+ (~(0x01u << (((uint32_t)address - 1) & 0x07U))); /* reset the allocated bit */
+ USB_HostUnlock();
+}
+
+static usb_status_t USB_HostRemoveDeviceInstance(usb_host_handle hostHandle, usb_device_handle deviceHandle)
+{
+ usb_host_instance_t *hostInstance = (usb_host_instance_t *)hostHandle;
+ usb_host_device_instance_t *currentInstance;
+ usb_host_device_instance_t *prevInstance;
+ if ((hostHandle == NULL) || (deviceHandle == NULL))
+ {
+ return kStatus_USB_InvalidHandle;
+ }
+
+ /* search and remove device instance */
+ prevInstance = (usb_host_device_instance_t *)hostInstance->deviceList;
+ if (prevInstance == deviceHandle)
+ {
+ hostInstance->deviceList = prevInstance->next;
+ return kStatus_USB_Success;
+ }
+ else
+ {
+ currentInstance = prevInstance->next;
+ }
+
+ while (currentInstance != NULL)
+ {
+ if (currentInstance == deviceHandle)
+ {
+ prevInstance->next = currentInstance->next;
+ return kStatus_USB_Success;
+ }
+ prevInstance = currentInstance;
+ currentInstance = currentInstance->next;
+ }
+
+ return kStatus_USB_Success;
+}
+
+static void USB_HostReleaseDeviceResource(usb_host_instance_t *hostInstance, usb_host_device_instance_t *deviceInstance)
+{
+#if ((defined USB_HOST_CONFIG_HUB) && (USB_HOST_CONFIG_HUB))
+ uint8_t level = 0;
+#endif
+ /* release device's address */
+ if (deviceInstance->setAddress != 0)
+ {
+ USB_HostReleaseDeviceAddress(hostInstance, deviceInstance->setAddress);
+ }
+ else
+ {
+ if (deviceInstance->allocatedAddress != 0)
+ {
+ USB_HostReleaseDeviceAddress(hostInstance, deviceInstance->allocatedAddress);
+ }
+ }
+
+ /* close control pipe */
+ if (deviceInstance->controlPipe != NULL)
+ {
+ USB_HostCancelTransfer(hostInstance, deviceInstance->controlPipe, NULL);
+ if (USB_HostClosePipe(hostInstance, deviceInstance->controlPipe) != kStatus_USB_Success)
+ {
+#ifdef HOST_ECHO
+ usb_echo("error when close pipe\r\n");
+#endif
+ }
+ deviceInstance->controlPipe = NULL;
+ }
+
+ /* free configuration buffer */
+ if (deviceInstance->configurationDesc != NULL)
+ {
+ USB_OsaMemoryFree(deviceInstance->configurationDesc);
+ }
+
+#if ((defined USB_HOST_CONFIG_HUB) && (USB_HOST_CONFIG_HUB))
+ level = deviceInstance->level;
+#endif
+
+ /* free device instance buffer */
+ USB_OsaMemoryFree(deviceInstance);
+
+#if ((defined USB_HOST_CONFIG_HUB) && (USB_HOST_CONFIG_HUB))
+ /* enable controller attach if root hub */
+ if (level == 1)
+ {
+ USB_HostControlBus(hostInstance, kUSB_HostBusEnableAttach);
+ }
+#else
+ /* enable controller attach */
+ USB_HostControlBus(hostInstance, kUSB_HostBusEnableAttach);
+#endif
+}
+
+static usb_status_t USB_HostParseDeviceConfigurationDescriptor(usb_device_handle deviceHandle)
+{
+ usb_host_device_instance_t *deviceInstance = (usb_host_device_instance_t *)deviceHandle;
+ uint32_t endPos;
+ usb_descriptor_union_t *unionDes;
+ usb_host_interface_t *interfaceParse = NULL;
+ usb_host_ep_t *epParse;
+ uint8_t *buffer;
+
+ if (deviceHandle == NULL)
+ {
+ return kStatus_USB_InvalidParameter;
+ }
+
+ buffer = (uint8_t *)&deviceInstance->configuration;
+ /* clear the previous parse result, note: end_pos means buffer index here*/
+ for (endPos = 0; endPos < sizeof(usb_host_configuration_t); endPos++)
+ {
+ buffer[endPos] = 0;
+ }
+ for (endPos = 0; endPos < USB_HOST_CONFIG_CONFIGURATION_MAX_INTERFACE; ++endPos)
+ {
+ deviceInstance->interfaceStatus[endPos] = 0;
+ }
+
+ /* parse configuration descriptor */
+ unionDes = (usb_descriptor_union_t *)deviceInstance->configurationDesc;
+ endPos = (uint32_t)(deviceInstance->configurationDesc + deviceInstance->configurationLen);
+
+ if ((unionDes->common.bLength == USB_DESCRIPTOR_LENGTH_CONFIGURE) &&
+ (unionDes->common.bDescriptorType == USB_DESCRIPTOR_TYPE_CONFIGURE))
+ {
+ /* configuration descriptor */
+ deviceInstance->configuration.configurationDesc = (usb_descriptor_configuration_t *)unionDes;
+ deviceInstance->configuration.configurationExtensionLength = 0;
+ deviceInstance->configuration.configurationExtension = NULL;
+ deviceInstance->configuration.interfaceCount = 0;
+ unionDes = (usb_descriptor_union_t *)((uint32_t)unionDes + unionDes->common.bLength);
+ while ((uint32_t)unionDes < endPos)
+ {
+ if (unionDes->common.bDescriptorType != USB_DESCRIPTOR_TYPE_INTERFACE)
+ {
+ if (deviceInstance->configuration.configurationExtension == NULL)
+ {
+ deviceInstance->configuration.configurationExtension = (uint8_t *)unionDes;
+ }
+ if ((unionDes->common.bDescriptorType == 0x00) ||
+ (unionDes->common.bLength == 0x00)) /* the descriptor data is wrong */
+ {
+ return kStatus_USB_Error;
+ }
+ deviceInstance->configuration.configurationExtensionLength += unionDes->common.bLength;
+ unionDes = (usb_descriptor_union_t *)((uint32_t)unionDes + unionDes->common.bLength);
+ }
+ else
+ {
+ break;
+ }
+ }
+
+ /* interface descriptor */
+ deviceInstance->configuration.interfaceCount = 0;
+ while ((uint32_t)unionDes < endPos)
+ {
+ if (unionDes->common.bDescriptorType == USB_DESCRIPTOR_TYPE_INTERFACE)
+ {
+ if (unionDes->interface.bAlternateSetting == 0x00)
+ {
+ if (deviceInstance->configuration.interfaceCount >= USB_HOST_CONFIG_CONFIGURATION_MAX_INTERFACE)
+ {
+#ifdef HOST_ECHO
+ usb_echo(
+ "Unsupported Device attached\r\n too many interfaces in one configuration, please increase "
+ "the USB_HOST_CONFIG_CONFIGURATION_MAX_INTERFACE value\n");
+#endif
+ return kStatus_USB_Error;
+ }
+ interfaceParse =
+ &deviceInstance->configuration.interfaceList[deviceInstance->configuration.interfaceCount];
+ deviceInstance->configuration.interfaceCount++;
+ interfaceParse->alternateSettingNumber = 0;
+ interfaceParse->epCount = 0;
+ interfaceParse->interfaceDesc = &unionDes->interface;
+ interfaceParse->interfaceExtensionLength = 0;
+ interfaceParse->interfaceExtension = NULL;
+ interfaceParse->interfaceIndex = unionDes->interface.bInterfaceNumber;
+ if (unionDes->common.bLength == 0x00) /* the descriptor data is wrong */
+ {
+ return kStatus_USB_Error;
+ }
+ unionDes = (usb_descriptor_union_t *)((uint32_t)unionDes + unionDes->common.bLength);
+ interfaceParse->interfaceExtension = (uint8_t *)unionDes;
+ while ((uint32_t)unionDes < endPos)
+ {
+ if ((unionDes->common.bDescriptorType != USB_DESCRIPTOR_TYPE_INTERFACE) &&
+ (unionDes->common.bDescriptorType != USB_DESCRIPTOR_TYPE_ENDPOINT))
+ {
+ if ((unionDes->common.bDescriptorType == 0x00) ||
+ (unionDes->common.bLength == 0x00)) /* the descriptor data is wrong */
+ {
+ return kStatus_USB_Error;
+ }
+ interfaceParse->interfaceExtensionLength += unionDes->common.bLength;
+ unionDes = (usb_descriptor_union_t *)((uint32_t)unionDes + unionDes->common.bLength);
+ }
+ else
+ {
+ break;
+ }
+ }
+
+ /* endpoint descriptor */
+ if (interfaceParse->interfaceDesc->bNumEndpoints != 0)
+ {
+ if ((unionDes->common.bDescriptorType != USB_DESCRIPTOR_TYPE_ENDPOINT) ||
+ (interfaceParse->interfaceDesc->bNumEndpoints > USB_HOST_CONFIG_INTERFACE_MAX_EP))
+ {
+#ifdef HOST_ECHO
+ usb_echo("interface descriptor error\n");
+#endif
+ return kStatus_USB_Error;
+ }
+ for (; interfaceParse->epCount < interfaceParse->interfaceDesc->bNumEndpoints;
+ (interfaceParse->epCount)++)
+ {
+ if (((uint32_t)unionDes >= endPos) ||
+ (unionDes->common.bDescriptorType != USB_DESCRIPTOR_TYPE_ENDPOINT))
+ {
+#ifdef HOST_ECHO
+ usb_echo("endpoint descriptor error\n");
+#endif
+ return kStatus_USB_Error;
+ }
+ epParse = (usb_host_ep_t *)&interfaceParse->epList[interfaceParse->epCount];
+ epParse->epDesc = (usb_descriptor_endpoint_t *)unionDes;
+ epParse->epExtensionLength = 0;
+ epParse->epExtension = NULL;
+ if (unionDes->common.bLength == 0x00) /* the descriptor data is wrong */
+ {
+ return kStatus_USB_Error;
+ }
+ interfaceParse->interfaceExtensionLength += unionDes->common.bLength;
+ unionDes = (usb_descriptor_union_t *)((uint32_t)unionDes + unionDes->common.bLength);
+ epParse->epExtension = (uint8_t *)unionDes;
+ while ((uint32_t)unionDes < endPos)
+ {
+ if ((unionDes->common.bDescriptorType != USB_DESCRIPTOR_TYPE_ENDPOINT) &&
+ (unionDes->common.bDescriptorType != USB_DESCRIPTOR_TYPE_INTERFACE))
+ {
+ if ((unionDes->common.bDescriptorType == 0x00) ||
+ (unionDes->common.bLength == 0x00)) /* the descriptor data is wrong */
+ {
+ return kStatus_USB_Error;
+ }
+ epParse->epExtensionLength += unionDes->common.bLength;
+ interfaceParse->interfaceExtensionLength += unionDes->common.bLength;
+ unionDes =
+ (usb_descriptor_union_t *)((uint32_t)unionDes + unionDes->common.bLength);
+ }
+ else
+ {
+ break;
+ }
+ }
+ }
+ }
+ }
+ else
+ {
+ if (interfaceParse == NULL)
+ {
+ return kStatus_USB_Error; /* in normal situation this cannot reach */
+ }
+ interfaceParse->alternateSettingNumber++;
+ if (unionDes->common.bLength == 0x00) /* the descriptor data is wrong */
+ {
+ return kStatus_USB_Error;
+ }
+ interfaceParse->interfaceExtensionLength += unionDes->common.bLength;
+ unionDes = (usb_descriptor_union_t *)((uint32_t)unionDes + unionDes->common.bLength);
+ while ((uint32_t)unionDes < endPos)
+ {
+ if (unionDes->common.bDescriptorType != USB_DESCRIPTOR_TYPE_INTERFACE)
+ {
+ if ((unionDes->common.bDescriptorType == 0x00) ||
+ (unionDes->common.bLength == 0x00)) /* the descriptor data is wrong */
+ {
+ return kStatus_USB_Error;
+ }
+ interfaceParse->interfaceExtensionLength += unionDes->common.bLength;
+ unionDes = (usb_descriptor_union_t *)((uint32_t)unionDes + unionDes->common.bLength);
+ }
+ else
+ {
+ break;
+ }
+ }
+ }
+ }
+ else
+ {
+ return kStatus_USB_Error;
+ }
+ }
+ }
+
+ for (endPos = 0; endPos < deviceInstance->configuration.interfaceCount; ++endPos)
+ {
+ deviceInstance->interfaceStatus[endPos] = kStatus_interface_Attached;
+ }
+
+ return kStatus_USB_Success;
+}
+
+usb_status_t USB_HostAttachDevice(usb_host_handle hostHandle,
+ uint8_t speed,
+ uint8_t hubNumber,
+ uint8_t portNumber,
+ uint8_t level,
+ usb_device_handle *deviceHandle)
+{
+ usb_host_instance_t *hostInstance = (usb_host_instance_t *)hostHandle;
+ usb_host_device_instance_t *newInstance;
+#if ((defined USB_HOST_CONFIG_HUB) && (USB_HOST_CONFIG_HUB))
+ usb_host_device_instance_t *currentInstance;
+#endif
+ uint8_t address;
+ usb_host_pipe_init_t pipeInit;
+
+ if (hostHandle == NULL)
+ {
+ return kStatus_USB_InvalidHandle;
+ }
+
+/* check whether is the device attached? */
+#if ((defined USB_HOST_CONFIG_HUB) && (USB_HOST_CONFIG_HUB))
+ currentInstance = (usb_host_device_instance_t *)hostInstance->deviceList;
+ while (currentInstance != NULL)
+ {
+ if ((currentInstance->hubNumber == hubNumber) && (currentInstance->portNumber == portNumber))
+ {
+ *deviceHandle = NULL;
+#ifdef HOST_ECHO
+ usb_echo("device has attached\r\n");
+#endif
+ return kStatus_USB_Busy;
+ }
+ else
+ {
+ currentInstance = currentInstance->next;
+ }
+ }
+#else
+ if (hostInstance->deviceList != NULL)
+ {
+ *deviceHandle = NULL;
+ usb_echo("device has attached\r\n");
+ return kStatus_USB_Busy;
+ }
+#endif
+
+ /* Allocate new device instance */
+ newInstance = (usb_host_device_instance_t *)USB_OsaMemoryAllocate(sizeof(usb_host_device_instance_t));
+ if (newInstance == NULL)
+ {
+#ifdef HOST_ECHO
+ usb_echo("allocate dev instance fail\r\n");
+#endif
+ return kStatus_USB_AllocFail;
+ }
+
+ /* new instance fields init */
+ newInstance->hostHandle = hostHandle;
+ newInstance->speed = speed;
+ newInstance->stallRetries = USB_HOST_CONFIG_ENUMERATION_MAX_STALL_RETRIES;
+ newInstance->enumRetries = USB_HOST_CONFIG_ENUMERATION_MAX_RETRIES;
+ newInstance->setAddress = 0;
+ newInstance->deviceAttachState = kStatus_device_Attached;
+
+#if ((defined USB_HOST_CONFIG_HUB) && (USB_HOST_CONFIG_HUB))
+ newInstance->hubNumber = hubNumber;
+ newInstance->portNumber = portNumber;
+ newInstance->level = level;
+
+ if ((speed != USB_SPEED_HIGH) && (level > 1))
+ {
+ newInstance->hsHubNumber = USB_HostHubGetHsHubNumber(hubNumber);
+ newInstance->hsHubPort = USB_HostHubGetHsHubPort(hubNumber, portNumber);
+ }
+ else
+ {
+ newInstance->hsHubNumber = hubNumber;
+ newInstance->hsHubPort = portNumber;
+ }
+#endif /* USB_HOST_CONFIG_HUB */
+
+ USB_HostLock();
+ /* allocate address && insert to the dev list */
+ address = USB_HostAllocateDeviceAddress(hostInstance);
+ if (address == 0)
+ {
+#ifdef HOST_ECHO
+ usb_echo("allocate address fail\r\n");
+#endif
+ USB_HostUnlock();
+ USB_OsaMemoryFree(newInstance);
+ return kStatus_USB_Error;
+ }
+ newInstance->allocatedAddress = address;
+
+ newInstance->next = (usb_host_device_instance_t *)hostInstance->deviceList;
+ hostInstance->deviceList = newInstance;
+ newInstance->state = kStatus_DEV_Initial;
+ USB_HostUnlock();
+
+ /* open control pipe */
+ pipeInit.devInstance = newInstance;
+ pipeInit.pipeType = USB_ENDPOINT_CONTROL;
+ pipeInit.direction = 0;
+ pipeInit.endpointAddress = 0;
+ pipeInit.interval = 0;
+ pipeInit.maxPacketSize = 8;
+ pipeInit.numberPerUframe = 0;
+ pipeInit.nakCount = USB_HOST_CONFIG_MAX_NAK;
+ if (USB_HostOpenPipe(hostHandle, &newInstance->controlPipe, &pipeInit) != kStatus_USB_Success)
+ {
+ /* don't need release resource, resource is released when detach */
+ *deviceHandle = newInstance;
+ return kStatus_USB_Error;
+ }
+
+ /* start enumeration */
+ newInstance->state = kStatus_DEV_GetDes8;
+ USB_HostProcessState(newInstance); /* process enumeration state machine */
+
+ *deviceHandle = newInstance;
+ return kStatus_USB_Success;
+}
+
+usb_status_t USB_HostDetachDevice(usb_host_handle hostHandle, uint8_t hubNumber, uint8_t portNumber)
+{
+ usb_host_device_instance_t *deviceInstance;
+ usb_host_instance_t *hostInstance = (usb_host_instance_t *)hostHandle;
+
+ if (hostHandle == NULL)
+ {
+ return kStatus_USB_InvalidHandle;
+ }
+
+ USB_HostLock();
+/* search for device instance handle */
+#if ((defined USB_HOST_CONFIG_HUB) && (USB_HOST_CONFIG_HUB))
+ deviceInstance = (usb_host_device_instance_t *)hostInstance->deviceList;
+ while (deviceInstance != NULL)
+ {
+ if ((deviceInstance->hubNumber == hubNumber) && (deviceInstance->portNumber == portNumber))
+ {
+ break;
+ }
+ deviceInstance = deviceInstance->next;
+ }
+#else
+ deviceInstance = (usb_host_device_instance_t *)hostInstance->deviceList;
+#endif
+ USB_HostUnlock();
+ if (deviceInstance != NULL)
+ {
+ return USB_HostDetachDeviceInternal(hostHandle, deviceInstance); /* device instance detach */
+ }
+ return kStatus_USB_Success;
+}
+
+usb_status_t USB_HostDetachDeviceInternal(usb_host_handle hostHandle, usb_device_handle deviceHandle)
+{
+ usb_host_device_instance_t *deviceInstance = (usb_host_device_instance_t *)deviceHandle;
+ usb_host_instance_t *hostInstance = (usb_host_instance_t *)hostHandle;
+ if ((hostHandle == NULL) || (deviceHandle == NULL))
+ {
+ return kStatus_USB_InvalidHandle;
+ }
+
+ deviceInstance->deviceAttachState = kStatus_device_Detached; /* mark the device is detached from host */
+
+ if (deviceInstance->state >= kStatus_DEV_Initial) /* device instance is valid */
+ {
+ /* detach internally */
+ if (deviceInstance->state < kStatus_DEV_AppUsed) /* enumeration is not done */
+ {
+ if (deviceInstance->controlPipe != NULL)
+ {
+ USB_HostCancelTransfer(hostInstance, deviceInstance->controlPipe, NULL);
+ }
+
+ /* remove device instance from host */
+ USB_HostRemoveDeviceInstance(hostInstance, deviceInstance);
+ USB_HostReleaseDeviceResource(hostInstance, deviceInstance);
+ }
+ else /* enumeration has be done and notifed application */
+ {
+ USB_HostNotifyDevice(deviceInstance, kUSB_HostEventDetach); /* notify application device detach */
+ }
+ }
+
+ return kStatus_USB_Success;
+}
+
+uint8_t USB_HostGetDeviceAttachState(usb_device_handle deviceHandle)
+{
+ return deviceHandle ? ((usb_host_device_instance_t *)deviceHandle)->deviceAttachState : 0x0;
+}
+
+usb_status_t USB_HostValidateDevice(usb_host_handle hostHandle, usb_device_handle deviceHandle)
+{
+ usb_host_device_instance_t *searchDev;
+
+ if (deviceHandle == NULL)
+ {
+ return kStatus_USB_InvalidParameter;
+ }
+ /* search for the device */
+ searchDev = (usb_host_device_instance_t *)((usb_host_instance_t *)hostHandle)->deviceList;
+ while ((searchDev != NULL) && ((usb_device_handle)searchDev != deviceHandle))
+ {
+ searchDev = searchDev->next;
+ }
+
+ if (searchDev)
+ {
+ return kStatus_USB_Success;
+ }
+ return kStatus_USB_Error;
+}
+
+static usb_status_t USB_HostControlBus(usb_host_handle hostHandle, uint8_t controlType)
+{
+ usb_status_t status = kStatus_USB_Success;
+ usb_host_instance_t *hostInstance = (usb_host_instance_t *)hostHandle;
+
+ if (hostHandle == NULL)
+ {
+ return kStatus_USB_InvalidHandle;
+ }
+
+ status = hostInstance->controllerTable->controllerIoctl(hostInstance->controllerHandle, kUSB_HostBusControl,
+ &controlType);
+
+ return status;
+}
+
+usb_status_t USB_HostOpenDeviceInterface(usb_device_handle deviceHandle, usb_host_interface_handle interfaceHandle)
+{
+ usb_host_device_instance_t *deviceInstance = (usb_host_device_instance_t *)deviceHandle;
+ usb_host_instance_t *hostInstance = NULL;
+ uint8_t interfaceIndex;
+ uint8_t index = 0;
+
+ if ((deviceHandle == NULL) || (interfaceHandle == NULL))
+ {
+ return kStatus_USB_InvalidHandle;
+ }
+
+ hostInstance = (usb_host_instance_t *)deviceInstance->hostHandle;
+ USB_HostLock();
+ /* check host_instance valid? */
+ for (; index < USB_HOST_CONFIG_MAX_HOST; ++index)
+ {
+ if ((g_UsbHostInstance[index].occupied == 1) &&
+ ((usb_host_instance_t *)(&g_UsbHostInstance[index]) == (hostInstance)))
+ {
+ break;
+ }
+ }
+ if (index >= USB_HOST_CONFIG_MAX_HOST)
+ {
+ USB_HostUnlock();
+ return kStatus_USB_Error;
+ }
+
+ /* check deviceHandle valid? */
+ if (USB_HostValidateDevice(hostInstance, deviceHandle) != kStatus_USB_Success)
+ {
+ USB_HostUnlock();
+ return kStatus_USB_Error;
+ }
+
+ /* search interface and set the interface as opened */
+ for (interfaceIndex = 0; interfaceIndex < deviceInstance->configuration.interfaceCount; ++interfaceIndex)
+ {
+ if (&deviceInstance->configuration.interfaceList[interfaceIndex] == interfaceHandle)
+ {
+ deviceInstance->interfaceStatus[interfaceIndex] = kStatus_interface_Opened;
+ break;
+ }
+ }
+ USB_HostUnlock();
+
+ return kStatus_USB_Success;
+}
+
+usb_status_t USB_HostCloseDeviceInterface(usb_device_handle deviceHandle, usb_host_interface_handle interfaceHandle)
+{
+ usb_host_device_instance_t *deviceInstance = (usb_host_device_instance_t *)deviceHandle;
+ usb_host_instance_t *hostInstance = NULL;
+ uint8_t interfaceIndex;
+ uint8_t removeLabel = 1;
+ uint8_t index = 0;
+
+ if (deviceHandle == NULL)
+ {
+ return kStatus_USB_InvalidHandle;
+ }
+
+ hostInstance = (usb_host_instance_t *)deviceInstance->hostHandle;
+ USB_HostLock();
+ /* check host_instance valid? */
+ for (; index < USB_HOST_CONFIG_MAX_HOST; ++index)
+ {
+ if ((g_UsbHostInstance[index].occupied == 1) &&
+ ((usb_host_instance_t *)(&g_UsbHostInstance[index]) == (hostInstance)))
+ {
+ break;
+ }
+ }
+ if (index >= USB_HOST_CONFIG_MAX_HOST)
+ {
+ USB_HostUnlock();
+ return kStatus_USB_Error;
+ }
+
+ /* check deviceHandle valid? */
+ if (USB_HostValidateDevice(hostInstance, deviceHandle) != kStatus_USB_Success)
+ {
+ USB_HostUnlock();
+ return kStatus_USB_Error;
+ }
+
+ if (interfaceHandle != NULL)
+ {
+ /* search interface and set the interface as detached */
+ for (interfaceIndex = 0; interfaceIndex < deviceInstance->configuration.interfaceCount; ++interfaceIndex)
+ {
+ if (&deviceInstance->configuration.interfaceList[interfaceIndex] == interfaceHandle)
+ {
+ deviceInstance->interfaceStatus[interfaceIndex] = kStatus_interface_Detached;
+ break;
+ }
+ }
+ }
+
+ if (deviceInstance->deviceAttachState == kStatus_device_Detached) /* device is removed from host */
+ {
+ removeLabel = 1;
+ /* check all the interfaces of the device are not opened */
+ for (interfaceIndex = 0; interfaceIndex < deviceInstance->configuration.interfaceCount; ++interfaceIndex)
+ {
+ if (deviceInstance->interfaceStatus[interfaceIndex] == kStatus_interface_Opened)
+ {
+ removeLabel = 0;
+ break;
+ }
+ }
+ if (removeLabel == 1)
+ {
+ /* remove device instance from host */
+ USB_HostRemoveDeviceInstance(hostInstance, deviceInstance);
+ }
+ USB_HostUnlock();
+
+ if (removeLabel == 1)
+ {
+ USB_HostReleaseDeviceResource((usb_host_instance_t *)deviceInstance->hostHandle,
+ deviceInstance); /* release device resource */
+ }
+ }
+ else
+ {
+ USB_HostUnlock();
+ }
+
+ return kStatus_USB_Success;
+}
+
+usb_status_t USB_HostRemoveDevice(usb_host_handle hostHandle, usb_device_handle deviceHandle)
+{
+ usb_host_instance_t *hostInstance = (usb_host_instance_t *)hostHandle;
+ usb_host_device_instance_t *deviceInstance = (usb_host_device_instance_t *)deviceHandle;
+ uint8_t interfaceIndex = 0;
+#if ((defined USB_HOST_CONFIG_HUB) && (USB_HOST_CONFIG_HUB))
+ uint8_t level = 0;
+ uint8_t devHubNo;
+ uint8_t devPortNo;
+#endif
+
+ if ((hostHandle == NULL) || (deviceHandle == NULL))
+ {
+ return kStatus_USB_InvalidHandle;
+ }
+ if (deviceInstance->hostHandle != hostHandle)
+ {
+ return kStatus_USB_InvalidParameter;
+ }
+
+ if (USB_HostValidateDevice(hostInstance, deviceInstance) == kStatus_USB_Success) /* device is valid */
+ {
+#if ((defined USB_HOST_CONFIG_HUB) && (USB_HOST_CONFIG_HUB))
+ devHubNo = deviceInstance->hubNumber;
+ devPortNo = deviceInstance->portNumber;
+ level = deviceInstance->level;
+#endif
+
+ deviceInstance->deviceAttachState = kStatus_device_Detached;
+ if (deviceInstance->state >= kStatus_DEV_Initial) /* device is valid */
+ {
+ if (deviceInstance->state < kStatus_DEV_AppUsed) /* enumeraion is not done or application don't use */
+ {
+ /* detach internally */
+ USB_HostDetachDeviceInternal(hostHandle, deviceHandle);
+ }
+ else /* application use the device */
+ {
+ for (interfaceIndex = 0; interfaceIndex < deviceInstance->configuration.interfaceCount;
+ ++interfaceIndex)
+ {
+ if (deviceInstance->interfaceStatus[interfaceIndex] == kStatus_interface_Opened)
+ {
+#ifdef HOST_ECHO
+ usb_echo("error: there is class instance that is not deinited\r\n");
+#endif
+ break;
+ }
+ }
+ /* remove device instance from host */
+ USB_HostRemoveDeviceInstance(hostInstance, deviceInstance);
+ USB_HostReleaseDeviceResource(hostInstance, deviceInstance); /* release resource */
+ }
+ }
+
+#if ((defined USB_HOST_CONFIG_HUB) && (USB_HOST_CONFIG_HUB))
+ if (level == 1)
+ {
+ USB_HostControlBus(hostHandle, kUSB_HostBusReset); /* reset controller port */
+ USB_HostControlBus(hostHandle, kUSB_HostBusRestart); /* restart controller port */
+ }
+ else
+ {
+ USB_HostHubRemovePort(devHubNo, devPortNo); /* reset hub port */
+ }
+#else
+ USB_HostControlBus(hostHandle, kUSB_HostBusReset); /* reset controller port */
+ USB_HostControlBus(hostHandle, kUSB_HostBusRestart); /* restart controller port */
+#endif /* USB_HOST_CONFIG_HUB */
+ }
+
+ return kStatus_USB_Success;
+}
diff --git a/usb_1.1.0/host/usb_host_devices.h b/usb_1.1.0/host/usb_host_devices.h
new file mode 100644
index 0000000..6dd0f31
--- /dev/null
+++ b/usb_1.1.0/host/usb_host_devices.h
@@ -0,0 +1,178 @@
+/*
+ * Copyright (c) 2015, Freescale Semiconductor, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * o Redistributions of source code must retain the above copyright notice, this list
+ * of conditions and the following disclaimer.
+ *
+ * o Redistributions in binary form must reproduce the above copyright notice, this
+ * list of conditions and the following disclaimer in the documentation and/or
+ * other materials provided with the distribution.
+ *
+ * o Neither the name of Freescale Semiconductor, Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _USB_HOST_DEV_MNG_H_
+#define _USB_HOST_DEV_MNG_H_
+
+#include "usb_host.h"
+
+/*******************************************************************************
+ * Definitions
+ ******************************************************************************/
+/*!
+ * @addtogroup usb_host_drv
+ * @{
+ */
+/*! @brief States of device instances enumeration */
+typedef enum _usb_host_device_enumeration_status
+{
+ kStatus_DEV_Notinit = 0, /*!< Device is invalid */
+ kStatus_DEV_Initial, /*!< Device has been processed by host driver */
+ kStatus_DEV_GetDes8, /*!< Enumeration process: get 8 bytes' device descriptor */
+ kStatus_DEV_SetAddress, /*!< Enumeration process: set device address */
+ kStatus_DEV_GetDes, /*!< Enumeration process: get device descriptor */
+ kStatus_DEV_GetCfg9, /*!< Enumeration process: get 9 bytes' configuration descriptor */
+ kStatus_DEV_GetCfg, /*!< Enumeration process: get configuration descriptor */
+ kStatus_DEV_SetCfg, /*!< Enumeration process: set configuration */
+ kStatus_DEV_EnumDone, /*!< Enumeration is done */
+ kStatus_DEV_AppUsed, /*!< This device has been used by application */
+} usb_host_device_enumeration_status_t;
+
+/*! @brief States of device's interface */
+typedef enum _usb_host_interface_state
+{
+ kStatus_interface_Attached = 1, /*!< Interface's default status */
+ kStatus_interface_Opened, /*!< Interface is used by application */
+ kStatus_interface_Detached, /*!< Interface is not used by application */
+} usb_host_interface_state_t;
+
+/*! @brief States of device */
+typedef enum _usb_host_device_state
+{
+ kStatus_device_Detached = 0, /*!< Device is used by application */
+ kStatus_device_Attached, /*!< Device's default status */
+} usb_host_device_state_t;
+
+/*! @brief Device instance */
+typedef struct _usb_host_device_instance
+{
+ struct _usb_host_device_instance *next; /*!< Next device, or NULL */
+ usb_host_handle hostHandle; /*!< Host handle */
+ usb_host_configuration_t configuration; /*!< Parsed configuration information for the device */
+ usb_descriptor_device_t deviceDescriptor; /*!< Standard device descriptor */
+ usb_host_pipe_handle controlPipe; /*!< Device's control pipe */
+ uint8_t *configurationDesc; /*!< Configuration descriptor pointer */
+ uint16_t configurationLen; /*!< Configuration descriptor length */
+ uint16_t configurationValue; /*!< Configuration index */
+ uint8_t interfaceStatus[USB_HOST_CONFIG_CONFIGURATION_MAX_INTERFACE]; /*!< Interfaces' status, please reference to
+ #usb_host_interface_state_t */
+ uint8_t enumBuffer[9]; /*!< Buffer for enumeration */
+ uint8_t state; /*!< Device state for enumeration */
+ uint8_t enumRetries; /*!< Re-enumeration when error in control transfer */
+ uint8_t stallRetries; /*!< Re-transfer when stall */
+ uint8_t speed; /*!< Device speed */
+ uint8_t allocatedAddress; /*!< Temporary address for the device. When set address request succeeds, setAddress is
+ a value, 1 - 127 */
+ uint8_t setAddress; /*!< The address has been set to the device successfully, 1 - 127 */
+ uint8_t deviceAttachState; /*!< See the usb_host_device_state_t */
+#if ((defined USB_HOST_CONFIG_HUB) && (USB_HOST_CONFIG_HUB))
+ /* hub related */
+ uint8_t hubNumber; /*!< Device's first connected hub address (root hub = 0) */
+ uint8_t portNumber; /*!< Device's first connected hub's port no (1 - 8) */
+ uint8_t hsHubNumber; /*!< Device's first connected high-speed hub's address (1 - 8) */
+ uint8_t hsHubPort; /*!< Device's first connected high-speed hub's port no (1 - 8) */
+ uint8_t level; /*!< Device's level (root device = 0) */
+#endif
+} usb_host_device_instance_t;
+
+typedef struct _usb_host_enum_process_entry
+{
+ uint8_t successState; /*!< When the last step is successful, the next state value */
+ uint8_t retryState; /*!< When the last step need retry, the next state value */
+ usb_status_t (*process)(usb_host_device_instance_t *deviceInstance); /*!< When the last step transfer is done, the
+ function is used to process the transfer
+ data */
+} usb_host_enum_process_entry_t;
+
+/*******************************************************************************
+ * API
+ ******************************************************************************/
+
+/*!
+ * @brief Calls this function when device attach.
+ *
+ * @param hostHandle Host instance handle.
+ * @param speed Device speed.
+ * @param hubNumber Device hub no. root device's hub no. is 0.
+ * @param portNumber Device port no. root device's port no. is 0.
+ * @param level Device level. root device's level is 1.
+ * @param deviceHandle Return device handle.
+ *
+ * @return kStatus_USB_Success or error codes.
+ */
+extern usb_status_t USB_HostAttachDevice(usb_host_handle hostHandle,
+ uint8_t speed,
+ uint8_t hubNumber,
+ uint8_t portNumber,
+ uint8_t level,
+ usb_device_handle *deviceHandle);
+
+/*!
+ * @brief Call this function when device detaches.
+ *
+ * @param hostHandle Host instance handle.
+ * @param hubNumber Device hub no. root device's hub no. is 0.
+ * @param portNumber Device port no. root device's port no. is 0.
+ *
+ * @return kStatus_USB_Success or error codes.
+ */
+extern usb_status_t USB_HostDetachDevice(usb_host_handle hostHandle, uint8_t hubNumber, uint8_t portNumber);
+
+/*!
+ * @brief Call this function when device detaches.
+ *
+ * @param hostHandle Host instance handle.
+ * @param deviceHandle Device handle.
+ *
+ * @return kStatus_USB_Success or error codes.
+ */
+extern usb_status_t USB_HostDetachDeviceInternal(usb_host_handle hostHandle, usb_device_handle deviceHandle);
+
+/*!
+ * @brief Gets the the device attach/detach state.
+ *
+ * @param deviceHandle Device handle.
+ *
+ * @return 0x01 - attached; 0x00 - detached.
+ */
+extern uint8_t USB_HostGetDeviceAttachState(usb_device_handle deviceHandle);
+
+/*!
+ * @brief Determine whether the device is attached.
+ *
+ * @param hostHandle Host instance pointer.
+ * @param deviceHandle Device handle.
+ *
+ * @return kStatus_USB_Success or error codes.
+ */
+extern usb_status_t USB_HostValidateDevice(usb_host_handle hostHandle, usb_device_handle deviceHandle);
+
+/*! @}*/
+#endif /* _USB_HOST_DEV_MNG_H_ */
diff --git a/usb_1.1.0/host/usb_host_framework.c b/usb_1.1.0/host/usb_host_framework.c
new file mode 100644
index 0000000..438f0f3
--- /dev/null
+++ b/usb_1.1.0/host/usb_host_framework.c
@@ -0,0 +1,377 @@
+/*
+ * Copyright (c) 2015 - 2016, Freescale Semiconductor, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * o Redistributions of source code must retain the above copyright notice, this list
+ * of conditions and the following disclaimer.
+ *
+ * o Redistributions in binary form must reproduce the above copyright notice, this
+ * list of conditions and the following disclaimer in the documentation and/or
+ * other materials provided with the distribution.
+ *
+ * o Neither the name of Freescale Semiconductor, Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "usb_host_config.h"
+#include "usb_host.h"
+#include "usb_host_hci.h"
+#include "usb_host_devices.h"
+
+/*******************************************************************************
+ * Definitions
+ ******************************************************************************/
+
+/*!
+ * @brief standard control transfer common code.
+ *
+ * @param deviceInstance device instance handle.
+ * @param transfer transfer.
+ * @param buffer data buffer pointer.
+ * @param bufferLen data length.
+ *
+ * @return kStatus_USB_Success or error codes.
+ */
+usb_status_t USB_HostCh9RequestCommon(usb_host_device_instance_t *deviceInstance,
+ usb_host_transfer_t *transfer,
+ uint8_t *buffer,
+ uint32_t bufferLen);
+
+/*!
+ * @brief standard get status implementation.
+ *
+ * @param deviceInstance device instance handle.
+ * @param transfer transfer.
+ * @param param parameter.
+ *
+ * @return kStatus_USB_Success or error codes.
+ */
+usb_status_t USB_HostStandardGetStatus(usb_host_device_instance_t *deviceInstance,
+ usb_host_transfer_t *transfer,
+ void *param);
+
+/*!
+ * @brief standard set/clear feature implementation.
+ *
+ * @param deviceInstance device instance handle.
+ * @param transfer transfer.
+ * @param param parameter.
+ *
+ * @return kStatus_USB_Success or error codes.
+ */
+usb_status_t USB_HostStandardSetClearFeature(usb_host_device_instance_t *deviceInstance,
+ usb_host_transfer_t *transfer,
+ void *param);
+
+/*!
+ * @brief standard set address implementation.
+ *
+ * @param deviceInstance device instance handle.
+ * @param transfer transfer.
+ * @param param parameter.
+ *
+ * @return kStatus_USB_Success or error codes.
+ */
+usb_status_t USB_HostStandardSetAddress(usb_host_device_instance_t *deviceInstance,
+ usb_host_transfer_t *transfer,
+ void *param);
+
+/*!
+ * @brief standard set/get descriptor implementation.
+ *
+ * @param deviceInstance device instance handle.
+ * @param transfer transfer.
+ * @param param parameter.
+ *
+ * @return kStatus_USB_Success or error codes.
+ */
+usb_status_t USB_HostStandardSetGetDescriptor(usb_host_device_instance_t *deviceInstance,
+ usb_host_transfer_t *transfer,
+ void *param);
+
+/*!
+ * @brief standard get interface implementation.
+ *
+ * @param deviceInstance device instance handle.
+ * @param transfer transfer.
+ * @param param parameter.
+ *
+ * @return kStatus_USB_Success or error codes.
+ */
+usb_status_t USB_HostStandardGetInterface(usb_host_device_instance_t *deviceInstance,
+ usb_host_transfer_t *transfer,
+ void *param);
+
+/*!
+ * @brief standard set interface implementation.
+ *
+ * @param deviceInstance device instance handle.
+ * @param transfer transfer.
+ * @param param parameter.
+ *
+ * @return kStatus_USB_Success or error codes.
+ */
+usb_status_t USB_HostStandardSetInterface(usb_host_device_instance_t *deviceInstance,
+ usb_host_transfer_t *transfer,
+ void *param);
+
+/*!
+ * @brief standard sync frame implementation.
+ *
+ * @param deviceInstance device instance handle.
+ * @param transfer transfer.
+ * @param param parameter.
+ *
+ * @return kStatus_USB_Success or error codes.
+ */
+usb_status_t USB_HostStandardSyncFrame(usb_host_device_instance_t *deviceInstance,
+ usb_host_transfer_t *transfer,
+ void *param);
+
+/*******************************************************************************
+ * Prototypes
+ ******************************************************************************/
+
+/*******************************************************************************
+ * Variables
+ ******************************************************************************/
+
+/*******************************************************************************
+ * Code
+ ******************************************************************************/
+
+usb_status_t USB_HostCh9RequestCommon(usb_host_device_instance_t *deviceInstance,
+ usb_host_transfer_t *transfer,
+ uint8_t *buffer,
+ uint32_t bufferLen)
+{
+ /* initialize transfer */
+ transfer->setupPacket.wLength = USB_SHORT_TO_LITTLE_ENDIAN(bufferLen);
+ transfer->transferBuffer = buffer;
+ transfer->transferLength = bufferLen;
+
+ if (USB_HostSendSetup(deviceInstance->hostHandle, deviceInstance->controlPipe, transfer) !=
+ kStatus_USB_Success) /* send setup transfer */
+ {
+#ifdef HOST_ECHO
+ usb_echo("failt for USB_HostSendSetup\r\n");
+#endif
+ USB_HostFreeTransfer(deviceInstance->hostHandle, transfer);
+ return kStatus_USB_Error;
+ }
+ return kStatus_USB_Success;
+}
+
+usb_status_t USB_HostStandardGetStatus(usb_host_device_instance_t *deviceInstance,
+ usb_host_transfer_t *transfer,
+ void *param)
+{
+ usb_host_get_status_param_t *statusParam;
+
+ /* initialize transfer */
+ statusParam = (usb_host_get_status_param_t *)param;
+ transfer->setupPacket.bmRequestType = USB_REQUEST_TYPE_DIR_IN | USB_REQUEST_TYPE_TYPE_STANDARD;
+ if (statusParam->requestType == kRequestDevice)
+ {
+ transfer->setupPacket.bmRequestType |= USB_REQUEST_TYPE_RECIPIENT_DEVICE;
+ }
+ else if (statusParam->requestType == kRequestInterface)
+ {
+ transfer->setupPacket.bmRequestType |= USB_REQUEST_TYPE_RECIPIENT_INTERFACE;
+ }
+ else
+ {
+ transfer->setupPacket.bmRequestType |= USB_REQUEST_TYPE_RECIPIENT_ENDPOINT;
+ }
+ transfer->setupPacket.wIndex = USB_SHORT_TO_LITTLE_ENDIAN(statusParam->interfaceOrEndpoint);
+
+ return USB_HostCh9RequestCommon(deviceInstance, transfer, statusParam->statusBuffer, 2);
+}
+
+usb_status_t USB_HostStandardSetClearFeature(usb_host_device_instance_t *deviceInstance,
+ usb_host_transfer_t *transfer,
+ void *param)
+{
+ usb_host_process_feature_param_t *featureParam;
+
+ /* initialize transfer */
+ featureParam = (usb_host_process_feature_param_t *)param;
+ if (featureParam->requestType == kRequestDevice)
+ {
+ transfer->setupPacket.bmRequestType |= USB_REQUEST_TYPE_RECIPIENT_DEVICE;
+ }
+ else if (featureParam->requestType == kRequestInterface)
+ {
+ transfer->setupPacket.bmRequestType |= USB_REQUEST_TYPE_RECIPIENT_INTERFACE;
+ }
+ else
+ {
+ transfer->setupPacket.bmRequestType |= USB_REQUEST_TYPE_RECIPIENT_ENDPOINT;
+ }
+ transfer->setupPacket.wValue = USB_SHORT_TO_LITTLE_ENDIAN(featureParam->featureSelector);
+ transfer->setupPacket.wIndex = USB_SHORT_TO_LITTLE_ENDIAN(featureParam->interfaceOrEndpoint);
+
+ return USB_HostCh9RequestCommon(deviceInstance, transfer, NULL, 0);
+}
+
+usb_status_t USB_HostStandardSetAddress(usb_host_device_instance_t *deviceInstance,
+ usb_host_transfer_t *transfer,
+ void *param)
+{
+ uint8_t address;
+
+ /* initialize transfer */
+ address = *(uint8_t *)param;
+ transfer->setupPacket.wValue = USB_SHORT_TO_LITTLE_ENDIAN(address);
+
+ return USB_HostCh9RequestCommon(deviceInstance, transfer, NULL, 0);
+}
+
+usb_status_t USB_HostStandardSetGetDescriptor(usb_host_device_instance_t *deviceInstance,
+ usb_host_transfer_t *transfer,
+ void *param)
+{
+ usb_host_process_descriptor_param_t *descriptorParam;
+
+ /* initialize transfer */
+ descriptorParam = (usb_host_process_descriptor_param_t *)param;
+ transfer->setupPacket.wValue =
+ ((uint16_t)((uint16_t)descriptorParam->descriptorType << 8) | descriptorParam->descriptorIndex);
+ transfer->setupPacket.wIndex = USB_SHORT_TO_LITTLE_ENDIAN(descriptorParam->languageId);
+ return USB_HostCh9RequestCommon(deviceInstance, transfer, descriptorParam->descriptorBuffer,
+ descriptorParam->descriptorLength);
+}
+
+usb_status_t USB_HostStandardGetInterface(usb_host_device_instance_t *deviceInstance,
+ usb_host_transfer_t *transfer,
+ void *param)
+{
+ usb_host_get_interface_param_t *interfaceParam;
+
+ /* initialize transfer */
+ interfaceParam = (usb_host_get_interface_param_t *)param;
+ transfer->setupPacket.bmRequestType |= USB_REQUEST_TYPE_DIR_IN;
+ transfer->setupPacket.bmRequestType |= USB_REQUEST_TYPE_RECIPIENT_INTERFACE;
+ transfer->setupPacket.wIndex = USB_SHORT_TO_LITTLE_ENDIAN(interfaceParam->interface);
+
+ return USB_HostCh9RequestCommon(deviceInstance, transfer, interfaceParam->alternateInterfaceBuffer, 1);
+}
+
+usb_status_t USB_HostStandardSetInterface(usb_host_device_instance_t *deviceInstance,
+ usb_host_transfer_t *transfer,
+ void *param)
+{
+ usb_host_set_interface_param_t *setParam;
+
+ /* initialize transfer */
+ setParam = (usb_host_set_interface_param_t *)param;
+ transfer->setupPacket.bmRequestType |= USB_REQUEST_TYPE_RECIPIENT_INTERFACE;
+ transfer->setupPacket.wIndex = USB_SHORT_TO_LITTLE_ENDIAN(setParam->interface);
+ transfer->setupPacket.wValue = USB_SHORT_TO_LITTLE_ENDIAN(setParam->alternateSetting);
+
+ return USB_HostCh9RequestCommon(deviceInstance, transfer, NULL, 0);
+}
+
+usb_status_t USB_HostStandardSyncFrame(usb_host_device_instance_t *deviceInstance,
+ usb_host_transfer_t *transfer,
+ void *param)
+{
+ usb_host_synch_frame_param_t *frameParam;
+
+ /* initialize transfer */
+ frameParam = (usb_host_synch_frame_param_t *)param;
+ transfer->setupPacket.bmRequestType |= USB_REQUEST_TYPE_DIR_IN;
+ transfer->setupPacket.bmRequestType |= USB_REQUEST_TYPE_RECIPIENT_ENDPOINT;
+ transfer->setupPacket.wIndex = USB_SHORT_TO_LITTLE_ENDIAN(frameParam->endpoint);
+
+ return USB_HostCh9RequestCommon(deviceInstance, transfer, frameParam->frameNumberBuffer, 2);
+}
+
+usb_status_t USB_HostRequestControl(usb_device_handle deviceHandle,
+ uint8_t usbRequest,
+ usb_host_transfer_t *transfer,
+ void *param)
+{
+ usb_host_device_instance_t *deviceInstance = (usb_host_device_instance_t *)deviceHandle;
+ usb_status_t status = kStatus_USB_Error;
+
+ if (deviceHandle == NULL)
+ {
+ return kStatus_USB_InvalidHandle;
+ }
+
+ /* reset transfer fields */
+ transfer->setupPacket.bmRequestType = 0x00;
+ transfer->setupPacket.bRequest = usbRequest;
+ transfer->setupPacket.wIndex = 0;
+ transfer->setupPacket.wLength = 0;
+ transfer->setupPacket.wValue = 0;
+
+ switch (usbRequest)
+ {
+ case USB_REQUEST_STANDARD_GET_STATUS: /* standard get status request */
+ status = USB_HostStandardGetStatus(deviceInstance, transfer, param);
+ break;
+
+ case USB_REQUEST_STANDARD_CLEAR_FEATURE: /* standard clear status request */
+ case USB_REQUEST_STANDARD_SET_FEATURE: /* standard set feature request */
+ status = USB_HostStandardSetClearFeature(deviceInstance, transfer, param);
+ break;
+
+ case USB_REQUEST_STANDARD_SET_ADDRESS: /* standard set address request */
+ status = USB_HostStandardSetAddress(deviceInstance, transfer, param);
+ break;
+
+ case USB_REQUEST_STANDARD_GET_DESCRIPTOR: /* standard get descriptor request */
+ case USB_REQUEST_STANDARD_SET_DESCRIPTOR: /* standard set descriptor request */
+ if (usbRequest == USB_REQUEST_STANDARD_GET_DESCRIPTOR)
+ {
+ transfer->setupPacket.bmRequestType |= USB_REQUEST_TYPE_DIR_IN;
+ }
+ status = USB_HostStandardSetGetDescriptor(deviceInstance, transfer, param);
+ break;
+
+ case USB_REQUEST_STANDARD_GET_CONFIGURATION: /* standard get configuration descriptor request */
+ transfer->setupPacket.bmRequestType |= USB_REQUEST_TYPE_DIR_IN;
+ status =
+ USB_HostCh9RequestCommon((usb_host_device_instance_t *)deviceHandle, transfer, (uint8_t *)param, 1);
+ break;
+
+ case USB_REQUEST_STANDARD_SET_CONFIGURATION: /* standard set configuration request */
+ transfer->setupPacket.wValue = USB_SHORT_TO_LITTLE_ENDIAN(*((uint8_t *)param));
+ status = USB_HostCh9RequestCommon((usb_host_device_instance_t *)deviceHandle, transfer, NULL, 0);
+ break;
+
+ case USB_REQUEST_STANDARD_GET_INTERFACE: /* standard get interface request */
+ status = USB_HostStandardGetInterface(deviceInstance, transfer, param);
+ break;
+
+ case USB_REQUEST_STANDARD_SET_INTERFACE: /* standard set interface request */
+ status = USB_HostStandardSetInterface(deviceInstance, transfer, param);
+ break;
+
+ case USB_REQUEST_STANDARD_SYNCH_FRAME: /* standard synch frame request */
+ status = USB_HostStandardSyncFrame(deviceInstance, transfer, param);
+ break;
+
+ default:
+ break;
+ }
+
+ return status;
+}
diff --git a/usb_1.1.0/host/usb_host_framework.h b/usb_1.1.0/host/usb_host_framework.h
new file mode 100644
index 0000000..aeca251
--- /dev/null
+++ b/usb_1.1.0/host/usb_host_framework.h
@@ -0,0 +1,107 @@
+/*
+ * Copyright (c) 2015 - 2016, Freescale Semiconductor, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * o Redistributions of source code must retain the above copyright notice, this list
+ * of conditions and the following disclaimer.
+ *
+ * o Redistributions in binary form must reproduce the above copyright notice, this
+ * list of conditions and the following disclaimer in the documentation and/or
+ * other materials provided with the distribution.
+ *
+ * o Neither the name of Freescale Semiconductor, Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _USB_HOST_CH9_H_
+#define _USB_HOST_CH9_H_
+
+/*******************************************************************************
+ * Definitions
+ ******************************************************************************/
+
+/*!
+ * @addtogroup usb_host_drv
+ * @{
+ */
+
+/*! @brief Request type */
+typedef enum _usb_host_request_type
+{
+ kRequestDevice = 1U, /*!< Control request object is device */
+ kRequestInterface, /*!< Control request object is interface */
+ kRequestEndpoint, /*!< Control request object is endpoint */
+} usb_host_request_type_t;
+
+/*! @brief For USB_REQUEST_STANDARD_CLEAR_FEATURE and USB_REQUEST_STANDARD_SET_FEATURE */
+typedef struct _usb_host_process_feature_param
+{
+ uint8_t requestType; /*!< See the #usb_host_request_type_t */
+ uint8_t featureSelector; /*!< Set/cleared feature */
+ uint8_t interfaceOrEndpoint; /*!< Interface or end pointer */
+} usb_host_process_feature_param_t;
+
+/*! @brief For USB_REQUEST_STANDARD_GET_DESCRIPTOR and USB_REQUEST_STANDARD_SET_DESCRIPTOR */
+typedef struct _usb_host_process_descriptor_param
+{
+ uint8_t descriptorType; /*!< See the usb_spec.h, such as the USB_DESCRIPTOR_TYPE_DEVICE */
+ uint8_t descriptorIndex; /*!< The descriptor index is used to select a specific descriptor (only for configuration
+ and string descriptors) when several descriptors of the same type are implemented in a
+ device */
+ uint8_t languageId; /*!< It specifies the language ID for string descriptors or is reset to zero for other
+ descriptors */
+ uint8_t *descriptorBuffer; /*!< Buffer pointer */
+ uint16_t descriptorLength; /*!< Buffer data length */
+} usb_host_process_descriptor_param_t;
+
+/*! @brief For USB_REQUEST_STANDARD_GET_INTERFACE */
+typedef struct _usb_host_get_interface_param
+{
+ uint8_t interface; /*!< Interface number */
+ uint8_t *alternateInterfaceBuffer; /*!< Save the transfer result */
+} usb_host_get_interface_param_t;
+
+/*! @brief For USB_REQUEST_STANDARD_GET_STATUS */
+typedef struct _usb_host_get_status_param
+{
+ uint8_t requestType; /*!< See the #usb_host_request_type_t */
+ uint8_t interfaceOrEndpoint; /*!< Interface number or the end pointer number */
+ uint8_t *statusBuffer; /*!< Save the transfer result */
+} usb_host_get_status_param_t;
+
+/*! @brief For USB_REQUEST_STANDARD_SET_INTERFACE */
+typedef struct _usb_host_set_interface_param
+{
+ uint8_t alternateSetting; /*!< Alternate setting value */
+ uint8_t interface; /*!< Interface number */
+} usb_host_set_interface_param_t;
+
+/*! @brief For USB_REQUEST_STANDARD_SYNCH_FRAME */
+typedef struct _usb_host_synch_frame_param
+{
+ uint8_t endpoint; /*!< Endpoint number */
+ uint8_t *frameNumberBuffer; /*!< Frame number data buffer */
+} usb_host_synch_frame_param_t;
+
+/*! @}*/
+
+/*******************************************************************************
+ * API
+ ******************************************************************************/
+
+#endif /* _USB_HOST_CH9_H_ */
diff --git a/usb_1.1.0/host/usb_host_hci.c b/usb_1.1.0/host/usb_host_hci.c
new file mode 100644
index 0000000..f50af20
--- /dev/null
+++ b/usb_1.1.0/host/usb_host_hci.c
@@ -0,0 +1,754 @@
+/*
+ * Copyright (c) 2015 - 2016, Freescale Semiconductor, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * o Redistributions of source code must retain the above copyright notice, this list
+ * of conditions and the following disclaimer.
+ *
+ * o Redistributions in binary form must reproduce the above copyright notice, this
+ * list of conditions and the following disclaimer in the documentation and/or
+ * other materials provided with the distribution.
+ *
+ * o Neither the name of Freescale Semiconductor, Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "usb_host_config.h"
+#include "usb_host.h"
+#include "usb_host_hci.h"
+#include "usb_host_devices.h"
+#include "fsl_device_registers.h"
+
+/*******************************************************************************
+ * Definitions
+ ******************************************************************************/
+
+/*******************************************************************************
+ * Prototypes
+ ******************************************************************************/
+extern uint32_t USB_HostHubGetTotalThinkTime(uint8_t parentHubNo);
+
+/*!
+ * @brief get the idle host instance.
+ *
+ * @return host instance pointer.
+ */
+static usb_host_instance_t *USB_HostGetInstance(void);
+
+/*!
+ * @brief release host instance.
+ *
+ * @param hostInstance host instance pointer.
+ */
+static void USB_HostReleaseInstance(usb_host_instance_t *hostInstance);
+
+/*!
+ * @brief get the khci/ehci interface.
+ *
+ * @param controllerId controller id.
+ * @param controllerTable return controller interface structure.
+ */
+static void USB_HostGetControllerInterface(uint8_t controllerId,
+ const usb_host_controller_interface_t **controllerTable);
+
+#if ((defined USB_HOST_CONFIG_EHCI) && (USB_HOST_CONFIG_EHCI))
+#if ((defined USB_HOST_CONFIG_COMPLIANCE_TEST) && (USB_HOST_CONFIG_COMPLIANCE_TEST))
+extern void USB_HostEhciTestModeInit(usb_device_handle devHandle);
+#endif /* USB_HOST_CONFIG_COMPLIANCE_TEST */
+#endif /* USB_HOST_CONFIG_EHCI */
+
+/*******************************************************************************
+ * Variables
+ ******************************************************************************/
+/*! @brief USB host instance resource */
+usb_host_instance_t g_UsbHostInstance[USB_HOST_CONFIG_MAX_HOST];
+
+#if ((defined USB_HOST_CONFIG_EHCI) && (USB_HOST_CONFIG_EHCI))
+#include "usb_host_ehci.h"
+static const usb_host_controller_interface_t s_EhciInterface = \
+{
+ USB_HostEhciCreate, USB_HostEhciDestory, USB_HostEhciOpenPipe, USB_HostEhciClosePipe,
+ USB_HostEhciWritePipe, USB_HostEhciReadpipe, USB_HostEhciIoctl,
+};
+#endif /* USB_HOST_CONFIG_EHCI */
+
+#if ((defined USB_HOST_CONFIG_KHCI) && (USB_HOST_CONFIG_KHCI))
+#include "usb_host_khci.h"
+static const usb_host_controller_interface_t s_KhciInterface = \
+{
+ USB_HostKhciCreate, USB_HostKhciDestory, USB_HostKhciOpenPipe, USB_HostKhciClosePipe,
+ USB_HostKhciWritePipe, USB_HostKhciReadpipe, USB_HostKciIoctl,
+};
+#endif /* USB_HOST_CONFIG_KHCI */
+
+/*******************************************************************************
+ * Code
+ ******************************************************************************/
+
+#if ((defined USB_HOST_CONFIG_COMPLIANCE_TEST) && (USB_HOST_CONFIG_COMPLIANCE_TEST))
+/*FUNCTION*----------------------------------------------------------------
+*
+* Function Name : usb_test_mode_init
+* Returned Value : None
+* Comments :
+* This function is called by common class to initialize the class driver. It
+* is called in response to a select interface call by application
+*
+*END*--------------------------------------------------------------------*/
+usb_status_t USB_HostTestModeInit(usb_device_handle deviceHandle)
+{
+#if ((defined USB_HOST_CONFIG_EHCI) && (USB_HOST_CONFIG_EHCI))
+ usb_host_device_instance_t *deviceInstance = (usb_host_device_instance_t *)deviceHandle;
+ usb_host_instance_t *hostInstance = (usb_host_instance_t *)deviceInstance->hostHandle;
+#endif
+ uint32_t productId;
+ uint32_t vendorId;
+
+ usb_echo("usb host test init\r\n");
+ USB_HostHelperGetPeripheralInformation(deviceHandle, kUSB_HostGetDevicePID, &productId);
+ USB_HostHelperGetPeripheralInformation(deviceHandle, kUSB_HostGetDeviceVID, &vendorId);
+ usb_echo(" vendor id :0x%x product id:0x%x \r\n", vendorId, productId);
+
+ if ((productId != 0x0200U) && (productId != 0x0101) && (productId != 0x0102) && (productId != 0x0103) &&
+ (productId != 0x0104) && (productId != 0x0105) && (productId != 0x0106) && (productId != 0x0107) &&
+ (productId != 0x0108))
+ {
+ usb_echo("Unsupported Device\r\n");
+ }
+
+ if (productId == 0x0200U)
+ {
+ usb_echo("PET test device attached\r\n");
+ }
+ else
+ {
+#if ((defined USB_HOST_CONFIG_EHCI) && (USB_HOST_CONFIG_EHCI))
+ if (hostInstance->controllerTable == &s_EhciInterface)
+ {
+ USB_HostEhciTestModeInit(deviceHandle);
+ }
+#endif
+ }
+
+ return kStatus_USB_Success;
+}
+#endif
+
+static usb_host_instance_t *USB_HostGetInstance(void)
+{
+ uint8_t i = 0;
+ USB_OSA_SR_ALLOC();
+ USB_OSA_ENTER_CRITICAL();
+ for (; i < USB_HOST_CONFIG_MAX_HOST; i++)
+ {
+ if (g_UsbHostInstance[i].occupied != 1)
+ {
+ uint8_t *buffer = (uint8_t *)&g_UsbHostInstance[i];
+ for (uint32_t j = 0U; j < sizeof(usb_host_instance_t); j++)
+ {
+ buffer[j] = 0x00U;
+ }
+ g_UsbHostInstance[i].occupied = 1;
+ USB_OSA_EXIT_CRITICAL();
+ return &g_UsbHostInstance[i];
+ }
+ }
+ USB_OSA_EXIT_CRITICAL();
+ return NULL;
+}
+
+static void USB_HostReleaseInstance(usb_host_instance_t *hostInstance)
+{
+ USB_OSA_SR_ALLOC();
+ USB_OSA_ENTER_CRITICAL();
+ hostInstance->occupied = 0;
+ USB_OSA_EXIT_CRITICAL();
+}
+
+static void USB_HostGetControllerInterface(uint8_t controllerId,
+ const usb_host_controller_interface_t **controllerTable)
+{
+#if ((defined USB_HOST_CONFIG_KHCI) && (USB_HOST_CONFIG_KHCI))
+ if (controllerId == kUSB_ControllerKhci0)
+ {
+ *controllerTable = &s_KhciInterface;
+ }
+#endif /* USB_HOST_CONFIG_KHCI */
+
+#if ((defined USB_HOST_CONFIG_EHCI) && (USB_HOST_CONFIG_EHCI))
+ if (controllerId == kUSB_ControllerEhci0)
+ {
+ *controllerTable = &s_EhciInterface;
+ }
+#endif /* USB_HOST_CONFIG_EHCI */
+}
+
+usb_status_t USB_HostInit(uint8_t controllerId, usb_host_handle *hostHandle, host_callback_t callbackFn)
+{
+ usb_status_t status = kStatus_USB_Success;
+ usb_host_instance_t *hostInstance = NULL;
+ usb_host_transfer_t *transferPrev = NULL;
+ uint8_t i = 0;
+
+ hostInstance = USB_HostGetInstance(); /* get one host instance */
+ if (hostInstance == NULL)
+ {
+ return kStatus_USB_InvalidHandle;
+ }
+
+ /* get khci/ehci API table */
+ USB_HostGetControllerInterface(controllerId, &hostInstance->controllerTable);
+ if (hostInstance->controllerTable == NULL)
+ {
+ USB_HostReleaseInstance(hostInstance);
+ return kStatus_USB_ControllerNotFound;
+ }
+
+ /* judge the controller interface one time at here */
+ if ((hostInstance->controllerTable->controllerCreate == NULL) ||
+ (hostInstance->controllerTable->controllerDestory == NULL) ||
+ (hostInstance->controllerTable->controllerOpenPipe == NULL) ||
+ (hostInstance->controllerTable->controllerClosePipe == NULL) ||
+ (hostInstance->controllerTable->controllerWritePipe == NULL) ||
+ (hostInstance->controllerTable->controllerReadPipe == NULL) ||
+ (hostInstance->controllerTable->controllerIoctl == NULL))
+ {
+ return kStatus_USB_Error;
+ }
+
+ /* HOST instance init*/
+ hostInstance->controllerId = controllerId;
+ hostInstance->deviceCallback = callbackFn;
+ hostInstance->deviceList = NULL;
+ if (kStatus_USB_OSA_Success != USB_OsaMutexCreate(&hostInstance->hostMutex))
+ {
+ USB_HostReleaseInstance(hostInstance);
+#ifdef HOST_ECHO
+ usb_echo("host init: create host mutex fail\r\n");
+#endif
+ return kStatus_USB_Error;
+ }
+
+ /* initialize transfer list */
+
+ hostInstance->transferHead = &hostInstance->transferList[0];
+ transferPrev = hostInstance->transferHead;
+ for (i = 1; i < USB_HOST_CONFIG_MAX_TRANSFERS; ++i)
+ {
+ transferPrev->next = &hostInstance->transferList[i];
+ transferPrev = transferPrev->next;
+ }
+
+ /* controller create */
+ status =
+ hostInstance->controllerTable->controllerCreate(controllerId, hostInstance, &(hostInstance->controllerHandle));
+ if ((status != kStatus_USB_Success) || (hostInstance->controllerHandle == NULL))
+ {
+ USB_OsaMutexDestroy(hostInstance->hostMutex);
+ USB_HostReleaseInstance(hostInstance);
+#ifdef HOST_ECHO
+ usb_echo("host init: controller init fail\r\n");
+#endif
+ return kStatus_USB_Error;
+ }
+
+ *hostHandle = hostInstance;
+ return kStatus_USB_Success;
+}
+
+usb_status_t USB_HostDeinit(usb_host_handle hostHandle)
+{
+ usb_status_t status = kStatus_USB_Success;
+ usb_host_instance_t *hostInstance = (usb_host_instance_t *)hostHandle;
+ usb_host_device_instance_t *deviceInstance = NULL;
+
+ if (hostHandle == NULL)
+ {
+ return kStatus_USB_InvalidHandle;
+ }
+
+ /* device list detach */
+ deviceInstance = (usb_host_device_instance_t *)hostInstance->deviceList;
+ while (deviceInstance != NULL)
+ {
+ deviceInstance = (usb_host_device_instance_t *)hostInstance->deviceList;
+ USB_HostDetachDeviceInternal(hostHandle, deviceInstance);
+ }
+
+ /* controller instance destory */
+ status = hostInstance->controllerTable->controllerDestory(hostInstance->controllerHandle);
+ hostInstance->controllerHandle = NULL;
+ if (status != kStatus_USB_Success)
+ {
+#ifdef HOST_ECHO
+ usb_echo("host controller destory fail\r\n");
+#endif
+ }
+
+ /* resource release */
+ if (hostInstance->hostMutex)
+ {
+ USB_OsaMutexDestroy(hostInstance->hostMutex);
+ hostInstance->hostMutex = NULL;
+ }
+ USB_HostReleaseInstance(hostInstance);
+
+ return status;
+}
+
+usb_status_t USB_HostOpenPipe(usb_host_handle hostHandle,
+ usb_host_pipe_handle *pipeHandle,
+ usb_host_pipe_init_t *pipeInit)
+{
+ usb_status_t status = kStatus_USB_Success;
+ usb_host_instance_t *hostInstance = (usb_host_instance_t *)hostHandle;
+
+ if ((hostHandle == NULL) || (pipeInit == NULL))
+ {
+ return kStatus_USB_InvalidHandle;
+ }
+
+ /* call controller open pipe interface */
+ status = hostInstance->controllerTable->controllerOpenPipe(hostInstance->controllerHandle, pipeHandle, pipeInit);
+
+ return status;
+}
+
+usb_status_t USB_HostClosePipe(usb_host_handle hostHandle, usb_host_pipe_handle pipeHandle)
+{
+ usb_status_t status = kStatus_USB_Success;
+ usb_host_instance_t *hostInstance = (usb_host_instance_t *)hostHandle;
+
+ if ((hostHandle == NULL) || (pipeHandle == NULL))
+ {
+ return kStatus_USB_InvalidHandle;
+ }
+
+ /* call controller close pipe interface */
+ status = hostInstance->controllerTable->controllerClosePipe(hostInstance->controllerHandle, pipeHandle);
+
+ return status;
+}
+
+usb_status_t USB_HostSend(usb_host_handle hostHandle, usb_host_pipe_handle pipeHandle, usb_host_transfer_t *transfer)
+{
+ usb_status_t status = kStatus_USB_Success;
+ usb_host_instance_t *hostInstance = (usb_host_instance_t *)hostHandle;
+
+ if ((hostHandle == NULL) || (pipeHandle == NULL) || (transfer == NULL))
+ {
+ return kStatus_USB_InvalidHandle;
+ }
+
+ /* initialize transfer */
+ transfer->transferSofar = 0;
+ transfer->direction = USB_OUT;
+
+ USB_HostLock(); /* This api can be called by host task and app task */
+/* keep this code: in normal situation application will guarantee the device is attached when call send/receive function
+ */
+#if 0
+ if ((USB_HostValidateDevice(pipe_ptr->deviceHandle) != kStatus_USB_Success) || (!(USB_HostGetDeviceAttachState(pipe_ptr->deviceHandle))))
+ {
+ USB_HostUnlock();
+ return status;
+ }
+#endif
+/* call controller write pipe interface */
+#if ((defined USB_HOST_CONFIG_BUFFER_PROPERTY_CACHEABLE) && (USB_HOST_CONFIG_BUFFER_PROPERTY_CACHEABLE))
+ if (transfer->transferLength > 0)
+ {
+ USB_CacheFlushLines((void *)transfer->transferBuffer, transfer->transferLength);
+ }
+#endif
+ status = hostInstance->controllerTable->controllerWritePipe(hostInstance->controllerHandle, pipeHandle, transfer);
+
+ USB_HostUnlock();
+ return status;
+}
+
+usb_status_t USB_HostSendSetup(usb_host_handle hostHandle,
+ usb_host_pipe_handle pipeHandle,
+ usb_host_transfer_t *transfer)
+{
+ usb_status_t status = kStatus_USB_Success;
+ usb_host_instance_t *hostInstance = (usb_host_instance_t *)hostHandle;
+
+ if ((hostHandle == NULL) || (pipeHandle == NULL) || (transfer == NULL))
+ {
+ return kStatus_USB_InvalidHandle;
+ }
+
+ /* initialize transfer */
+ transfer->transferSofar = 0;
+ transfer->next = NULL;
+ transfer->setupStatus = 0;
+ if ((transfer->setupPacket.bmRequestType & USB_REQUEST_TYPE_DIR_MASK) == USB_REQUEST_TYPE_DIR_IN)
+ {
+ transfer->direction = USB_IN;
+ }
+ else
+ {
+ transfer->direction = USB_OUT;
+ }
+
+ USB_HostLock(); /* This API can be called by host task and application task */
+/* keep this code: in normal situation application will guarantee the device is attached when call send/receive function
+ */
+#if 0
+ if ((USB_HostValidateDevice(pipe_ptr->deviceHandle) != kStatus_USB_Success) || (!(USB_HostGetDeviceAttachState(pipe_ptr->deviceHandle))))
+ {
+ USB_HostUnlock();
+ return status;
+ }
+#endif
+/* call controller write pipe interface */
+#if ((defined USB_HOST_CONFIG_BUFFER_PROPERTY_CACHEABLE) && (USB_HOST_CONFIG_BUFFER_PROPERTY_CACHEABLE))
+ if (transfer->transferLength > 0)
+ {
+ USB_CacheFlushLines((void *)transfer->transferBuffer, transfer->transferLength);
+ }
+#endif
+ status = hostInstance->controllerTable->controllerWritePipe(hostInstance->controllerHandle, pipeHandle, transfer);
+
+ USB_HostUnlock();
+ return status;
+}
+
+usb_status_t USB_HostRecv(usb_host_handle hostHandle, usb_host_pipe_handle pipeHandle, usb_host_transfer_t *transfer)
+{
+ usb_status_t status = kStatus_USB_Success;
+ usb_host_instance_t *hostInstance = (usb_host_instance_t *)hostHandle;
+
+ if ((hostHandle == NULL) || (pipeHandle == NULL) || (transfer == NULL))
+ {
+ return kStatus_USB_InvalidHandle;
+ }
+
+ /* initialize transfer */
+ transfer->transferSofar = 0;
+ transfer->direction = USB_IN;
+
+ USB_HostLock(); /* This API can be called by host task and application task */
+/* keep this code: in normal situation application will guarantee the device is attached when call send/receive function
+ */
+#if 0
+ if ((USB_HostValidateDevice(pipe_ptr->deviceHandle) != kStatus_USB_Success) || (!(USB_HostGetDeviceAttachState(pipe_ptr->deviceHandle))))
+ {
+ USB_HostUnlock();
+ return status;
+ }
+#endif
+
+#if ((defined USB_HOST_CONFIG_BUFFER_PROPERTY_CACHEABLE) && (USB_HOST_CONFIG_BUFFER_PROPERTY_CACHEABLE))
+ if (transfer->transferLength > 0)
+ {
+ USB_CacheInvalidateLines((void *)transfer->transferBuffer, transfer->transferLength);
+ }
+#endif
+ status = hostInstance->controllerTable->controllerReadPipe(hostInstance->controllerHandle, pipeHandle, transfer);
+
+ USB_HostUnlock();
+ return status;
+}
+
+usb_status_t USB_HostCancelTransfer(usb_host_handle hostHandle,
+ usb_host_pipe_handle pipeHandle,
+ usb_host_transfer_t *transfer)
+{
+ usb_status_t status = kStatus_USB_Success;
+ usb_host_instance_t *hostInstance = (usb_host_instance_t *)hostHandle;
+ usb_host_cancel_param_t cancelParam;
+
+ if ((hostHandle == NULL) || (pipeHandle == NULL))
+ {
+ return kStatus_USB_InvalidHandle;
+ }
+
+ /* initialize cancel parameter */
+ cancelParam.pipeHandle = pipeHandle;
+ cancelParam.transfer = transfer;
+
+ /* USB_HostLock(); This api can be called by host task and app task */
+ status = hostInstance->controllerTable->controllerIoctl(hostInstance->controllerHandle, kUSB_HostCancelTransfer,
+ &cancelParam);
+ /* USB_HostUnlock(); */
+
+ return status;
+}
+
+usb_status_t USB_HostMallocTransfer(usb_host_handle hostHandle, usb_host_transfer_t **transfer)
+{
+ usb_host_instance_t *hostInstance = (usb_host_instance_t *)hostHandle;
+
+ if ((hostHandle == NULL) || (transfer == NULL))
+ {
+ return kStatus_USB_InvalidHandle;
+ }
+
+ /* get one from the transfer_head */
+ USB_HostLock();
+ if (hostInstance->transferHead != NULL)
+ {
+ *transfer = hostInstance->transferHead;
+ hostInstance->transferHead = hostInstance->transferHead->next;
+ USB_HostUnlock();
+ return kStatus_USB_Success;
+ }
+ else
+ {
+ *transfer = NULL;
+ USB_HostUnlock();
+ return kStatus_USB_Error;
+ }
+}
+
+usb_status_t USB_HostFreeTransfer(usb_host_handle hostHandle, usb_host_transfer_t *transfer)
+{
+ usb_host_instance_t *hostInstance = (usb_host_instance_t *)hostHandle;
+
+ if (hostHandle == NULL)
+ {
+ return kStatus_USB_InvalidHandle;
+ }
+ if (transfer == NULL)
+ {
+ return kStatus_USB_Success;
+ }
+
+ /* release one to the transfer_head */
+ USB_HostLock();
+ transfer->next = hostInstance->transferHead;
+ hostInstance->transferHead = transfer;
+ USB_HostUnlock();
+ return kStatus_USB_Success;
+}
+
+usb_status_t USB_HostHelperGetPeripheralInformation(usb_device_handle deviceHandle,
+ uint32_t infoCode,
+ uint32_t *infoValue)
+{
+ usb_host_device_instance_t *deviceInstance = (usb_host_device_instance_t *)deviceHandle;
+ if ((deviceHandle == NULL) || (infoValue == NULL))
+ {
+ return kStatus_USB_InvalidParameter;
+ }
+
+ switch (infoCode)
+ {
+ case kUSB_HostGetDeviceAddress: /* device address */
+ *infoValue = (uint32_t)deviceInstance->setAddress;
+ break;
+
+ case kUSB_HostGetDeviceControlPipe: /* device control pipe */
+ *infoValue = (uint32_t)deviceInstance->controlPipe;
+ break;
+
+ case kUSB_HostGetHostHandle: /* device host handle */
+ *infoValue = (uint32_t)deviceInstance->hostHandle;
+ break;
+
+#if ((defined USB_HOST_CONFIG_HUB) && (USB_HOST_CONFIG_HUB))
+ case kUSB_HostGetDeviceHubNumber: /* device hub address */
+ *infoValue = (uint32_t)deviceInstance->hubNumber;
+ break;
+
+ case kUSB_HostGetDevicePortNumber: /* device port no */
+ *infoValue = (uint32_t)deviceInstance->portNumber;
+ break;
+
+ case kUSB_HostGetDeviceLevel: /* device level */
+ *infoValue = (uint32_t)deviceInstance->level;
+ break;
+
+ case kUSB_HostGetDeviceHSHubNumber: /* device high-speed hub address */
+ *infoValue = (uint32_t)deviceInstance->hsHubNumber;
+ break;
+
+ case kUSB_HostGetDeviceHSHubPort: /* device high-speed hub port no */
+ *infoValue = (uint32_t)deviceInstance->hsHubPort;
+ break;
+
+ case kUSB_HostGetHubThinkTime: /* device hub think time */
+ *infoValue = USB_HostHubGetTotalThinkTime(deviceInstance->hubNumber);
+ break;
+#else
+ case kUSB_HostGetDeviceHubNumber: /* device hub address */
+ case kUSB_HostGetDevicePortNumber: /* device port no */
+ case kUSB_HostGetDeviceHSHubNumber: /* device high-speed hub address */
+ case kUSB_HostGetDeviceHSHubPort: /* device high-speed hub port no */
+ case kUSB_HostGetHubThinkTime: /* device hub think time */
+ *infoValue = 0;
+ break;
+ case kUSB_HostGetDeviceLevel: /* device level */
+ *infoValue = 1;
+ break;
+#endif /* USB_HOST_CONFIG_HUB */
+
+ case kUSB_HostGetDeviceSpeed: /* device speed */
+ *infoValue = (uint32_t)deviceInstance->speed;
+ break;
+
+ case kUSB_HostGetDevicePID: /* device pid */
+ *infoValue = (uint32_t)USB_SHORT_FROM_LITTLE_ENDIAN_ADDRESS(deviceInstance->deviceDescriptor.idProduct);
+ break;
+
+ case kUSB_HostGetDeviceVID: /* device vid */
+ *infoValue = (uint32_t)USB_SHORT_FROM_LITTLE_ENDIAN_ADDRESS(deviceInstance->deviceDescriptor.idVendor);
+ break;
+
+ case kUSB_HostGetDeviceConfigIndex: /* device config index */
+ *infoValue = (uint32_t)deviceInstance->configurationValue - 1U;
+ break;
+
+ default:
+ return kStatus_USB_Error;
+ }
+
+ return kStatus_USB_Success;
+}
+
+usb_status_t USB_HostHelperParseAlternateSetting(usb_host_interface_handle interfaceHandle,
+ uint8_t alternateSetting,
+ usb_host_interface_t *interface)
+{
+ uint32_t endPosition;
+ usb_descriptor_union_t *unionDes;
+ usb_host_ep_t *epParse;
+
+ if (interfaceHandle == NULL)
+ {
+ return kStatus_USB_InvalidHandle;
+ }
+
+ if (alternateSetting == 0)
+ {
+ return kStatus_USB_InvalidParameter;
+ }
+
+ /* parse configuration descriptor */
+ /* interface extend descriptor start */
+ unionDes = (usb_descriptor_union_t *)(((usb_host_interface_t *)interfaceHandle)->interfaceExtension);
+ /* interface extend descriptor end */
+ endPosition = (uint32_t)unionDes + ((usb_host_interface_t *)interfaceHandle)->interfaceExtensionLength;
+
+ /* search for the alternate setting interface descritpor */
+ while ((uint32_t)unionDes < endPosition)
+ {
+ if (unionDes->common.bDescriptorType == USB_DESCRIPTOR_TYPE_INTERFACE)
+ {
+ if (unionDes->interface.bAlternateSetting == alternateSetting)
+ {
+ break;
+ }
+ else
+ {
+ unionDes = (usb_descriptor_union_t *)((uint32_t)unionDes + unionDes->common.bLength);
+ }
+ }
+ else
+ {
+ unionDes = (usb_descriptor_union_t *)((uint32_t)unionDes + unionDes->common.bLength);
+ }
+ }
+ if ((uint32_t)unionDes >= endPosition)
+ {
+ return kStatus_USB_Error;
+ }
+
+ /* initialize interface handle structure instance */
+ interface->interfaceDesc = &unionDes->interface;
+ interface->alternateSettingNumber = 0;
+ interface->epCount = 0;
+ interface->interfaceExtension = NULL;
+ interface->interfaceExtensionLength = 0;
+ interface->interfaceIndex = unionDes->interface.bInterfaceNumber;
+
+ /* search for endpoint descriptor start position */
+ unionDes = (usb_descriptor_union_t *)((uint32_t)unionDes + unionDes->common.bLength);
+ interface->interfaceExtension = (uint8_t *)unionDes;
+ while ((uint32_t)unionDes < endPosition)
+ {
+ if ((unionDes->common.bDescriptorType != USB_DESCRIPTOR_TYPE_INTERFACE) &&
+ (unionDes->common.bDescriptorType != USB_DESCRIPTOR_TYPE_ENDPOINT))
+ {
+ interface->interfaceExtensionLength += unionDes->common.bLength;
+ unionDes = (usb_descriptor_union_t *)((uint32_t)unionDes + unionDes->common.bLength);
+ }
+ else
+ {
+ break;
+ }
+ }
+
+ /* parse endpoint descriptor */
+ if (interface->interfaceDesc->bNumEndpoints != 0)
+ {
+ if ((unionDes->common.bDescriptorType != USB_DESCRIPTOR_TYPE_ENDPOINT) ||
+ (interface->interfaceDesc->bNumEndpoints > USB_HOST_CONFIG_INTERFACE_MAX_EP))
+ {
+#ifdef HOST_ECHO
+ usb_echo("interface descriptor error\n");
+#endif
+ return kStatus_USB_Error;
+ }
+ for (; interface->epCount < interface->interfaceDesc->bNumEndpoints; (interface->epCount)++)
+ {
+ if (((uint32_t)unionDes >= endPosition) ||
+ (unionDes->common.bDescriptorType != USB_DESCRIPTOR_TYPE_ENDPOINT))
+ {
+#ifdef HOST_ECHO
+ usb_echo("endpoint descriptor error\n");
+#endif
+ return kStatus_USB_Error;
+ }
+ epParse = (usb_host_ep_t *)&interface->epList[interface->epCount];
+ epParse->epDesc = (usb_descriptor_endpoint_t *)unionDes;
+ epParse->epExtensionLength = 0;
+ epParse->epExtension = NULL;
+ interface->interfaceExtensionLength += unionDes->common.bLength;
+ unionDes = (usb_descriptor_union_t *)((uint32_t)unionDes + unionDes->common.bLength);
+ epParse->epExtension = (uint8_t *)unionDes;
+ while ((uint32_t)unionDes < endPosition)
+ {
+ if ((unionDes->common.bDescriptorType != USB_DESCRIPTOR_TYPE_ENDPOINT) &&
+ (unionDes->common.bDescriptorType != USB_DESCRIPTOR_TYPE_INTERFACE))
+ {
+ epParse->epExtensionLength += unionDes->common.bLength;
+ interface->interfaceExtensionLength += unionDes->common.bLength;
+ unionDes = (usb_descriptor_union_t *)((uint32_t)unionDes + unionDes->common.bLength);
+ }
+ else
+ {
+ break;
+ }
+ }
+ }
+ }
+
+ return kStatus_USB_Success;
+}
+
+void USB_HostGetVersion(uint32_t *version)
+{
+ if (version)
+ {
+ *version =
+ (uint32_t)USB_MAKE_VERSION(USB_STACK_VERSION_MAJOR, USB_STACK_VERSION_MINOR, USB_STACK_VERSION_BUGFIX);
+ }
+}
diff --git a/usb_1.1.0/host/usb_host_hci.h b/usb_1.1.0/host/usb_host_hci.h
new file mode 100644
index 0000000..f73c8f3
--- /dev/null
+++ b/usb_1.1.0/host/usb_host_hci.h
@@ -0,0 +1,118 @@
+/*
+ * Copyright (c) 2015, Freescale Semiconductor, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * o Redistributions of source code must retain the above copyright notice, this list
+ * of conditions and the following disclaimer.
+ *
+ * o Redistributions in binary form must reproduce the above copyright notice, this
+ * list of conditions and the following disclaimer in the documentation and/or
+ * other materials provided with the distribution.
+ *
+ * o Neither the name of Freescale Semiconductor, Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _USB_HOST_HCI_H_
+#define _USB_HOST_HCI_H_
+
+/*******************************************************************************
+ * Definitions
+ ******************************************************************************/
+
+/*! @brief USB host lock */
+#define USB_HostLock() USB_OsaMutexLock(hostInstance->hostMutex)
+/*! @brief USB host unlock */
+#define USB_HostUnlock() USB_OsaMutexUnlock(hostInstance->hostMutex)
+
+/*!
+ * @addtogroup usb_host_controller_driver
+ * @{
+ */
+
+/*! @brief USB host controller control code */
+typedef enum _usb_host_controller_control
+{
+ kUSB_HostCancelTransfer = 1U, /*!< Cancel transfer code */
+ kUSB_HostBusControl, /*!< Bus control code */
+ kUSB_HostGetFrameNumber, /*!< Get frame number code */
+ kUSB_HostUpdateControlEndpointAddress, /*!< Update control endpoint address */
+ kUSB_HostUpdateControlPacketSize, /*!< Update control endpoint maximum packet size */
+} usb_host_controller_control_t;
+
+/*! @brief USB host controller bus control code */
+typedef enum _usb_host_bus_control
+{
+ kUSB_HostBusReset = 1U, /*!< Reset bus */
+ kUSB_HostBusRestart, /*!< Restart bus */
+ kUSB_HostBusEnableAttach, /*!< Enable attach */
+ kUSB_HostBusDisableAttach, /*!< Disable attach*/
+} usb_host_bus_control_t;
+
+/*! @brief USB host controller interface structure */
+typedef struct _usb_host_controller_interface
+{
+ usb_status_t (*controllerCreate)(
+ uint8_t controllerId,
+ usb_host_handle upperLayerHandle,
+ usb_host_controller_handle *controllerHandle); /*!< Create a controller instance function prototype*/
+ usb_status_t (*controllerDestory)(
+ usb_host_controller_handle controllerHandle); /*!< Destroy a controller instance function prototype*/
+ usb_status_t (*controllerOpenPipe)(usb_host_controller_handle controllerHandle,
+ usb_host_pipe_handle *pipeHandle,
+ usb_host_pipe_init_t *pipeInit); /*!< Open a controller pipe function prototype*/
+ usb_status_t (*controllerClosePipe)(
+ usb_host_controller_handle controllerHandle,
+ usb_host_pipe_handle pipeHandle); /*!< Close a controller pipe function prototype*/
+ usb_status_t (*controllerWritePipe)(usb_host_controller_handle controllerHandle,
+ usb_host_pipe_handle pipeHandle,
+ usb_host_transfer_t *transfer); /*!< Write data to a pipe function prototype*/
+ usb_status_t (*controllerReadPipe)(usb_host_controller_handle controllerHandle,
+ usb_host_pipe_handle pipeHandle,
+ usb_host_transfer_t *transfer); /*!< Read data from a pipe function prototype*/
+ usb_status_t (*controllerIoctl)(usb_host_controller_handle controllerHandle,
+ uint32_t ioctlEvent,
+ void *ioctlParam); /*!< Control a controller function prototype*/
+} usb_host_controller_interface_t;
+
+/*! @}*/
+
+/*!
+ * @addtogroup usb_host_drv
+ * @{
+ */
+
+/*! @brief USB host instance structure */
+typedef struct _usb_host_instance
+{
+ void *controllerHandle; /*!< The low level controller handle*/
+ host_callback_t deviceCallback; /*!< Device attach/detach callback*/
+ usb_osa_mutex_handle hostMutex; /*!< Host layer mutex*/
+ usb_host_transfer_t transferList[USB_HOST_CONFIG_MAX_TRANSFERS]; /*!< Transfer resource*/
+ usb_host_transfer_t *transferHead; /*!< Idle transfer head*/
+ const usb_host_controller_interface_t *controllerTable; /*!< KHCI/EHCI interface*/
+ void *deviceList; /*!< Device list*/
+ uint8_t addressBitMap[16]; /*!< Used for address allocation. The first bit is the address 1, second bit is the
+ address 2*/
+ uint8_t occupied; /*!< 0 - the instance is not occupied; 1 - the instance is occupied*/
+ uint8_t controllerId; /*!< The controller ID*/
+} usb_host_instance_t;
+
+/*! @}*/
+
+#endif /* _USB_HOST_HCI_H_ */
diff --git a/usb_1.1.0/host/usb_host_khci.c b/usb_1.1.0/host/usb_host_khci.c
new file mode 100644
index 0000000..57af624
--- /dev/null
+++ b/usb_1.1.0/host/usb_host_khci.c
@@ -0,0 +1,1886 @@
+/*
+ * Copyright (c) 2015 -2016, Freescale Semiconductor, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * o Redistributions of source code must retain the above copyright notice, this list
+ * of conditions and the following disclaimer.
+ *
+ * o Redistributions in binary form must reproduce the above copyright notice, this
+ * list of conditions and the following disclaimer in the documentation and/or
+ * other materials provided with the distribution.
+ *
+ * o Neither the name of Freescale Semiconductor, Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "usb_host_config.h"
+#if ((defined USB_HOST_CONFIG_KHCI) && (USB_HOST_CONFIG_KHCI))
+#include "usb_host.h"
+#include "usb_host_hci.h"
+#include "fsl_device_registers.h"
+#include "usb_host_khci.h"
+#include "usb_host_devices.h"
+
+/*******************************************************************************
+ * Variables
+ ******************************************************************************/
+#if defined(__ICCCF__) || defined(__ICCARM__)
+#pragma segment = "USB_BDT_Z"
+#pragma data_alignment = 512
+__no_init static uint8_t bdt[512] @"USB_BDT_Z";
+#elif defined(__GNUC__)
+__attribute__((aligned(512))) static uint8_t bdt[512];
+#elif defined(__CC_ARM)
+__align(512) uint8_t bdt[512];
+#else
+#error Unsupported compiler, please use IAR, Keil or arm gcc compiler and rebuild the project.
+#endif
+
+/*******************************************************************************
+ * Code
+ ******************************************************************************/
+/*!
+ * @brief get the 2 power value of uint32_t.
+ *
+ * @param data input uint32_t value.
+ *
+ */
+static uint32_t _USB_HostKhciGetRoundUpPow2(uint32_t data)
+{
+ uint8_t i = 0U;
+
+ if ((data == 1U) || (data == 0U))
+ {
+ return data;
+ }
+ while (data != 1U)
+ {
+ data = data >> 1U;
+ i++;
+ }
+ return 1U << (i);
+}
+
+/*!
+ * @brief get the current host khci frame number count.
+ *
+ * @param handle Pointer of the host KHCI state structure.
+ *
+ * @return current frame number count.
+ */
+static uint32_t _USB_HostKhciGetFrameCount(usb_host_controller_handle handle)
+{
+ uint32_t tempFrameCount;
+ usb_khci_host_state_struct_t *usbHostPointer = (usb_khci_host_state_struct_t *)handle;
+
+ tempFrameCount = usbHostPointer->usbRegBase->FRMNUMH;
+
+ return (uint16_t)((tempFrameCount << 8U) | (usbHostPointer->usbRegBase->FRMNUML));
+}
+
+/*!
+ * @brief get the total of host khci frame number count.
+ *
+ * @param usbHostPointer Pointer of the host KHCI state structure.
+ *
+ * @return total of frame number count.
+ */
+static uint32_t _USB_HostKhciGetFrameCountSum(usb_khci_host_state_struct_t *usbHostPointer)
+{
+ static uint32_t totalFrameNumber = 0U;
+ static uint16_t oldFrameNumber = 0U;
+ uint16_t frameNumber = 0xFFFFU;
+
+ frameNumber = _USB_HostKhciGetFrameCount((usb_host_controller_handle)usbHostPointer);
+
+ if (frameNumber < oldFrameNumber)
+ {
+ totalFrameNumber += 2048U;
+ }
+
+ oldFrameNumber = frameNumber;
+
+ return (frameNumber + totalFrameNumber);
+}
+
+/*!
+ * @brief host khci delay.
+ *
+ * @param usbHostPointer Pointer of the host KHCI state structure.
+ * @param ms milliseconds.
+ *
+ */
+static void _USB_HostKhciDelay(usb_khci_host_state_struct_t *usbHostPointer, uint32_t ms)
+{
+ uint32_t sofStart;
+ uint32_t sofEnd;
+ sofStart = _USB_HostKhciGetFrameCountSum(usbHostPointer);
+
+ do
+ {
+ sofEnd = _USB_HostKhciGetFrameCountSum(usbHostPointer);
+ } while ((sofEnd - sofStart) < ms);
+}
+
+/*!
+ * @brief Device KHCI isr function.
+ *
+ * The function is KHCI interrupt service routine.
+ *
+ * @param hostHandle The host handle.
+ */
+void USB_HostKhciIsrFunction(void *hostHandle)
+{
+ usb_khci_host_state_struct_t *usbHostPointer;
+
+ uint8_t status;
+
+ if (hostHandle == NULL)
+ {
+ return;
+ }
+
+ usbHostPointer = (usb_khci_host_state_struct_t *)((usb_host_instance_t *)hostHandle)->controllerHandle;
+
+ while (1U)
+ {
+ status = (uint8_t)((usbHostPointer->usbRegBase->ISTAT));
+ status &= (uint8_t)(usbHostPointer->usbRegBase->INTEN);
+
+ if (!status)
+ {
+ break;
+ }
+
+ usbHostPointer->usbRegBase->ISTAT = status;
+
+ if (status & USB_ISTAT_SOFTOK_MASK)
+ {
+ USB_OsaEventSet(usbHostPointer->khciEventPointer, USB_KHCI_EVENT_SOF_TOK);
+ }
+
+ if (status & USB_ISTAT_ATTACH_MASK)
+ {
+ usbHostPointer->usbRegBase->INTEN &= (~USB_INTEN_ATTACHEN_MASK);
+ USB_OsaEventSet(usbHostPointer->khciEventPointer, USB_KHCI_EVENT_ATTACH);
+ }
+
+ if (status & USB_ISTAT_TOKDNE_MASK)
+ {
+ /* atom transaction done - token done */
+ USB_OsaEventSet(usbHostPointer->khciEventPointer, USB_KHCI_EVENT_TOK_DONE);
+ }
+
+ if (status & USB_ISTAT_USBRST_MASK)
+ {
+ USB_OsaEventSet(usbHostPointer->khciEventPointer, USB_KHCI_EVENT_RESET);
+ }
+ }
+}
+
+/*!
+ * @brief Handle khci host controller attach event.
+ *
+ * The function is used to handle attach event when a device is attached to khci host controller, the process is detect
+ * the line state, do bus reset, and call device attached function.
+ *
+ * @param usbHostPointer Pointer of the host KHCI state structure.
+ *
+ */
+static void _USB_HostKhciAttach(usb_khci_host_state_struct_t *usbHostPointer)
+{
+ uint8_t speed;
+ uint8_t temp;
+ usb_device_handle deviceHandle;
+ uint8_t index = 0U;
+
+ usbHostPointer->usbRegBase->CTL |= USB_CTL_ODDRST_MASK;
+ usbHostPointer->usbRegBase->CTL = USB_CTL_HOSTMODEEN_MASK;
+ usbHostPointer->usbRegBase->ADDR = ((usbHostPointer->usbRegBase->ADDR & (~USB_ADDR_ADDR_MASK)) |
+ ((((0U) << USB_ADDR_ADDR_SHIFT) & USB_ADDR_ADDR_MASK)));
+ usbHostPointer->usbRegBase->ADDR &= (~USB_ADDR_LSEN_MASK);
+
+ /* here wait for about 120ms to check line state */
+ for (volatile uint32_t i = 0U; i < 2000000U; i++)
+ {
+ __ASM("nop");
+ }
+
+ do
+ {
+ temp = ((usbHostPointer->usbRegBase->CTL) & USB_CTL_JSTATE_MASK) ? 0U : 1U;
+ for (volatile uint32_t i = 0U; i < 100000U; i++)
+ {
+ __ASM("nop");
+ }
+ speed = ((usbHostPointer->usbRegBase->CTL) & USB_CTL_JSTATE_MASK) ? 0U : 1U;
+ index++;
+ } while ((temp != speed) && (index < USB_KHCI_MAX_SPEED_DETECTION_COUNT));
+
+ if (temp != speed)
+ {
+#ifdef HOST_ECHO
+ usb_echo("speed not match!\n");
+#endif
+ usbHostPointer->usbRegBase->INTEN |= USB_INTEN_ATTACHEN_MASK;
+ return;
+ }
+ if (((usbHostPointer->usbRegBase->CTL) & USB_CTL_SE0_MASK) == USB_CTL_SE0_MASK)
+ {
+ usbHostPointer->usbRegBase->INTEN |= USB_INTEN_ATTACHEN_MASK;
+ return;
+ }
+
+ if (speed == USB_SPEED_FULL)
+ {
+ usbHostPointer->usbRegBase->ADDR &= (~USB_ADDR_LSEN_MASK);
+ }
+ else if (speed == USB_SPEED_LOW)
+ {
+ usbHostPointer->usbRegBase->ENDPOINT[0U].ENDPT = USB_ENDPT_HOSTWOHUB_MASK;
+ usbHostPointer->usbRegBase->ADDR |= USB_ADDR_LSEN_MASK;
+ }
+ else
+ {
+ }
+
+ usbHostPointer->usbRegBase->CTL |= USB_CTL_USBENSOFEN_MASK;
+
+ usbHostPointer->usbRegBase->ISTAT = 0xffU;
+ usbHostPointer->usbRegBase->INTEN &= (~(USB_INTEN_TOKDNEEN_MASK | USB_INTEN_USBRSTEN_MASK));
+
+ /* Do USB bus reset here */
+ usbHostPointer->usbRegBase->CTL |= USB_CTL_RESET_MASK;
+ _USB_HostKhciDelay(usbHostPointer, 30U);
+ usbHostPointer->usbRegBase->CTL &= (~USB_CTL_RESET_MASK);
+
+#ifdef USBCFG_OTG
+ _USB_HostKhciDelay(usbHostPointer, 30U);
+#else
+ _USB_HostKhciDelay(usbHostPointer, 100U);
+#endif
+ usbHostPointer->usbRegBase->CONTROL &= ~USB_CONTROL_DPPULLUPNONOTG_MASK;
+ usbHostPointer->usbRegBase->INTEN |= (USB_INTEN_TOKDNEEN_MASK | USB_INTEN_USBRSTEN_MASK);
+ usbHostPointer->deviceAttached++;
+ USB_OsaEventClear(usbHostPointer->khciEventPointer, USB_KHCI_EVENT_TOK_DONE);
+ USB_HostAttachDevice(usbHostPointer->hostHandle, speed, 0U, 0U, 1, &deviceHandle);
+
+ usbHostPointer->txBd = 0U;
+ usbHostPointer->rxBd = 0U;
+}
+
+/*!
+ * @brief Handle khci host controller bus reset event.
+ *
+ * The function is used to handle khci host controller bus reset event, reset event also is used for khci detached
+ * detecction.
+ *
+ * @param usbHostPointer Pointer of the host KHCI state structure.
+ *
+ */
+static void _USB_HostKhciReset(usb_khci_host_state_struct_t *usbHostPointer)
+{
+ volatile uint32_t i = 0xfffU;
+ /* clear attach flag */
+ usbHostPointer->usbRegBase->ISTAT = USB_ISTAT_ATTACH_MASK;
+ while (i--)
+ {
+ __ASM("nop");
+ }
+ /* Test the presence of USB device */
+ if ((usbHostPointer->usbRegBase->ISTAT) & USB_ISTAT_ATTACH_MASK)
+ {
+ /* device attached, so really normal reset was performed */
+ usbHostPointer->usbRegBase->INTEN |= USB_ISTAT_USBRST_MASK;
+ usbHostPointer->usbRegBase->ADDR = ((usbHostPointer->usbRegBase->ADDR & (~USB_ADDR_ADDR_MASK)) |
+ ((((0U) << USB_ADDR_ADDR_SHIFT) & USB_ADDR_ADDR_MASK)));
+ usbHostPointer->usbRegBase->ENDPOINT[0U].ENDPT |= USB_ENDPT_HOSTWOHUB_MASK;
+ }
+ else
+ {
+ /* device was detached,, notify about detach */
+ USB_OsaEventSet(usbHostPointer->khciEventPointer, USB_KHCI_EVENT_DETACH);
+ }
+}
+
+/*!
+ * @brief Handle khci host controller bus detach event.
+ *
+ * @param usbHostPointer Pointer of the host KHCI state structure.
+ *
+ */
+static void _USB_HostKhciDetach(usb_khci_host_state_struct_t *usbHostPointer)
+{
+ if (usbHostPointer->deviceAttached > 0)
+ {
+ usbHostPointer->deviceAttached--;
+ }
+ else
+ {
+ return;
+ }
+ USB_HostDetachDevice(usbHostPointer->hostHandle, 0U, 0U);
+ /* Enable USB week pull-downs, useful for detecting detach (effectively bus discharge) */
+ usbHostPointer->usbRegBase->USBCTRL |= USB_USBCTRL_PDE_MASK;
+ /* Remove suspend state */
+ usbHostPointer->usbRegBase->USBCTRL &= (~USB_USBCTRL_SUSP_MASK);
+
+ usbHostPointer->usbRegBase->CTL |= USB_CTL_ODDRST_MASK;
+
+ usbHostPointer->usbRegBase->CTL = USB_CTL_HOSTMODEEN_MASK;
+
+ usbHostPointer->txBd = 0U;
+ usbHostPointer->rxBd = 0U;
+
+ usbHostPointer->usbRegBase->ISTAT = 0xffU;
+ USB_OsaEventClear(usbHostPointer->khciEventPointer, USB_KHCI_EVENT_MSG);
+}
+
+/*!
+ * @brief get a right transfer from periodic and async list.
+ *
+ * This function return a right transfer for khci atom transfer, the function implemented simple USB transaction
+ * dispatch algorithm.
+ *
+ * @param handle Pointer of the host khci controller handle.
+ * @param transfer Pointer of pointer of transfer node struct, will get the a tr quest pointer if operator
+ * success, will get NULL pointer if fail.
+ *
+ */
+static void _USB_HostKhciGetRightTrRequest(usb_host_controller_handle handle, usb_host_transfer_t **transfer)
+{
+ usb_host_transfer_t *tempTransfer;
+ usb_host_transfer_t *firstTransfer;
+ usb_host_transfer_t *prevTtransfer;
+ usb_khci_host_state_struct_t *usbHostPointer = (usb_khci_host_state_struct_t *)handle;
+ uint32_t frame_number;
+
+ if (handle == NULL)
+ {
+ *transfer = NULL;
+ return;
+ }
+
+ USB_HostKhciLock();
+ /* First check whether periodic list is active, will get transfer from periodic list */
+ if (usbHostPointer->periodicListAvtive)
+ {
+ prevTtransfer = tempTransfer = usbHostPointer->periodicListPointer;
+ frame_number = _USB_HostKhciGetFrameCount(usbHostPointer);
+ /* Will get the transfer if the pipe frame count and current frame count is equal */
+ while (tempTransfer != NULL)
+ {
+ if ((tempTransfer->transferPipe->currentCount != frame_number) &&
+ (frame_number % tempTransfer->transferPipe->interval == 0U) &&
+ (tempTransfer->transferPipe->pipeType == USB_ENDPOINT_INTERRUPT))
+ {
+ tempTransfer->transferPipe->currentCount = frame_number;
+ *transfer = firstTransfer = tempTransfer;
+ /* Will move the selected interrupt transfer to end of the periodic list */
+ if ((tempTransfer->transferPipe->pipeType == USB_ENDPOINT_INTERRUPT) && (tempTransfer->next != NULL))
+ {
+ if (tempTransfer == usbHostPointer->periodicListPointer)
+ {
+ usbHostPointer->periodicListPointer = tempTransfer->next;
+ }
+ else
+ {
+ prevTtransfer->next = tempTransfer->next;
+ }
+ while (tempTransfer != NULL)
+ {
+ prevTtransfer = tempTransfer;
+ tempTransfer = tempTransfer->next;
+ }
+ prevTtransfer->next = firstTransfer;
+ firstTransfer->next = NULL;
+ USB_OsaEventSet(usbHostPointer->khciEventPointer, USB_KHCI_EVENT_MSG);
+ }
+ USB_HostKhciUnlock();
+ return;
+ }
+ prevTtransfer = tempTransfer;
+ tempTransfer = tempTransfer->next;
+ }
+ }
+ /* will get the first transfer from active list if no active transfer in async list */
+ if (usbHostPointer->asyncListAvtive)
+ {
+ firstTransfer = tempTransfer = usbHostPointer->asyncListPointer;
+ *transfer = firstTransfer;
+
+ if (tempTransfer->next != NULL)
+ {
+ usbHostPointer->asyncListPointer = tempTransfer->next;
+ }
+ else
+ {
+ USB_HostKhciUnlock();
+ return;
+ }
+ tempTransfer = tempTransfer->next;
+ while (tempTransfer != NULL)
+ {
+ prevTtransfer = tempTransfer;
+ tempTransfer = tempTransfer->next;
+ }
+ prevTtransfer->next = firstTransfer;
+ firstTransfer->next = NULL;
+ }
+ USB_HostKhciUnlock();
+}
+
+/*!
+ * @brief unlink transfer from periodic and async khci transfer list.
+ *
+ * @param handle Pointer of the host khci controller handle.
+ * @param transfer Pointer of transfer node struct, which will be unlink from transfer list.
+ *
+ */
+static void _USB_HostKhciUnlinkTrRequestFromList(usb_host_controller_handle handle, usb_host_transfer_t *transfer)
+{
+ usb_host_transfer_t *temptr = NULL;
+ usb_host_transfer_t *pretr = NULL;
+ usb_khci_host_state_struct_t *usbHostPointer = (usb_khci_host_state_struct_t *)handle;
+
+ if ((handle == NULL) || (transfer == NULL))
+ {
+ return;
+ }
+
+ USB_HostKhciLock();
+ if (usbHostPointer->asyncListAvtive == 1U)
+ {
+ temptr = usbHostPointer->asyncListPointer;
+ if (transfer == temptr)
+ {
+ usbHostPointer->asyncListPointer = temptr->next;
+ }
+ else
+ {
+ while (temptr != NULL)
+ {
+ pretr = temptr;
+ temptr = temptr->next;
+ if (transfer == temptr)
+ {
+ pretr->next = temptr->next;
+ break;
+ }
+ }
+ }
+ if (usbHostPointer->asyncListPointer == NULL)
+ {
+ usbHostPointer->asyncListAvtive = 0U;
+ }
+ }
+ if (usbHostPointer->periodicListAvtive == 1U)
+ {
+ temptr = usbHostPointer->periodicListPointer;
+ if (transfer == temptr)
+ {
+ usbHostPointer->periodicListPointer = temptr->next;
+ }
+ else
+ {
+ while (temptr != NULL)
+ {
+ pretr = temptr;
+ temptr = temptr->next;
+ if (transfer == temptr)
+ {
+ pretr->next = temptr->next;
+ break;
+ }
+ }
+ }
+ if (usbHostPointer->periodicListPointer == NULL)
+ {
+ usbHostPointer->periodicListAvtive = 0U;
+ }
+ }
+ USB_HostKhciUnlock();
+}
+
+/*!
+ * @brief link transfer to periodic and async khci transfer list.
+ *
+ * @param handle Pointer of the host khci controller handle.
+ * @param transfer Pointer of transfer node struct, which will be link to transfer list.
+ *
+ */
+static usb_status_t _USB_HostKhciLinkTrRequestToList(usb_host_controller_handle controllerHandle,
+ usb_host_transfer_t *transfer)
+{
+ usb_host_transfer_t *temptransfer;
+ usb_khci_host_state_struct_t *usbHostPointer = (usb_khci_host_state_struct_t *)controllerHandle;
+
+ if ((transfer == NULL))
+ {
+ return kStatus_USB_InvalidParameter;
+ }
+
+ USB_HostKhciLock();
+ if ((transfer->transferPipe->pipeType == USB_ENDPOINT_ISOCHRONOUS) ||
+ (transfer->transferPipe->pipeType == USB_ENDPOINT_INTERRUPT))
+ {
+ if (usbHostPointer->periodicListAvtive == 0U)
+ {
+ usbHostPointer->periodicListPointer = transfer;
+ transfer->next = NULL;
+ usbHostPointer->periodicListAvtive = 1U;
+ }
+ else
+ {
+ temptransfer = usbHostPointer->periodicListPointer;
+ while (temptransfer->next != NULL)
+ {
+ temptransfer = temptransfer->next;
+ }
+ temptransfer->next = transfer;
+ transfer->next = NULL;
+ }
+ }
+ else if ((transfer->transferPipe->pipeType == USB_ENDPOINT_CONTROL) ||
+ (transfer->transferPipe->pipeType == USB_ENDPOINT_BULK))
+ {
+ if (usbHostPointer->asyncListAvtive == 0U)
+ {
+ usbHostPointer->asyncListPointer = transfer;
+ transfer->next = NULL;
+ usbHostPointer->asyncListAvtive = 1U;
+ }
+ else
+ {
+ temptransfer = usbHostPointer->asyncListPointer;
+ while (temptransfer->next != NULL)
+ {
+ temptransfer = temptransfer->next;
+ }
+ temptransfer->next = transfer;
+ transfer->next = NULL;
+ }
+ }
+ else
+ {
+ }
+ USB_HostKhciUnlock();
+ return kStatus_USB_Success;
+}
+
+/*!
+ * @brief khci process tranfer callback function.
+ *
+ * @param controllerHandle Pointer of the host khci controller handle.
+ * @param transfer Pointer of transfer , which will be process callback.
+ * @param err The return value of transfer.
+ *
+ */
+static void _USB_HostKhciProcessTrCallback(usb_host_controller_handle controllerHandle,
+ usb_host_transfer_t *transfer,
+ int32_t err)
+{
+ usb_status_t status = kStatus_USB_Success;
+
+ if (err == USB_KHCI_ATOM_TR_STALL)
+ {
+ status = kStatus_USB_TransferStall;
+ }
+ else if ((err == USB_KHCI_ATOM_TR_NAK) || (err >= 0))
+ {
+ status = kStatus_USB_Success;
+
+ if (err == USB_KHCI_ATOM_TR_NAK)
+ {
+ status = kStatus_USB_TransferFailed;
+ }
+ }
+ else if (err < 0)
+ {
+ status = kStatus_USB_TransferFailed;
+ }
+ else
+ {
+ }
+
+ transfer->callbackFn(transfer->callbackParam, transfer, status);
+}
+
+/*!
+ * @brief khci transaction done process function.
+ *
+ * @param usbHostPointer Pointer of the host khci controller handle.
+ * @param transfer Pointer of transfer node struct, which will be handled process done.
+ *1400
+ */
+static int32_t _USB_HostKhciTransactionDone(usb_khci_host_state_struct_t *usbHostPointer, usb_host_transfer_t *transfer)
+{
+ uint32_t bd;
+ uint8_t err;
+ int32_t transferResult = 0U;
+ uint32_t type = kTr_Unknown;
+ uint32_t *bdPointer = NULL;
+ usb_host_pipe_t *pipeDescPointer = transfer->transferPipe;
+
+ if (pipeDescPointer->pipeType == USB_ENDPOINT_CONTROL)
+ {
+ if (transfer->setupStatus == kTransfer_Setup0)
+ {
+ type = kTr_Ctrl;
+ }
+ else if ((transfer->setupStatus == kTransfer_Setup1))
+ {
+ if (transfer->transferLength)
+ {
+ if (transfer->direction == USB_IN)
+ {
+ type = kTr_In;
+ }
+ else
+ {
+ type = kTr_Out;
+ }
+ }
+ else
+ {
+ type = kTr_In;
+ }
+ }
+ else if (transfer->setupStatus == kTransfer_Setup2)
+ {
+ if (transfer->transferLength)
+ {
+ if (transfer->direction == USB_IN)
+ {
+ type = kTr_Out;
+ }
+ else
+ {
+ type = kTr_In;
+ }
+ }
+ else
+ {
+ type = kTr_In;
+ }
+ }
+ else if (transfer->setupStatus == kTransfer_Setup3)
+ {
+ type = kTr_In;
+ }
+ else
+ {
+ }
+ }
+ else
+ {
+ if (pipeDescPointer->direction == USB_IN)
+ {
+ type = kTr_In;
+ }
+ else if (pipeDescPointer->direction == USB_OUT)
+ {
+ type = kTr_Out;
+ }
+ else
+ {
+ }
+ }
+ switch (type)
+ {
+ case kTr_Ctrl:
+ case kTr_Out:
+ usbHostPointer->txBd ^= 1U;
+ bdPointer = (uint32_t *)USB_KHCI_BD_PTR(0U, 1, usbHostPointer->txBd);
+ usbHostPointer->txBd ^= 1U;
+ break;
+
+ case kTr_In:
+ usbHostPointer->rxBd ^= 1U;
+ bdPointer = (uint32_t *)USB_KHCI_BD_PTR(0U, 0U, usbHostPointer->rxBd);
+ usbHostPointer->rxBd ^= 1U;
+ break;
+
+ default:
+ bdPointer = NULL;
+ break;
+ }
+
+ if (bdPointer == NULL)
+ {
+ return -1;
+ }
+
+ bd = *bdPointer;
+ err = usbHostPointer->usbRegBase->ERRSTAT;
+ if (err & (USB_ERRSTAT_PIDERR_MASK | USB_ERRSTAT_CRC5EOF_MASK | USB_ERRSTAT_CRC16_MASK | USB_ERRSTAT_DFN8_MASK |
+ USB_ERRSTAT_DMAERR_MASK | USB_ERRSTAT_BTSERR_MASK))
+ {
+ transferResult = -(int32_t)err;
+ return transferResult;
+ }
+ else
+ {
+ if (bd & USB_KHCI_BD_OWN)
+ {
+#ifdef HOST_ECHO
+ usb_echo("Own bit is not clear 0x%x\n", (unsigned int)bd);
+#endif
+ *bdPointer = 0U;
+ }
+ if ((pipeDescPointer->pipeType == USB_ENDPOINT_ISOCHRONOUS))
+ {
+ transferResult = (bd >> 16) & 0x3ffU;
+ }
+ else
+ {
+ switch (bd >> 2 & 0xfU)
+ {
+ case 0x03: /* Last Transfer status is DATA0 */
+ case 0x0b: /* Last Transfer status is DATA1 */
+ case 0x02: /* Last Transfer status is ACK */
+ transferResult = (bd >> 16) & 0x3ffU;
+ /* switch data toggle */
+ pipeDescPointer->nextdata01 ^= 1U;
+ break;
+
+ case 0x0e: /* Last Transfer status is STALL */
+ transferResult = USB_KHCI_ATOM_TR_STALL;
+ break;
+
+ case 0x0a: /* Last Transfer status is NAK */
+ transferResult = USB_KHCI_ATOM_TR_NAK;
+ break;
+
+ case 0x00: /* Last Transfer status is bus timeout **/
+ transferResult = USB_KHCI_ATOM_TR_BUS_TIMEOUT;
+ break;
+
+ case 0x0f: /* Last Transfer status is data error */
+ transferResult = USB_KHCI_ATOM_TR_DATA_ERROR;
+ break;
+ default:
+ break;
+ }
+ }
+ }
+
+ if ((kTr_In == type) && (0 == usbHostPointer->sXferSts.isDmaAlign))
+ {
+ usbHostPointer->sXferSts.isDmaAlign = 1U;
+ if (transferResult > 0)
+ {
+ for (int j = 0; j < transferResult; j++)
+ {
+ usbHostPointer->sXferSts.rxBufOrig[j] = usbHostPointer->sXferSts.rxBuf[j];
+ }
+ }
+ }
+ return transferResult;
+}
+
+/*!
+ * @brief khci atom transaction process function.
+ *
+ * @param usbHostPointer Pointer of the host khci controller instance.
+ * @param type The USB transfer type.
+ * @param pipeDescPointer Pointer of usb pipe desc.
+ * @param bufPointer The memory address is needed to be transferred.
+ * @param len Transferred data length.
+ *
+ * @return 0 mean sucess or other opertor failure error code.
+ *
+ */
+static int32_t _USB_HostKhciAtomNonblockingTransaction(usb_khci_host_state_struct_t *usbHostPointer,
+ uint32_t type,
+ usb_host_pipe_t *pipeDescPointer,
+ uint8_t *bufPointer,
+ uint32_t len)
+{
+ uint32_t *bdPointer = NULL;
+ uint8_t *buf = bufPointer;
+ int32_t transferResult;
+ uint32_t speed;
+ uint32_t address;
+ uint32_t level;
+ uint8_t counter = 0U;
+ uint32_t eventBit;
+ usb_osa_status_t osaStatus;
+ uint8_t epCtlVal;
+
+ len = (len > pipeDescPointer->maxPacketSize) ? pipeDescPointer->maxPacketSize : len;
+ USB_HostHelperGetPeripheralInformation(pipeDescPointer->deviceHandle, kUSB_HostGetDeviceLevel, &level);
+ USB_HostHelperGetPeripheralInformation(pipeDescPointer->deviceHandle, kUSB_HostGetDeviceSpeed, &speed);
+ USB_HostHelperGetPeripheralInformation(pipeDescPointer->deviceHandle, kUSB_HostGetDeviceAddress, &address);
+
+ if (speed == USB_SPEED_LOW)
+ {
+ usbHostPointer->usbRegBase->ADDR |= USB_ADDR_LSEN_MASK;
+ }
+ else
+ {
+ usbHostPointer->usbRegBase->ADDR &= (~USB_ADDR_LSEN_MASK);
+ }
+ usbHostPointer->usbRegBase->ADDR = ((usbHostPointer->usbRegBase->ADDR & (~USB_ADDR_ADDR_MASK)) |
+ ((((address) << USB_ADDR_ADDR_SHIFT) & USB_ADDR_ADDR_MASK)));
+
+#if (FSL_FEATURE_USB_KHCI_HOST_ENABLED)
+ epCtlVal = (level == 1 ? USB_ENDPT_HOSTWOHUB_MASK : 0U) | USB_ENDPT_RETRYDIS_MASK | USB_ENDPT_EPTXEN_MASK |
+ USB_ENDPT_EPRXEN_MASK |
+ ((pipeDescPointer->pipeType == USB_ENDPOINT_ISOCHRONOUS ? 0 : USB_ENDPT_EPHSHK_MASK));
+#else
+ epCtlVal = USB_ENDPT_EPTXEN_MASK | USB_ENDPT_EPRXEN_MASK |
+ ((pipeDescPointer->pipeType == USB_ENDPOINT_ISOCHRONOUS ? 0 : USB_ENDPT_EPHSHK_MASK));
+#endif
+ usbHostPointer->usbRegBase->ENDPOINT[0U].ENDPT = epCtlVal;
+
+ transferResult = 0U;
+ counter = 0U;
+ /* wait for USB conttoller is ready, and with timeout */
+ while ((usbHostPointer->usbRegBase->CTL) & USB_CTL_TXSUSPENDTOKENBUSY_MASK)
+ {
+ _USB_HostKhciDelay(usbHostPointer, 1U);
+ osaStatus = USB_OsaEventWait(usbHostPointer->khciEventPointer, USB_KHCI_EVENT_TOK_DONE, 0U, 1, &eventBit);
+ if (osaStatus == kStatus_USB_OSA_Success)
+ {
+ transferResult = USB_KHCI_ATOM_TR_RESET;
+ break;
+ }
+ else
+ {
+ counter++;
+ if (counter >= 3)
+ {
+ transferResult = USB_KHCI_ATOM_TR_CRC_ERROR;
+ return transferResult;
+ }
+ }
+ }
+
+ if (!transferResult)
+ {
+#if defined(FSL_FEATURE_USB_KHCI_DYNAMIC_SOF_THRESHOLD_COMPARE_ENABLED) && \
+ (FSL_FEATURE_USB_KHCI_DYNAMIC_SOF_THRESHOLD_COMPARE_ENABLED == 1U)
+ if (speed == USB_SPEED_LOW)
+ {
+ usbHostPointer->usbRegBase->SOFTHLD = (len * 12 * 7 / 6 + KHCICFG_THSLD_DELAY) / 8;
+ }
+ else
+ {
+ usbHostPointer->usbRegBase->SOFTHLD = (len * 7 / 6 + KHCICFG_THSLD_DELAY) / 8;
+ }
+#endif
+ usbHostPointer->usbRegBase->ERRSTAT = 0xffU;
+
+ if ((kTr_In == type) && ((len & USB_MEM4_ALIGN_MASK) || ((uint32_t)bufPointer & USB_MEM4_ALIGN_MASK)))
+ {
+ if ((usbHostPointer->khciSwapBufPointer != NULL) && (len <= USB_HOST_CONFIG_KHCI_DMA_ALIGN_BUFFER))
+ {
+ buf = (uint8_t *)USB_MEM4_ALIGN((uint32_t)(usbHostPointer->khciSwapBufPointer + 4));
+ usbHostPointer->sXferSts.rxBuf = buf;
+ usbHostPointer->sXferSts.rxBufOrig = bufPointer;
+ usbHostPointer->sXferSts.rxLen = len;
+ usbHostPointer->sXferSts.isDmaAlign = 0U;
+ }
+ }
+ else
+ {
+ usbHostPointer->sXferSts.isDmaAlign = 1U;
+ }
+
+ switch (type)
+ {
+ case kTr_Ctrl:
+ bdPointer = (uint32_t *)USB_KHCI_BD_PTR(0U, 1, usbHostPointer->txBd);
+ *(bdPointer + 1U) = USB_LONG_TO_LITTLE_ENDIAN((uint32_t)buf);
+ *bdPointer = USB_LONG_TO_LITTLE_ENDIAN(USB_KHCI_BD_BC(len) | USB_KHCI_BD_OWN);
+ usbHostPointer->usbRegBase->TOKEN =
+ (USB_TOKEN_TOKENENDPT((uint8_t)pipeDescPointer->endpointAddress) | USB_TOKEN_TOKENPID(0xD));
+ usbHostPointer->txBd ^= 1U;
+ break;
+ case kTr_In:
+ bdPointer = (uint32_t *)USB_KHCI_BD_PTR(0U, 0U, usbHostPointer->rxBd);
+ *(bdPointer + 1U) = USB_LONG_TO_LITTLE_ENDIAN((uint32_t)buf);
+ *bdPointer = USB_LONG_TO_LITTLE_ENDIAN(USB_KHCI_BD_BC(len) | USB_KHCI_BD_OWN |
+ USB_KHCI_BD_DATA01(pipeDescPointer->nextdata01));
+ usbHostPointer->usbRegBase->TOKEN =
+ (USB_TOKEN_TOKENENDPT((uint8_t)pipeDescPointer->endpointAddress) | USB_TOKEN_TOKENPID(0x9));
+ usbHostPointer->rxBd ^= 1U;
+ break;
+ case kTr_Out:
+ bdPointer = (uint32_t *)USB_KHCI_BD_PTR(0U, 1, usbHostPointer->txBd);
+ *(bdPointer + 1U) = USB_LONG_TO_LITTLE_ENDIAN((uint32_t)buf);
+ *bdPointer = USB_LONG_TO_LITTLE_ENDIAN(USB_KHCI_BD_BC(len) | USB_KHCI_BD_OWN |
+ USB_KHCI_BD_DATA01(pipeDescPointer->nextdata01));
+ usbHostPointer->usbRegBase->TOKEN =
+ (USB_TOKEN_TOKENENDPT((uint8_t)pipeDescPointer->endpointAddress) | USB_TOKEN_TOKENPID(0x1));
+ usbHostPointer->txBd ^= 1U;
+ break;
+ default:
+ bdPointer = NULL;
+ break;
+ }
+ }
+
+ return transferResult;
+}
+
+/*!
+ * @brief khci host start tramsfer.
+ *
+ * @param handle Pointer of the host khci controller handle.
+ * @param transfer Pointer of transfer node struct, which will transfer.
+ *
+ * @retval kKhci_TrTransmiting khci host transaction prime successfully, will enter next stage.
+ * @retval kKhci_TrTransmitDone khci host transaction prime unsuccessfully, will enter exit stage.
+ *
+ */
+static khci_tr_state_t _USB_HostKhciStartTranfer(usb_host_controller_handle handle, usb_host_transfer_t *transfer)
+{
+ static int32_t transferResult;
+ uint8_t *buf;
+ usb_khci_host_state_struct_t *usbHostPointer = (usb_khci_host_state_struct_t *)handle;
+
+ if (transfer->transferPipe->pipeType == USB_ENDPOINT_CONTROL)
+ {
+ if ((transfer->setupStatus == kTransfer_Setup0))
+ {
+ transferResult = _USB_HostKhciAtomNonblockingTransaction(usbHostPointer, kTr_Ctrl, transfer->transferPipe,
+ (uint8_t *)&transfer->setupPacket, 8U);
+ }
+ else if (transfer->setupStatus == kTransfer_Setup1)
+ {
+ if (transfer->transferLength)
+ {
+ buf = transfer->transferBuffer;
+ buf += transfer->transferSofar;
+ transferResult = _USB_HostKhciAtomNonblockingTransaction(
+ usbHostPointer, (transfer->direction == USB_IN) ? kTr_In : kTr_Out, transfer->transferPipe, buf,
+ transfer->transferLength - transfer->transferSofar);
+ }
+ else
+ {
+ transfer->transferPipe->nextdata01 = 1U;
+ transfer->setupStatus = kTransfer_Setup3;
+ transferResult =
+ _USB_HostKhciAtomNonblockingTransaction(usbHostPointer, kTr_In, transfer->transferPipe, 0U, 0U);
+ }
+ }
+ else if (transfer->setupStatus == kTransfer_Setup2)
+ {
+ if (transfer->transferLength)
+ {
+ transfer->transferPipe->nextdata01 = 1U;
+
+ transferResult = _USB_HostKhciAtomNonblockingTransaction(
+ usbHostPointer, (transfer->direction == USB_IN) ? kTr_Out : kTr_In, transfer->transferPipe, 0U, 0U);
+ }
+ else
+ {
+ transfer->transferPipe->nextdata01 = 1U;
+ transferResult =
+ _USB_HostKhciAtomNonblockingTransaction(usbHostPointer, kTr_In, transfer->transferPipe, 0U, 0U);
+ }
+ }
+ else if (transfer->setupStatus == kTransfer_Setup3)
+ {
+ transfer->transferPipe->nextdata01 = 1U;
+ transferResult =
+ _USB_HostKhciAtomNonblockingTransaction(usbHostPointer, kTr_In, transfer->transferPipe, 0U, 0U);
+ }
+ else
+ {
+ }
+ }
+ else
+ {
+ buf = transfer->transferBuffer;
+ buf += transfer->transferSofar;
+ transferResult = _USB_HostKhciAtomNonblockingTransaction(
+ usbHostPointer, (transfer->transferPipe->direction == USB_IN) ? kTr_In : kTr_Out, transfer->transferPipe,
+ buf, transfer->transferLength - transfer->transferSofar);
+ }
+
+ transfer->transferResult = transferResult;
+
+ if (transfer->transferResult == 0U)
+ {
+ usbHostPointer->trState = kKhci_TrTransmiting;
+ }
+ else
+ {
+ usbHostPointer->trState = kKhci_TrTransmitDone;
+ }
+ return (khci_tr_state_t)usbHostPointer->trState;
+}
+
+/*!
+ * @brief khci host finish tramsfer.
+ *
+ * @param handle Pointer of the host khci controller handle.
+ * @param transfer Pointer of transfer node struct, which will be transfer.
+ *
+ * @retval kKhci_TrGetMsg The current of transaction is transfer done, will enter first stage.
+ * @retval kKhci_TrTransmitDone All of khci host transaction of the transfer have transfer done, will enter exit
+ * stage.
+ *
+ */
+static khci_tr_state_t _USB_HostKhciFinishTranfer(usb_host_controller_handle handle, usb_host_transfer_t *transfer)
+{
+ static int32_t transferResult;
+ usb_khci_host_state_struct_t *usbHostPointer = (usb_khci_host_state_struct_t *)handle;
+
+ transfer->transferResult = transferResult = _USB_HostKhciTransactionDone(usbHostPointer, transfer);
+ if (transferResult >= 0)
+ {
+ if (transfer->transferPipe->pipeType == USB_ENDPOINT_CONTROL)
+ {
+ if ((transfer->setupStatus == kTransfer_Setup2) || (transfer->setupStatus == kTransfer_Setup3))
+ {
+ usbHostPointer->trState = kKhci_TrTransmitDone;
+ }
+ else
+ {
+ usbHostPointer->trState = kKhci_TrStartTransmit;
+ if (transfer->setupStatus == kTransfer_Setup1)
+ {
+ transfer->transferSofar += transferResult;
+ if (((transfer->transferLength - transfer->transferSofar) <= 0U) ||
+ (transferResult < transfer->transferPipe->maxPacketSize))
+ {
+ transfer->setupStatus++;
+ }
+ }
+ else
+ {
+ transfer->setupStatus++;
+ }
+ }
+ }
+ else
+ {
+ transfer->transferSofar += transferResult;
+ if (((transfer->transferLength - transfer->transferSofar) == 0U) ||
+ (transferResult < transfer->transferPipe->maxPacketSize))
+ {
+ usbHostPointer->trState = kKhci_TrTransmitDone;
+ }
+ else
+ {
+ usbHostPointer->trState = kKhci_TrStartTransmit;
+ }
+ }
+ }
+ else
+ {
+ if ((transferResult == USB_KHCI_ATOM_TR_NAK))
+ {
+ if (transfer->transferPipe->pipeType == USB_ENDPOINT_INTERRUPT)
+ {
+ usbHostPointer->trState = kKhci_TrGetMsg;
+ USB_OsaEventSet(usbHostPointer->khciEventPointer, USB_KHCI_EVENT_MSG);
+ }
+ else
+ {
+ if ((_USB_HostKhciGetFrameCountSum(usbHostPointer) - transfer->frame) > transfer->nakTimeout)
+ {
+ usbHostPointer->trState = kKhci_TrTransmitDone;
+ transfer->transferResult = USB_KHCI_ATOM_TR_BUS_TIMEOUT;
+ }
+ else
+ {
+ usbHostPointer->trState = kKhci_TrGetMsg;
+ USB_OsaEventSet(usbHostPointer->khciEventPointer, USB_KHCI_EVENT_MSG);
+ }
+ }
+ }
+ else
+ {
+ usbHostPointer->trState = kKhci_TrTransmitDone;
+ }
+ }
+ return (khci_tr_state_t)usbHostPointer->trState;
+}
+
+/*!
+ * @brief host khci controller transfer clear up
+ *
+ * The function is used to handle controller transfer clear up.
+ * @param handle Pointer of the host khci controller handle.
+ *
+ *
+ */
+void _USB_HostKhciTransferClearUp(usb_host_controller_handle controllerHandle)
+{
+ usb_khci_host_state_struct_t *usbHostPointer = (usb_khci_host_state_struct_t *)controllerHandle;
+ usb_host_transfer_t *trCancel;
+
+ USB_HostKhciLock();
+ trCancel = usbHostPointer->periodicListPointer;
+ USB_HostKhciUnlock();
+ while (trCancel != NULL)
+ {
+ _USB_HostKhciUnlinkTrRequestFromList(controllerHandle, trCancel);
+ trCancel->callbackFn(trCancel->callbackParam, trCancel, kStatus_USB_TransferCancel);
+ USB_HostKhciLock();
+ trCancel = usbHostPointer->periodicListPointer;
+ USB_HostKhciUnlock();
+ }
+
+ USB_HostKhciLock();
+ trCancel = usbHostPointer->asyncListPointer;
+ USB_HostKhciUnlock();
+ while (trCancel != NULL)
+ {
+ _USB_HostKhciUnlinkTrRequestFromList(controllerHandle, trCancel);
+ trCancel->callbackFn(trCancel->callbackParam, trCancel, kStatus_USB_TransferCancel);
+ USB_HostKhciLock();
+ trCancel = usbHostPointer->asyncListPointer;
+ USB_HostKhciUnlock();
+ }
+ usbHostPointer->trState = kKhci_TrGetMsg;
+}
+
+/*!
+ * @brief host khci controller transfer state machine
+ *
+ * The function is used to handle controller transfer state machine.
+ * @param handle Pointer of the host khci controller handle.
+ * @param transfer Pointer of transfer node struct, which will be transfer.
+ *
+ *
+ */
+void _USB_HostKhciTransferStateMachine(usb_host_controller_handle controllerHandle, usb_host_transfer_t **ptransfer)
+{
+ usb_khci_host_state_struct_t *usbHostPointer = (usb_khci_host_state_struct_t *)controllerHandle;
+ usb_host_transfer_t *transfer = *ptransfer;
+ usb_host_transfer_t *tempTransfer = NULL;
+ uint32_t eventBit = 0;
+
+ switch (usbHostPointer->trState)
+ {
+ case kKhci_TrGetMsg:
+ transfer = NULL;
+ _USB_HostKhciGetRightTrRequest(controllerHandle, &transfer);
+ if (transfer != NULL)
+ {
+ *ptransfer = transfer;
+ usbHostPointer->trState = _USB_HostKhciStartTranfer(controllerHandle, transfer);
+ usbHostPointer->trState = kKhci_TrTransmiting;
+ }
+ break;
+
+ case kKhci_IsoTrGetMsg:
+ *ptransfer = NULL;
+ if (usbHostPointer->periodicListAvtive)
+ {
+ tempTransfer = usbHostPointer->periodicListPointer;
+ while (tempTransfer != NULL)
+ {
+ if ((_USB_HostKhciGetFrameCount(usbHostPointer) % tempTransfer->transferPipe->interval == 0U) &&
+ (tempTransfer->transferPipe->pipeType == USB_ENDPOINT_ISOCHRONOUS))
+ {
+ *ptransfer = tempTransfer;
+
+ _USB_HostKhciStartTranfer(controllerHandle, tempTransfer);
+ usbHostPointer->trState = kKhci_TrTransmiting;
+ if (kStatus_USB_OSA_Success == USB_OsaEventWait(usbHostPointer->khciEventPointer,
+ USB_KHCI_EVENT_TOK_DONE, 0U, 0, &eventBit))
+ {
+ if (eventBit & USB_KHCI_EVENT_TOK_DONE)
+ {
+ _USB_HostKhciTransactionDone(usbHostPointer, tempTransfer);
+ _USB_HostKhciUnlinkTrRequestFromList(usbHostPointer, tempTransfer);
+ _USB_HostKhciProcessTrCallback(usbHostPointer, tempTransfer, transfer->transferResult);
+ usbHostPointer->trState = kKhci_TrGetMsg;
+ }
+ }
+ else
+ {
+ usbHostPointer->trState = kKhci_TrTransmiting;
+ }
+ break;
+ }
+ tempTransfer = tempTransfer->next;
+ }
+ }
+ if (*ptransfer == NULL)
+ {
+ usbHostPointer->trState = kKhci_TrGetMsg;
+ }
+ break;
+
+ case kKhci_TrStartTransmit:
+ if (transfer != NULL)
+ {
+ usbHostPointer->trState = _USB_HostKhciStartTranfer(controllerHandle, transfer);
+ }
+ break;
+
+ case kKhci_TrTransmiting:
+ if (transfer != NULL)
+ {
+ if ((_USB_HostKhciGetFrameCountSum(usbHostPointer) - transfer->frame) > USB_TIMEOUT_OTHER)
+ {
+ if ((transfer->transferPipe->pipeType == USB_ENDPOINT_CONTROL) ||
+ (transfer->transferPipe->pipeType == USB_ENDPOINT_BULK))
+ {
+ /* clear current bdt status */
+ _USB_HostKhciTransactionDone(usbHostPointer, transfer);
+ usbHostPointer->trState = kKhci_TrTransmitDone;
+ transfer->transferResult = USB_KHCI_ATOM_TR_BUS_TIMEOUT;
+ return;
+ }
+ }
+ }
+ break;
+
+ case kKhci_TrTransmitDone:
+ if (transfer != NULL)
+ {
+ _USB_HostKhciUnlinkTrRequestFromList(usbHostPointer, transfer);
+ _USB_HostKhciProcessTrCallback(usbHostPointer, transfer, transfer->transferResult);
+ usbHostPointer->trState = kKhci_TrGetMsg;
+ if ((usbHostPointer->asyncListAvtive == 1U) || (usbHostPointer->periodicListAvtive == 1U))
+ {
+ USB_OsaEventSet(usbHostPointer->khciEventPointer, USB_KHCI_EVENT_MSG);
+ }
+ }
+ break;
+
+ default:
+ break;
+ }
+}
+
+/*!
+ * @brief khci task function.
+ *
+ * The function is used to handle KHCI controller message.
+ * In the BM environment, this function should be called periodically in the main function.
+ * And in the RTOS environment, this function should be used as a function entry to create a task.
+ *
+ * @param hostHandle The host handle.
+ */
+void USB_HostKhciTaskFunction(void *hostHandle)
+{
+ volatile ptr_usb_host_khci_state_struct_t usbHostPointer;
+ uint32_t eventBit = 0;
+ static usb_host_transfer_t *transfer;
+
+ if (hostHandle == NULL)
+ {
+ return;
+ }
+
+ usbHostPointer = (usb_khci_host_state_struct_t *)(((usb_host_instance_t *)hostHandle)->controllerHandle);
+ if (USB_OsaEventWait(usbHostPointer->khciEventPointer, 0xff, 0U, 1U, &eventBit) ==
+ kStatus_USB_OSA_Success) /* wait all event */
+ {
+ if (eventBit & USB_KHCI_EVENT_ATTACH)
+ {
+ _USB_HostKhciAttach(usbHostPointer);
+ usbHostPointer->trState = kKhci_TrGetMsg;
+ }
+ if (eventBit & USB_KHCI_EVENT_RESET)
+ {
+ _USB_HostKhciReset(usbHostPointer);
+ }
+ if (eventBit & USB_KHCI_EVENT_DETACH)
+ {
+ _USB_HostKhciDetach(usbHostPointer);
+ }
+ if (eventBit & USB_KHCI_EVENT_SOF_TOK)
+ {
+ if ((kKhci_TrGetMsg == usbHostPointer->trState) && (usbHostPointer->deviceAttached))
+ {
+ usbHostPointer->trState = kKhci_IsoTrGetMsg;
+ _USB_HostKhciTransferStateMachine(usbHostPointer, &transfer);
+ }
+ }
+ if (eventBit & USB_KHCI_EVENT_TOK_DONE)
+ {
+ if (transfer != NULL)
+ {
+ usbHostPointer->trState =
+ _USB_HostKhciFinishTranfer(((usb_host_instance_t *)hostHandle)->controllerHandle, transfer);
+ }
+ }
+ }
+ if (usbHostPointer->deviceAttached)
+ {
+ _USB_HostKhciTransferStateMachine(usbHostPointer, &transfer);
+ }
+ else
+ {
+ _USB_HostKhciTransferClearUp(usbHostPointer);
+ }
+}
+
+/*!
+ * @brief create the USB host khci instance.
+ *
+ * This function initializes the USB host khci controller driver.
+ *
+ * @param controllerId The controller id of the USB IP. Please refer to the enumeration usb_controller_index_t.
+ * @param hostHandle The host level handle.
+ * @param controllerHandle Return the controller instance handle.
+ *
+ * @retval kStatus_USB_Success The host is initialized successfully.
+ * @retval kStatus_USB_AllocFail allocate memory fail.
+ * @retval kStatus_USB_Error host mutex create fail, KHCI/EHCI mutex or KHCI/EHCI event create fail.
+ * Or, KHCI/EHCI IP initialize fail.
+ *
+ */
+usb_status_t USB_HostKhciCreate(uint8_t controllerId,
+ usb_host_handle hostHandle,
+ usb_host_controller_handle *controllerHandle)
+{
+ usb_khci_host_state_struct_t *usbHostPointer;
+ usb_status_t status = kStatus_USB_Success;
+ usb_osa_status_t osaStatus;
+ uint32_t usb_base_addrs[] = USB_BASE_ADDRS;
+
+ if (((controllerId - kUSB_ControllerKhci0) >= (uint8_t)USB_HOST_CONFIG_KHCI) ||
+ ((controllerId - kUSB_ControllerKhci0) >= (sizeof(usb_base_addrs) / sizeof(uint32_t))))
+ {
+ return kStatus_USB_ControllerNotFound;
+ }
+
+ usbHostPointer = (usb_khci_host_state_struct_t *)USB_OsaMemoryAllocate(sizeof(usb_khci_host_state_struct_t));
+ if (NULL == usbHostPointer)
+ {
+ *controllerHandle = NULL;
+ return kStatus_USB_AllocFail;
+ }
+
+ /* Allocate the USB Host Pipe Descriptors */
+ usbHostPointer->pipeDescriptorBasePointer = NULL;
+ usbHostPointer->hostHandle = hostHandle;
+ *controllerHandle = (usb_host_handle)usbHostPointer;
+
+ if (NULL == (usbHostPointer->khciSwapBufPointer =
+ (uint8_t *)USB_OsaMemoryAllocate(USB_HOST_CONFIG_KHCI_DMA_ALIGN_BUFFER + 4)))
+ {
+#ifdef HOST_DEBUG_
+ usb_echo("usbHostPointer->khciSwapBufPointer- memory allocation failed");
+#endif
+ USB_HostKhciDestory(controllerHandle);
+ return kStatus_USB_AllocFail;
+ }
+
+ /* init khci mutext */
+ osaStatus = USB_OsaMutexCreate(&usbHostPointer->khciMutex);
+ if (osaStatus != kStatus_USB_OSA_Success)
+ {
+#ifdef HOST_ECHO
+ usb_echo("khci mutex init fail\r\n");
+#endif
+ USB_HostKhciDestory(controllerHandle);
+ return kStatus_USB_Error;
+ }
+
+ USB_OsaEventCreate(&usbHostPointer->khciEventPointer, 1U);
+ if (usbHostPointer->khciEventPointer == NULL)
+ {
+#ifdef HOST_ECHO
+ usb_echo(" memalloc failed in usb_khci_init\n");
+#endif
+
+ return kStatus_USB_AllocFail;
+ } /* Endif */
+
+ usbHostPointer->usbRegBase = (USB_Type *)usb_base_addrs[controllerId - kUSB_ControllerKhci0];
+
+ usbHostPointer->asyncListAvtive = 0U;
+ usbHostPointer->periodicListAvtive = 0U;
+ usbHostPointer->periodicListPointer = NULL;
+ usbHostPointer->asyncListPointer = NULL;
+ usbHostPointer->sXferSts.isDmaAlign = 0U;
+
+ /* set internal register pull down */
+ usbHostPointer->usbRegBase->CTL = USB_CTL_SE0_MASK;
+
+ /* Reset USB CTRL register */
+ usbHostPointer->usbRegBase->CTL = 0UL;
+ usbHostPointer->usbRegBase->ISTAT = 0xffU;
+ /* Enable week pull-downs, useful for detecting detach (effectively bus discharge) */
+ usbHostPointer->usbRegBase->USBCTRL |= USB_USBCTRL_PDE_MASK;
+ /* Remove suspend state */
+ usbHostPointer->usbRegBase->USBCTRL &= (~USB_USBCTRL_SUSP_MASK);
+ usbHostPointer->usbRegBase->CTL |= USB_CTL_ODDRST_MASK;
+
+ usbHostPointer->usbRegBase->BDTPAGE1 = (uint8_t)((uint32_t)USB_KHCI_BDT_BASE >> 8U);
+ usbHostPointer->usbRegBase->BDTPAGE2 = (uint8_t)((uint32_t)USB_KHCI_BDT_BASE >> 16);
+ usbHostPointer->usbRegBase->BDTPAGE3 = (uint8_t)((uint32_t)USB_KHCI_BDT_BASE >> 24);
+ /* Set SOF threshold */
+ usbHostPointer->usbRegBase->SOFTHLD = 255;
+
+ usbHostPointer->usbRegBase->CTL = USB_CTL_HOSTMODEEN_MASK;
+ /* Wait for attach interrupt */
+ usbHostPointer->usbRegBase->INTEN |= (USB_INTEN_ATTACHEN_MASK);// | USB_INTEN_SOFTOKEN_MASK);
+#if defined(FSL_FEATURE_USB_KHCI_DYNAMIC_SOF_THRESHOLD_COMPARE_ENABLED) && \
+ (FSL_FEATURE_USB_KHCI_DYNAMIC_SOF_THRESHOLD_COMPARE_ENABLED == 1U)
+ usbHostPointer->usbRegBase->MISCCTRL |= USB_MISCCTRL_SOFDYNTHLD_MASK;
+#endif
+ usbHostPointer->trState = kKhci_TrGetMsg;
+ return status;
+}
+
+/*!
+ * @brief destroy USB host khci instance.
+ *
+ * This function de-initialize the USB host khci controller driver.
+ *
+ * @param handle the controller handle.
+ *
+ * @retval kStatus_USB_Success The host is initialized successfully.
+ */
+usb_status_t USB_HostKhciDestory(usb_host_controller_handle controllerHandle)
+{
+ usb_khci_host_state_struct_t *usbHostPointer = (usb_khci_host_state_struct_t *)controllerHandle;
+
+ usbHostPointer->usbRegBase->INTEN &= (~0xFFU);
+
+ usbHostPointer->usbRegBase->ADDR = ((usbHostPointer->usbRegBase->ADDR & (~USB_ADDR_ADDR_MASK)) |
+ ((((0U) << USB_ADDR_ADDR_SHIFT) & USB_ADDR_ADDR_MASK)));
+ usbHostPointer->usbRegBase->CTL &= (~0xFFu);
+ usbHostPointer->usbRegBase->USBCTRL |= USB_USBCTRL_PDE_MASK;
+ usbHostPointer->usbRegBase->USBCTRL |= USB_USBCTRL_SUSP_MASK;
+ usbHostPointer->usbRegBase->ADDR &= (~USB_ADDR_LSEN_MASK);
+
+ if (NULL != usbHostPointer->khciEventPointer)
+ {
+ USB_OsaEventDestroy(usbHostPointer->khciEventPointer);
+ }
+ if (NULL != usbHostPointer->khciMutex)
+ {
+ USB_OsaMutexDestroy(usbHostPointer->khciMutex);
+ }
+
+ if (NULL != usbHostPointer->khciSwapBufPointer)
+ {
+ USB_OsaMemoryFree(usbHostPointer->khciSwapBufPointer);
+ usbHostPointer->khciSwapBufPointer = NULL;
+ }
+
+ USB_OsaMemoryFree(usbHostPointer);
+ usbHostPointer = NULL;
+
+ return kStatus_USB_Success;
+}
+
+/*!
+ * @brief open USB host pipe.
+ *
+ * This function open one pipe according to the pipeInitPointer parameter.
+ *
+ * @param controllerHandle the controller handle.
+ * @param pipeHandlePointer the pipe handle pointer, it is used to return the pipe handle.
+ * @param pipeInitPointer it is used to initialize the pipe.
+ *
+ * @retval kStatus_USB_Success The host is initialized successfully.
+ * @retval kStatus_USB_Error there is no idle pipe.
+*
+*/
+usb_status_t USB_HostKhciOpenPipe(usb_host_controller_handle controllerHandle,
+ usb_host_pipe_handle *pipeHandlePointer,
+ usb_host_pipe_init_t *pipeInitPointer)
+{
+ usb_khci_host_state_struct_t *usbHostPointer = (usb_khci_host_state_struct_t *)controllerHandle;
+ usb_host_pipe_t *pipePointer;
+ usb_host_pipe_t *prePipePointer;
+ usb_host_pipe_t *tempPipePointer;
+
+ USB_OSA_SR_ALLOC();
+ USB_OSA_ENTER_CRITICAL();
+ pipePointer = (usb_host_pipe_t *)USB_OsaMemoryAllocate(sizeof(usb_host_pipe_t));
+ if (pipePointer == NULL)
+ {
+ USB_OsaMemoryFree(usbHostPointer);
+ return kStatus_USB_AllocFail;
+ }
+ else
+ {
+ if (usbHostPointer->pipeDescriptorBasePointer == NULL)
+ {
+ usbHostPointer->pipeDescriptorBasePointer = pipePointer;
+ }
+ else
+ {
+ tempPipePointer = usbHostPointer->pipeDescriptorBasePointer;
+ while (NULL != tempPipePointer)
+ {
+ prePipePointer = tempPipePointer;
+ tempPipePointer = tempPipePointer->next;
+ }
+ prePipePointer->next = pipePointer;
+ }
+ pipePointer->next = NULL;
+ }
+ USB_OSA_EXIT_CRITICAL();
+
+ pipePointer->deviceHandle = pipeInitPointer->devInstance;
+ pipePointer->endpointAddress = pipeInitPointer->endpointAddress;
+ pipePointer->direction = pipeInitPointer->direction;
+ pipePointer->interval = pipeInitPointer->interval;
+ pipePointer->maxPacketSize = pipeInitPointer->maxPacketSize;
+ pipePointer->pipeType = pipeInitPointer->pipeType;
+ pipePointer->numberPerUframe = pipeInitPointer->numberPerUframe;
+ pipePointer->nakCount = pipeInitPointer->nakCount;
+ pipePointer->nextdata01 = 0U;
+ pipePointer->open = (uint8_t)1U;
+ pipePointer->currentCount = 0xffffU;
+
+ if (pipePointer->pipeType == USB_ENDPOINT_ISOCHRONOUS)
+ {
+ pipePointer->interval = 1 << (pipeInitPointer->interval - 1U);
+ }
+ else
+ {
+ pipePointer->interval = _USB_HostKhciGetRoundUpPow2(pipeInitPointer->interval);
+ }
+ *pipeHandlePointer = pipePointer;
+
+ return kStatus_USB_Success;
+}
+
+/*!
+ * @brief close USB host pipe.
+ *
+ * This function close one pipe and release the related resources.
+ *
+ * @param controllerHandle the controller handle.
+ * @param pipeHandle the closing pipe handle.
+ *
+ * @retval kStatus_USB_Success The host is initialized successfully.
+ */
+usb_status_t USB_HostKhciClosePipe(usb_host_controller_handle controllerHandle, usb_host_pipe_handle pipeHandle)
+{
+ usb_khci_host_state_struct_t *usbHostPointer = (usb_khci_host_state_struct_t *)controllerHandle;
+ usb_host_pipe_t *pipePointer = (usb_host_pipe_t *)pipeHandle;
+ usb_host_pipe_t *prePipePointer;
+
+ USB_OSA_SR_ALLOC();
+ USB_OSA_ENTER_CRITICAL();
+
+ if ((pipePointer != NULL) && (pipePointer->open == (uint8_t)1U))
+ {
+ if (pipeHandle == usbHostPointer->pipeDescriptorBasePointer)
+ {
+ usbHostPointer->pipeDescriptorBasePointer = usbHostPointer->pipeDescriptorBasePointer->next;
+ USB_OsaMemoryFree(pipeHandle);
+ }
+ else
+ {
+ pipePointer = usbHostPointer->pipeDescriptorBasePointer;
+ prePipePointer = pipePointer;
+ while (NULL != pipePointer)
+ {
+ if ((pipePointer->open) && (pipePointer == pipeHandle))
+ {
+ prePipePointer->next = pipePointer->next;
+ if (NULL != pipePointer)
+ {
+ USB_OsaMemoryFree(pipePointer);
+ pipePointer = NULL;
+ }
+ break;
+ }
+ prePipePointer = pipePointer;
+ pipePointer = pipePointer->next;
+ }
+ }
+ }
+ else
+ {
+#ifdef HOST_ECHO
+ usb_echo("usb_khci_close_pipe invalid pipe \n");
+#endif
+ }
+ USB_OSA_EXIT_CRITICAL();
+
+ return kStatus_USB_Success;
+}
+
+/*!
+ * @brief send data to pipe.
+ *
+ * This function request to send the transfer to the specified pipe.
+ *
+ * @param controllerHandle the controller handle.
+ * @param pipeHandle the sending pipe handle.
+ * @param transfer the transfer which will be wrote.
+ *
+ * @retval kStatus_USB_Success send successfully.
+ * @retval kStatus_USB_LackSwapBuffer there is no swap buffer for KHCI.
+ *
+ */
+usb_status_t USB_HostKhciWritePipe(usb_host_controller_handle controllerHandle,
+ usb_host_pipe_handle pipeHandle,
+ usb_host_transfer_t *transfer)
+{
+ usb_status_t status = kStatus_USB_Success;
+ usb_khci_host_state_struct_t *usbHostPointer = (usb_khci_host_state_struct_t *)controllerHandle;
+
+ usb_host_pipe_t *pipePointer = (usb_host_pipe_t *)pipeHandle;
+
+ transfer->transferPipe = pipePointer;
+ transfer->retry = RETRY_TIME;
+
+ if (pipePointer->endpointAddress == 0U)
+ {
+ if ((transfer->direction == USB_IN) && (transfer->transferBuffer != NULL) &&
+ ((transfer->transferLength & USB_MEM4_ALIGN_MASK) ||
+ ((uint32_t)transfer->transferBuffer & USB_MEM4_ALIGN_MASK)))
+ {
+ if (usbHostPointer->khciSwapBufPointer == NULL)
+ {
+ return kStatus_USB_LackSwapBuffer;
+ }
+ if (pipePointer->maxPacketSize > USB_HOST_CONFIG_KHCI_DMA_ALIGN_BUFFER)
+ {
+ return kStatus_USB_LackSwapBuffer;
+ }
+ }
+ transfer->setupStatus = kTransfer_Setup0;
+
+ if (transfer->transferLength)
+ {
+ if (transfer->direction == USB_IN)
+ {
+ transfer->nakTimeout = USB_TIMEOUT_TOHOST;
+ }
+ else
+ {
+ transfer->nakTimeout = USB_TIMEOUT_TODEVICE;
+ }
+ }
+ else
+ {
+ transfer->nakTimeout = USB_TIMEOUT_NODATA;
+ }
+ }
+ else
+ {
+ if (pipePointer->nakCount == 0U)
+ {
+ transfer->nakTimeout = USB_TIMEOUT_DEFAULT;
+ }
+ else
+ {
+ transfer->nakTimeout = pipePointer->nakCount * NAK_RETRY_TIME;
+ }
+ }
+ transfer->frame = _USB_HostKhciGetFrameCountSum(usbHostPointer);
+
+ _USB_HostKhciLinkTrRequestToList(controllerHandle, transfer);
+
+ USB_OsaEventSet(usbHostPointer->khciEventPointer, USB_KHCI_EVENT_MSG);
+
+ return status;
+}
+
+/*!
+ * @brief receive data from pipe.
+ *
+ * This function request to receive the transfer from the specified pipe.
+ *
+ * @param controllerHandle the controller handle.
+ * @param pipeHandle the receiving pipe handle.
+ * @param transfer the transfer which will be read.
+ *
+ * @retval kStatus_USB_Success send successfully.
+ * @retval kStatus_USB_LackSwapBuffer there is no swap buffer for KHCI.
+ *
+ */
+usb_status_t USB_HostKhciReadpipe(usb_host_controller_handle controllerHandle,
+ usb_host_pipe_handle pipeHandle,
+ usb_host_transfer_t *transfer)
+{
+ usb_status_t status = kStatus_USB_Success;
+ usb_khci_host_state_struct_t *usbHostPointer = (usb_khci_host_state_struct_t *)controllerHandle;
+ usb_host_pipe_t *pipePointer = (usb_host_pipe_t *)pipeHandle;
+
+ if ((transfer->transferLength & USB_MEM4_ALIGN_MASK) || ((uint32_t)transfer->transferBuffer & USB_MEM4_ALIGN_MASK))
+ {
+ if (usbHostPointer->khciSwapBufPointer == NULL)
+ {
+ return kStatus_USB_LackSwapBuffer;
+ }
+ if (pipePointer->maxPacketSize > USB_HOST_CONFIG_KHCI_DMA_ALIGN_BUFFER)
+ {
+ return kStatus_USB_LackSwapBuffer;
+ }
+ }
+
+ transfer->transferPipe = pipePointer;
+ transfer->transferSofar = 0U;
+ if (pipePointer->nakCount == 0U)
+ {
+ transfer->nakTimeout = USB_TIMEOUT_DEFAULT;
+ }
+ else
+ {
+ transfer->nakTimeout = pipePointer->nakCount * NAK_RETRY_TIME;
+ }
+ transfer->retry = RETRY_TIME;
+ transfer->frame = _USB_HostKhciGetFrameCountSum(usbHostPointer);
+
+ _USB_HostKhciLinkTrRequestToList(controllerHandle, transfer);
+ USB_OsaEventSet(usbHostPointer->khciEventPointer, USB_KHCI_EVENT_MSG);
+
+ return status;
+}
+
+/*!
+ * @brief cancel pipe's transfers.
+ *
+ * @param handle Pointer of the host khci controller handle.
+ * @param pipePointer Pointer of the pipe.
+ * @param trPointer The canceling transfer.
+ *
+ * @return kStatus_USB_Success or error codes.
+ */
+static usb_status_t _USB_HostKhciCancelPipe(usb_host_controller_handle handle,
+ usb_host_pipe_t *pipePointer,
+ usb_host_transfer_t *trPointer)
+{
+ usb_host_transfer_t *temptr = NULL;
+ usb_khci_host_state_struct_t *usbHostPointer = (usb_khci_host_state_struct_t *)handle;
+
+ if ((pipePointer->pipeType == USB_ENDPOINT_ISOCHRONOUS) || (pipePointer->pipeType == USB_ENDPOINT_INTERRUPT))
+ {
+ temptr = usbHostPointer->periodicListPointer;
+ }
+ else if ((pipePointer->pipeType == USB_ENDPOINT_CONTROL) || (pipePointer->pipeType == USB_ENDPOINT_BULK))
+ {
+ temptr = usbHostPointer->asyncListPointer;
+ }
+ else
+ {
+ }
+
+ while (temptr != NULL)
+ {
+ if (((usb_host_pipe_t *)(temptr->transferPipe) == pipePointer) &&
+ ((trPointer == NULL) || (trPointer == temptr)))
+ {
+ _USB_HostKhciUnlinkTrRequestFromList(handle, temptr);
+ temptr->callbackFn(temptr->callbackParam, temptr, kStatus_USB_TransferCancel);
+ return kStatus_USB_Success;
+ }
+ temptr = temptr->next;
+ }
+
+ return kStatus_USB_Success;
+}
+
+/*!
+ * @brief khci bus control.
+ *
+ * @param handle Pointer of the host khci controller handle.
+ * @param busControl Bus control code.
+ *
+ * @return kStatus_USB_Success
+ */
+static usb_status_t _USB_HostKhciBusControl(usb_host_controller_handle handle, uint8_t busControl)
+{
+ ptr_usb_host_khci_state_struct_t usbHostPointer = (usb_khci_host_state_struct_t *)handle;
+ if (busControl == kUSB_HostBusReset)
+ {
+ usbHostPointer->usbRegBase->CTL |= USB_CTL_RESET_MASK;
+ /* wait for 30 milliseconds (2.5 is minimum for reset, 10 recommended) */
+ _USB_HostKhciDelay(usbHostPointer, 30U);
+ usbHostPointer->usbRegBase->CTL &= (~USB_CTL_RESET_MASK);
+ usbHostPointer->usbRegBase->CTL |= USB_CTL_ODDRST_MASK;
+ usbHostPointer->usbRegBase->CTL = USB_CTL_HOSTMODEEN_MASK;
+
+ usbHostPointer->txBd = 0U;
+ usbHostPointer->rxBd = 0U;
+ }
+ else if (busControl == kUSB_HostBusRestart)
+ {
+ usbHostPointer->deviceAttached = 0U;
+
+ usbHostPointer->usbRegBase->CTL = USB_CTL_HOSTMODEEN_MASK;
+ usbHostPointer->usbRegBase->ISTAT = 0xffU;
+ /* Now, enable only USB interrupt attach for host mode */
+ usbHostPointer->usbRegBase->INTEN |= USB_INTEN_ATTACHEN_MASK;
+ }
+ else if (busControl == kUSB_HostBusEnableAttach)
+ {
+ if (usbHostPointer->deviceAttached <= 0)
+ {
+ usbHostPointer->usbRegBase->INTEN |= USB_INTEN_ATTACHEN_MASK;
+ }
+ }
+ else if (busControl == kUSB_HostBusDisableAttach)
+ {
+ usbHostPointer->usbRegBase->INTEN &= (~USB_INTEN_ATTACHEN_MASK);
+ }
+ else
+ {
+ }
+
+ return kStatus_USB_Success;
+}
+
+/*!
+ * @brief io control khci.
+ *
+ * This function implemented khci io control khci.
+ *
+ * @param controllerHandle the controller handle.
+ * @param ioctlEvent please reference to enumeration host_busControl_t.
+ * @param ioctlParam the control parameter.
+ *
+ * @retval kStatus_USB_Success io ctrol successfully.
+ * @retval kStatus_USB_InvalidHandle The controllerHandle is a NULL pointer.
+ */
+usb_status_t USB_HostKciIoctl(usb_host_controller_handle controllerHandle, uint32_t ioctlEvent, void *ioctlParam)
+{
+ usb_status_t status = kStatus_USB_Success;
+ usb_host_cancel_param_t *param;
+
+ if (controllerHandle == NULL)
+ {
+ return kStatus_USB_InvalidHandle;
+ }
+
+ switch (ioctlEvent)
+ {
+ case kUSB_HostCancelTransfer:
+ param = (usb_host_cancel_param_t *)ioctlParam;
+ status = _USB_HostKhciCancelPipe(controllerHandle, (usb_host_pipe_t *)param->pipeHandle, param->transfer);
+ break;
+
+ case kUSB_HostBusControl:
+ status = _USB_HostKhciBusControl(controllerHandle, *((uint8_t *)ioctlParam));
+ break;
+
+ case kUSB_HostGetFrameNumber:
+ *((uint32_t *)ioctlParam) = _USB_HostKhciGetFrameCount(controllerHandle);
+ break;
+
+ default:
+ break;
+ }
+ return status;
+}
+#endif /* USB_HOST_CONFIG_KHCI */
diff --git a/usb_1.1.0/host/usb_host_khci.h b/usb_1.1.0/host/usb_host_khci.h
new file mode 100644
index 0000000..38884c7
--- /dev/null
+++ b/usb_1.1.0/host/usb_host_khci.h
@@ -0,0 +1,328 @@
+/*
+ * Copyright (c) 2015 -2016, Freescale Semiconductor, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * o Redistributions of source code must retain the above copyright notice, this list
+ * of conditions and the following disclaimer.
+ *
+ * o Redistributions in binary form must reproduce the above copyright notice, this
+ * list of conditions and the following disclaimer in the documentation and/or
+ * other materials provided with the distribution.
+ *
+ * o Neither the name of Freescale Semiconductor, Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __USB_HOST_KHCI_H__
+#define __USB_HOST_KHCI_H__
+
+/*******************************************************************************
+ * KHCI driver private structures, enumerations, macros, functions
+ ******************************************************************************/
+
+/*******************************************************************************
+ * Definitions
+ ******************************************************************************/
+#define USB_KHCI_MAX_SPEED_DETECTION_COUNT 3
+
+/* usb khci atom transaction error results */
+#define USB_KHCI_ATOM_TR_PID_ERROR (-1)
+#define USB_KHCI_ATOM_TR_EOF_ERROR (-2)
+#define USB_KHCI_ATOM_TR_CRC_ERROR (-4)
+#define USB_KHCI_ATOM_TR_TO (-16)
+#define USB_KHCI_ATOM_TR_DMA_ERROR (-32)
+#define USB_KHCI_ATOM_TR_BTS_ERROR (-128)
+#define USB_KHCI_ATOM_TR_NAK (-256)
+#define USB_KHCI_ATOM_TR_DATA_ERROR (-512)
+#define USB_KHCI_ATOM_TR_STALL (-1024)
+#define USB_KHCI_ATOM_TR_RESET (-2048)
+#define USB_KHCI_ATOM_TR_BUS_TIMEOUT (-4096)
+#define USB_KHCI_ATOM_TR_INVALID (-8192)
+
+/* KHCI event bits */
+#define USB_KHCI_EVENT_ATTACH 0x01
+#define USB_KHCI_EVENT_RESET 0x02
+#define USB_KHCI_EVENT_TOK_DONE 0x04
+#define USB_KHCI_EVENT_SOF_TOK 0x08
+#define USB_KHCI_EVENT_DETACH 0x10
+#define USB_KHCI_EVENT_MSG 0x20
+#define USB_KHCI_EVENT_ISO_MSG 0x40
+#define USB_KHCI_EVENT_NAK_MSG 0x80
+#define USB_KHCI_EVENT_MASK 0xff
+
+typedef enum _transfer_status
+{
+ kTransfer_Idle = 0,
+ kTransfer_Setup0,
+ kTransfer_Setup1,
+ kTransfer_Setup2,
+ kTransfer_Setup3,
+} transfer_status_t;
+
+typedef enum _khci_intr_type
+{
+ kIntr_UsbRst = 0x01,
+ kIntr_Error = 0x02,
+ kIntr_SofTok = 0x04,
+ kIntr_TokDne = 0x08,
+ kIntr_Sleep = 0x10,
+ kIntr_Resume = 0x20,
+ kIntr_Attach = 0x40,
+ kIntr_Stall = 0x80,
+} khci_intr_type_t;
+
+typedef enum _tr_type
+{
+ kTr_Ctrl = 0,
+ kTr_In,
+ kTr_Out,
+ kTr_OutHndsk,
+ kTr_InHndsk,
+ kTr_Unknown
+} tr_type_t;
+
+/* Transaction type */
+typedef enum _tr_request_type
+{
+ kTr_MsgUnknown = 0, /*Unknown - not used */
+ kTr_MsgSetup, /* Set up transaction */
+ kTr_MsgSend, /* Send transaction */
+ kTr_MsgRecv /* Receive transaction */
+} tr_request_type_t;
+
+typedef enum tr_request_state
+{
+ kTr_MsgIdle = 0, /*Normal transfer */
+ kTr_MsgNak, /* NAK transfer */
+ kTr_BusTimeout,
+} tr_request_state_t;
+
+typedef enum khci_tr_state
+{
+ kKhci_TrGetMsg = 0,
+ kKhci_IsoTrGetMsg,
+ kKhci_TrStartTransmit,
+ kKhci_TrTransmiting,
+ kKhci_TrTransmitDone,
+ kKhci_TrNone
+} khci_tr_state_t;
+
+/* Defines the USB KHCI time out value from USB specification */
+#define USB_TIMEOUT_NODATA (500)
+#define USB_TIMEOUT_TOHOST (5000)
+#define USB_TIMEOUT_TODEVICE (5000)
+#define USB_TIMEOUT_OTHER (10000)
+#define USB_TIMEOUT_DEFAULT (500)
+
+#define NAK_RETRY_TIME (1)
+#define RETRY_TIME (3)
+
+/* Define USB buffer descriptor operator MACRO definitions; This part is not included in header files */
+#define USB_KHCI_BDT_BASE ((uint32_t *)(&bdt[0]))
+#define USB_KHCI_BD_PTR(ep, rxtx, odd) \
+ ((((uint32_t)USB_KHCI_BDT_BASE) & 0xfffffe00U) | ((ep & 0x0fu) << 5) | ((rxtx & 1u) << 4) | ((odd & 1u) << 3))
+
+#define USB_KHCI_BD_CTRL(ep, rxtx, odd) (*((uint32_t *)USB_KHCI_BD_PTR(ep, rxtx, odd)))
+#define USB_KHCI_BD_CTRL_RX(ep, odd) (*((uint32_t *)USB_KHCI_BD_PTR(ep, 0, odd)))
+#define USB_KHCI_BD_CTRL_TX(ep, odd) (*((uint32_t *)USB_KHCI_BD_PTR(ep, 1, odd)))
+
+#define USB_KHCI_BD_ADDR(ep, rxtx, odd) (*((uint32_t *)USB_KHCI_BD_PTR(ep, rxtx, odd) + 1))
+#define USB_KHCI_BD_ADDR_RX(ep, odd) (*((uint32_t *)USB_KHCI_BD_PTR(ep, 0, odd) + 1))
+#define USB_KHCI_BD_ADDR_TX(ep, odd) (*((uint32_t *)USB_KHCI_BD_PTR(ep, 1, odd) + 1))
+
+/* Define USB buffer descriptor definitions; This part is not included in header files */
+#define USB_KHCI_BD_BC(n) ((n & 0x3ffu) << 16)
+#define USB_KHCI_BD_OWN 0x80u
+#define USB_KHCI_BD_DATA01(n) ((n & 1u) << 6)
+#define USB_KHCI_BD_DATA0 USB_KHCI_BD_DATA01(0u)
+#define USB_KHCI_BD_DATA1 USB_KHCI_BD_DATA01(1u)
+#define USB_KHCI_BD_KEEP 0x20u
+#define USB_KHCI_BD_NINC 0x10u
+#define USB_KHCI_BD_DTS 0x08u
+#define USB_KHCI_BD_STALL 0x04u
+#define USB_KHCI_BD_PID(n) ((n & 0x0fu) << 2)
+
+#define USB_HostKhciLock() USB_OsaMutexLock(usbHostPointer->khciMutex)
+#define USB_HostKhciUnlock() USB_OsaMutexUnlock(usbHostPointer->khciMutex)
+
+typedef struct _khci_xfer_sts
+{
+ uint32_t rxLen;
+ uint8_t *rxBuf;
+ uint8_t *rxBufOrig;
+ uint8_t isDmaAlign;
+} khci_xfer_sts_t;
+
+/*******************************************************************************
+ * KHCI driver public structures, enumerations, macros, functions
+ ******************************************************************************/
+
+/*!
+ * @addtogroup usb_host_controller_khci
+ * @{
+ */
+
+/*! @brief The value programmed into the threshold register must reserve enough time to ensure the worst case
+ transaction completes. In general, the worst case transaction is an IN token followed by a data packet from the target
+ followed by the response from the host. The actual time required is a function of the maximum packet size on the bus. Set the
+ KHCICFG_THSLD_DELAY to 0x65 to meet the worst case.*/
+
+#define KHCICFG_THSLD_DELAY 0x65
+
+/*! @brief KHCI controller driver instance structure */
+typedef struct _usb_khci_host_state_struct
+{
+ volatile USB_Type *usbRegBase; /*!< The base address of the register */
+ void *hostHandle; /*!< Related host handle*/
+ usb_host_pipe_t *pipeDescriptorBasePointer; /*!< Pipe descriptor bas pointer*/
+ usb_osa_event_handle khciEventPointer; /*!< KHCI event*/
+ usb_osa_mutex_handle khciMutex; /*!< KHCI mutex*/
+ usb_host_transfer_t
+ *periodicListPointer; /*!< KHCI periodic list pointer, which link is an interrupt and an ISO transfer request*/
+ usb_host_transfer_t *asyncListPointer; /*!< KHCI async list pointer, which link controls and bulk transfer request*/
+ khci_xfer_sts_t sXferSts; /*!< KHCI transfer status structure for the DAM ALIGN workaround */
+ uint8_t *khciSwapBufPointer; /*!< KHCI swap buffer pointer for the DAM ALIGN workaround*/
+ volatile uint32_t trState; /*!< KHCI transfer state*/
+ uint8_t asyncListAvtive; /*!< KHCI async list is active*/
+ uint8_t periodicListAvtive; /*!< KHCI periodic list is active*/
+ uint8_t rxBd; /*!< RX buffer descriptor toggle bits*/
+ uint8_t txBd; /*!< TX buffer descriptor toggle bits*/
+ uint8_t deviceSpeed; /*!< Device speed*/
+ int8_t deviceAttached; /*!< Device attach/detach state */
+} usb_khci_host_state_struct_t, *ptr_usb_host_khci_state_struct_t;
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+/*!
+ * @name USB host KHCI APIs
+ * @{
+ */
+
+/*!
+ * @brief Creates the USB host KHCI instance.
+ *
+ * This function initializes the USB host KHCI controller driver.
+ *
+ * @param controllerId The controller ID of the USB IP. See the enumeration usb_controller_index_t.
+ * @param hostHandle The host level handle.
+ * @param controllerHandle Returns the controller instance handle.
+ *
+ * @retval kStatus_USB_Success The host is initialized successfully.
+ * @retval kStatus_USB_AllocFail Allocates memory failed.
+ * @retval kStatus_USB_Error Host mutex create failed, KHCI mutex or KHCI event create failed.
+ * Or, KHCI IP initialize failed.
+ */
+extern usb_status_t USB_HostKhciCreate(uint8_t controllerId,
+ usb_host_handle hostHandle,
+ usb_host_controller_handle *controllerHandle);
+
+/*!
+ * @brief Destroys the USB host KHCI instance.
+ *
+ * This function deinitializes the USB host KHCI controller driver.
+ *
+ * @param controllerHandle The controller handle.
+ *
+ * @retval kStatus_USB_Success The host is initialized successfully.
+ */
+extern usb_status_t USB_HostKhciDestory(usb_host_controller_handle controllerHandle);
+
+/*!
+ * @brief Opens the USB host pipe.
+ *
+ * This function opens a pipe according to the pipe_init_ptr parameter.
+ *
+ * @param controllerHandle The controller handle.
+ * @param pipeHandlePointer The pipe handle pointer used to return the pipe handle.
+ * @param pipeInitPointer It is used to initialize the pipe.
+ *
+ * @retval kStatus_USB_Success The host is initialized successfully.
+ * @retval kStatus_USB_Error There is no idle pipe.
+ *
+ */
+extern usb_status_t USB_HostKhciOpenPipe(usb_host_controller_handle controllerHandle,
+ usb_host_pipe_handle *pipeHandlePointer,
+ usb_host_pipe_init_t *pipeInitPointer);
+
+/*!
+ * @brief Closes the USB host pipe.
+ *
+ * This function closes a pipe and frees the related resources.
+ *
+ * @param controllerHandle The controller handle.
+ * @param pipeHandle The closing pipe handle.
+ *
+ * @retval kStatus_USB_Success The host is initialized successfully.
+ */
+extern usb_status_t USB_HostKhciClosePipe(usb_host_controller_handle controllerHandle, usb_host_pipe_handle pipeHandle);
+
+/*!
+ * @brief Sends data to the pipe.
+ *
+ * This function requests to send the transfer to the specified pipe.
+ *
+ * @param controllerHandle The controller handle.
+ * @param pipeHandle The sending pipe handle.
+ * @param transfer The transfer information.
+ *
+ * @retval kStatus_USB_Success Send successful.
+ * @retval kStatus_USB_LackSwapBuffer There is no swap buffer for KHCI.
+ */
+extern usb_status_t USB_HostKhciWritePipe(usb_host_controller_handle controllerHandle,
+ usb_host_pipe_handle pipeHandle,
+ usb_host_transfer_t *transfer);
+
+/*!
+ * @brief Receives data from the pipe.
+ *
+ * This function requests to receive the transfer from the specified pipe.
+ *
+ * @param controllerHandle The controller handle.
+ * @param pipeHandle The receiving pipe handle.
+ * @param transfer The transfer information.
+ *
+ * @retval kStatus_USB_Success Receive successful.
+ * @retval kStatus_USB_LackSwapBuffer There is no swap buffer for KHCI.
+ */
+extern usb_status_t USB_HostKhciReadpipe(usb_host_controller_handle controllerHandle,
+ usb_host_pipe_handle pipeHandle,
+ usb_host_transfer_t *transfer);
+
+/*!
+ * @brief Controls the KHCI.
+ *
+ * This function controls the KHCI.
+ *
+ * @param controllerHandle The controller handle.
+ * @param ioctlEvent See the enumeration host_bus_control_t.
+ * @param ioctlParam The control parameter.
+ *
+ * @retval kStatus_USB_Success Cancel successful.
+ * @retval kStatus_USB_InvalidHandle The controllerHandle is a NULL pointer.
+ */
+extern usb_status_t USB_HostKciIoctl(usb_host_controller_handle controllerHandle,
+ uint32_t ioctlEvent,
+ void *ioctlParam);
+
+/*! @}*/
+#ifdef __cplusplus
+}
+#endif
+/*! @}*/
+#endif /* __USB_HOST_KHCI_H__ */
diff --git a/usb_1.1.0/include/usb.h b/usb_1.1.0/include/usb.h
new file mode 100644
index 0000000..8241732
--- /dev/null
+++ b/usb_1.1.0/include/usb.h
@@ -0,0 +1,119 @@
+/*
+ * Copyright (c) 2015, Freescale Semiconductor, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * o Redistributions of source code must retain the above copyright notice, this list
+ * of conditions and the following disclaimer.
+ *
+ * o Redistributions in binary form must reproduce the above copyright notice, this
+ * list of conditions and the following disclaimer in the documentation and/or
+ * other materials provided with the distribution.
+ *
+ * o Neither the name of Freescale Semiconductor, Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __USB_H__
+#define __USB_H__
+
+#include <stdint.h>
+#include <stdio.h>
+#include "usb_osa.h"
+#include "usb_misc.h"
+#include "usb_spec.h"
+
+/*!
+ * @addtogroup usb_drv
+ * @{
+ */
+
+/*******************************************************************************
+ * Definitions
+ ******************************************************************************/
+/*! @brief Defines USB stack major version */
+#define USB_STACK_VERSION_MAJOR (1U)
+/*! @brief Defines USB stack minor version */
+#define USB_STACK_VERSION_MINOR (1U)
+/*! @brief Defines USB stack bugfix version */
+#define USB_STACK_VERSION_BUGFIX (0U)
+
+/*! @brief USB stack version definition */
+#define USB_MAKE_VERSION(major, minor, bugfix) (((major) << 16) | ((minor) << 8) | (bugfix))
+
+/*! @brief USB error code */
+typedef enum _usb_status
+{
+ kStatus_USB_Success = 0x00U, /*!< Success */
+ kStatus_USB_Error, /*!< Failed */
+
+ kStatus_USB_Busy, /*!< Busy */
+ kStatus_USB_InvalidHandle, /*!< Invalid handle */
+ kStatus_USB_InvalidParameter, /*!< Invalid parameter */
+ kStatus_USB_InvalidRequest, /*!< Invalid request */
+ kStatus_USB_ControllerNotFound, /*!< Controller cannot be found */
+ kStatus_USB_InvalidControllerInterface, /*!< Invalid controller interface */
+
+ kStatus_USB_NotSupported, /*!< Configuration is not supported */
+ kStatus_USB_Retry, /*!< Enumeration get configuration retry */
+ kStatus_USB_TransferStall, /*!< Transfer stalled */
+ kStatus_USB_TransferFailed, /*!< Transfer failed */
+ kStatus_USB_AllocFail, /*!< Allocation failed */
+ kStatus_USB_LackSwapBuffer, /*!< Insufficient swap buffer for KHCI */
+ kStatus_USB_TransferCancel, /*!< The transfer cancelled */
+ kStatus_USB_BandwidthFail, /*!< Allocate bandwidth failed */
+ kStatus_USB_MSDStatusFail, /*!< For MSD, the CSW status means fail */
+} usb_status_t;
+
+/*! @brief USB host handle type define */
+typedef void *usb_host_handle;
+
+/*! @brief USB device handle type define. For device stack it is the whole device handle; for host stack it is the
+ * attached device instance handle*/
+typedef void *usb_device_handle;
+
+/*! @brief USB OTG handle type define */
+typedef void *usb_otg_handle;
+
+/*! @brief USB controller ID */
+typedef enum _usb_controller_index
+{
+ kUSB_ControllerKhci0 = 0U, /*!< KHCI 0U */
+ kUSB_ControllerKhci1, /*!< KHCI 1U, Currently, there are no platforms which have two KHCI IPs, this is reserved
+ to be used in the future. */
+ kUSB_ControllerEhci0, /*!< EHCI 0U */
+ kUSB_ControllerEhci1, /*!< EHCI 1U, Currently, there are no platforms which have two KHCI IPs, this is reserved
+ to be used in the future. */
+} usb_controller_index_t;
+
+/**
+* @brief USB stack version fields
+*/
+typedef struct _usb_version
+{
+ uint8_t major; /*!< Major */
+ uint8_t minor; /*!< Minor */
+ uint8_t bugfix; /*!< Bug fix */
+} usb_version_t;
+
+/*******************************************************************************
+ * API
+ ******************************************************************************/
+
+/*! @} */
+
+#endif /* __USB_H__ */
diff --git a/usb_1.1.0/include/usb_khci.h b/usb_1.1.0/include/usb_khci.h
new file mode 100644
index 0000000..c60346f
--- /dev/null
+++ b/usb_1.1.0/include/usb_khci.h
@@ -0,0 +1,62 @@
+/*
+ * Copyright (c) 2015, Freescale Semiconductor, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * o Redistributions of source code must retain the above copyright notice, this list
+ * of conditions and the following disclaimer.
+ *
+ * o Redistributions in binary form must reproduce the above copyright notice, this
+ * list of conditions and the following disclaimer in the documentation and/or
+ * other materials provided with the distribution.
+ *
+ * o Neither the name of Freescale Semiconductor, Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __USB_KHCI_H__
+#define __USB_KHCI_H__
+
+/*******************************************************************************
+ * Definitions
+ ******************************************************************************/
+
+#define USB_KHCI_BDT_DEVICE_OUT_TOKEN (0x01U)
+#define USB_KHCI_BDT_DEVICE_IN_TOKEN (0x09U)
+#define USB_KHCI_BDT_DEVICE_SETUP_TOKEN (0x0DU)
+
+#define USB_KHCI_BDT_OWN (0x80U)
+#define USB_KHCI_BDT_DATA01(x) ((((uint32_t)(x)) & 0x01U) << 0x06U)
+#define USB_KHCI_BDT_BC(x) ((((uint32_t)(x)) & 0x3FFU) << 0x10U)
+#define UBS_KHCI_BDT_KEEP (0x20U)
+#define UBS_KHCI_BDT_NINC (0x10U)
+#define USB_KHCI_BDT_DTS (0x08U)
+#define USB_KHCI_BDT_STALL (0x04U)
+
+typedef enum _usb_khci_interrupt_type
+{
+ kUSB_KhciInterruptReset = 0x01U,
+ kUSB_KhciInterruptError = 0x02U,
+ kUSB_KhciInterruptSofToken = 0x04U,
+ kUSB_KhciInterruptTokenDone = 0x08U,
+ kUSB_KhciInterruptSleep = 0x10U,
+ kUSB_KhciInterruptResume = 0x20U,
+ kUSB_KhciInterruptAttach = 0x40U,
+ kUSB_KhciInterruptStall = 0x80U,
+} usb_khci_interrupt_type_t;
+
+#endif /* __USB_KHCI_H__ */
diff --git a/usb_1.1.0/include/usb_misc.h b/usb_1.1.0/include/usb_misc.h
new file mode 100644
index 0000000..576cfeb
--- /dev/null
+++ b/usb_1.1.0/include/usb_misc.h
@@ -0,0 +1,238 @@
+/*
+ * Copyright (c) 2015 - 2016, Freescale Semiconductor, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * o Redistributions of source code must retain the above copyright notice, this list
+ * of conditions and the following disclaimer.
+ *
+ * o Redistributions in binary form must reproduce the above copyright notice, this
+ * list of conditions and the following disclaimer in the documentation and/or
+ * other materials provided with the distribution.
+ *
+ * o Neither the name of Freescale Semiconductor, Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __USB_MISC_H__
+#define __USB_MISC_H__
+
+#ifndef ENDIANNESS
+
+#error ENDIANNESS should be defined, and then rebulid the project.
+
+#endif
+
+/*******************************************************************************
+ * Definitions
+ ******************************************************************************/
+
+/*! @brief Define USB printf */
+#if defined(__cplusplus)
+extern "C" {
+#endif /* __cplusplus */
+
+extern int DbgConsole_Printf(const char *fmt_s, ...);
+
+#if defined(__cplusplus)
+}
+#endif /* __cplusplus */
+
+#define usb_echo DbgConsole_Printf
+
+#if defined(__ICCARM__)
+
+#ifndef STRUCT_PACKED
+#define STRUCT_PACKED __packed
+#endif
+
+#ifndef STRUCT_UNPACKED
+#define STRUCT_UNPACKED
+#endif
+
+#elif defined(__GNUC__)
+
+#ifndef STRUCT_PACKED
+#define STRUCT_PACKED
+#endif
+
+#ifndef STRUCT_UNPACKED
+#define STRUCT_UNPACKED __attribute__((__packed__))
+#endif
+
+#elif defined(__CC_ARM)
+
+#ifndef STRUCT_PACKED
+#define STRUCT_PACKED _Pragma("pack(1U)")
+#endif
+
+#ifndef STRUCT_UNPACKED
+#define STRUCT_UNPACKED _Pragma("pack()")
+#endif
+
+#endif
+
+#define USB_SHORT_GET_LOW(x) (((uint16_t)x) & 0xFFU)
+#define USB_SHORT_GET_HIGH(x) ((uint8_t)(((uint16_t)x) >> 8U) & 0xFFU)
+
+#define USB_LONG_GET_BYTE0(x) ((uint8_t)(((uint32_t)(x))) & 0xFFU)
+#define USB_LONG_GET_BYTE1(x) ((uint8_t)(((uint32_t)(x)) >> 8U) & 0xFFU)
+#define USB_LONG_GET_BYTE2(x) ((uint8_t)(((uint32_t)(x)) >> 16U) & 0xFFU)
+#define USB_LONG_GET_BYTE3(x) ((uint8_t)(((uint32_t)(x)) >> 24U) & 0xFFU)
+
+#define USB_MEM4_ALIGN_MASK (0x03U)
+
+/* accessory macro */
+#define USB_MEM4_ALIGN(n) ((n + 3U) & (0xFFFFFFFCu))
+#define USB_MEM32_ALIGN(n) ((n + 31U) & (0xFFFFFFE0u))
+#define USB_MEM64_ALIGN(n) ((n + 63U) & (0xFFFFFFC0u))
+
+/* big/little endian */
+#define SWAP2BYTE_CONST(n) ((((n)&0x00FFU) << 8U) | (((n)&0xFF00U) >> 8U))
+#define SWAP4BYTE_CONST(n) \
+ ((((n)&0x000000FFU) << 24U) | (((n)&0x0000FF00U) << 8U) | (((n)&0x00FF0000U) >> 8U) | (((n)&0xFF000000U) >> 24U))
+
+#if (ENDIANNESS == BIG_ENDIAN)
+
+#define USB_SHORT_TO_LITTLE_ENDIAN(n) SWAP2BYTE_CONST(n)
+#define USB_LONG_TO_LITTLE_ENDIAN(n) SWAP4BYTE_CONST(n)
+#define USB_SHORT_FROM_LITTLE_ENDIAN(n) SWAP2BYTE_CONST(n)
+#define USB_LONG_FROM_LITTLE_ENDIAN(n) SWAP2BYTE_CONST(n)
+
+#define USB_SHORT_TO_BIG_ENDIAN(n) (n)
+#define USB_LONG_TO_BIG_ENDIAN(n) (n)
+#define USB_SHORT_FROM_BIG_ENDIAN(n) (n)
+#define USB_LONG_FROM_BIG_ENDIAN(n) (n)
+
+#define USB_LONG_TO_LITTLE_ENDIAN_ADDRESS(n, m) \
+ { \
+ m[0] = ((n >> 24U) & 0xFFU); \
+ m[1] = ((n >> 16U) & 0xFFU); \
+ m[2] = ((n >> 8U) & 0xFFU); \
+ m[3] = (n & 0xFFU); \
+ }
+
+#define USB_LONG_FROM_LITTLE_ENDIAN_ADDRESS(n) \
+ ((uint32_t)(((uint32_t)n[0] << 24U) | ((uint32_t)n[1] << 16U) | ((uint32_t)n[2] << 8U) | ((uint32_t)n[3] << 0U)))
+
+#define USB_LONG_TO_BIG_ENDIAN_ADDRESS(n, m) \
+ { \
+ m[3] = ((n >> 24U) & 0xFFU); \
+ m[2] = ((n >> 16U) & 0xFFU); \
+ m[1] = ((n >> 8U) & 0xFFU); \
+ m[0] = (n & 0xFFU); \
+ }
+
+#define USB_LONG_FROM_BIG_ENDIAN_ADDRESS(n) \
+ ((uint32_t)(((uint32_t)n[3] << 24U) | ((uint32_t)n[2] << 16U) | ((uint32_t)n[1] << 8U) | ((uint32_t)n[0] << 0U)))
+
+#define USB_SHORT_TO_LITTLE_ENDIAN_ADDRESS(n, m) \
+ { \
+ m[0] = ((n >> 8U) & 0xFFU); \
+ m[1] = (n & 0xFFU); \
+ }
+
+#define USB_SHORT_FROM_LITTLE_ENDIAN_ADDRESS(n) ((uint32_t)(((uint32_t)n[0] << 8U) | ((uint32_t)n[1] << 0U)))
+
+#define USB_SHORT_TO_BIG_ENDIAN_ADDRESS(n, m) \
+ { \
+ m[1] = ((n >> 8U) & 0xFFU); \
+ m[0] = (n & 0xFFU); \
+ }
+
+#define USB_SHORT_FROM_BIG_ENDIAN_ADDRESS(n) ((uint32_t)(((uint32_t)n[1] << 8U) | ((uint32_t)n[0] << 0U)))
+
+#else
+
+#define USB_SHORT_TO_LITTLE_ENDIAN(n) (n)
+#define USB_LONG_TO_LITTLE_ENDIAN(n) (n)
+#define USB_SHORT_FROM_LITTLE_ENDIAN(n) (n)
+#define USB_LONG_FROM_LITTLE_ENDIAN(n) (n)
+
+#define USB_SHORT_TO_BIG_ENDIAN(n) SWAP2BYTE_CONST(n)
+#define USB_LONG_TO_BIG_ENDIAN(n) SWAP4BYTE_CONST(n)
+#define USB_SHORT_FROM_BIG_ENDIAN(n) SWAP2BYTE_CONST(n)
+#define USB_LONG_FROM_BIG_ENDIAN(n) SWAP4BYTE_CONST(n)
+
+#define USB_LONG_TO_LITTLE_ENDIAN_ADDRESS(n, m) \
+ { \
+ m[3] = ((n >> 24U) & 0xFFU); \
+ m[2] = ((n >> 16U) & 0xFFU); \
+ m[1] = ((n >> 8U) & 0xFFU); \
+ m[0] = (n & 0xFFU); \
+ }
+
+#define USB_LONG_FROM_LITTLE_ENDIAN_ADDRESS(n) \
+ ((uint32_t)(((uint32_t)n[3] << 24U) | ((uint32_t)n[2] << 16U) | ((uint32_t)n[1] << 8U) | ((uint32_t)n[0] << 0U)))
+
+#define USB_LONG_TO_BIG_ENDIAN_ADDRESS(n, m) \
+ { \
+ m[0] = ((n >> 24U) & 0xFFU); \
+ m[1] = ((n >> 16U) & 0xFFU); \
+ m[2] = ((n >> 8U) & 0xFFU); \
+ m[3] = (n & 0xFFU); \
+ }
+
+#define USB_LONG_FROM_BIG_ENDIAN_ADDRESS(n) \
+ ((uint32_t)(((uint32_t)n[0] << 24U) | ((uint32_t)n[1] << 16U) | ((uint32_t)n[2] << 8U) | ((uint32_t)n[3] << 0U)))
+
+#define USB_SHORT_TO_LITTLE_ENDIAN_ADDRESS(n, m) \
+ { \
+ m[1] = ((n >> 8U) & 0xFFU); \
+ m[0] = (n & 0xFFU); \
+ }
+
+#define USB_SHORT_FROM_LITTLE_ENDIAN_ADDRESS(n) ((uint32_t)(((uint32_t)n[1] << 8U) | ((uint32_t)n[0] << 0U)))
+
+#define USB_SHORT_TO_BIG_ENDIAN_ADDRESS(n, m) \
+ { \
+ m[0] = ((n >> 8U) & 0xFFU); \
+ m[1] = (n & 0xFFU); \
+ }
+
+#define USB_SHORT_FROM_BIG_ENDIAN_ADDRESS(n) ((uint32_t)(((uint32_t)n[0] << 8U) | ((uint32_t)n[1] << 0U)))
+#endif
+
+/*
+ * The following MACROs (USB_GLOBAL, USB_BDT, USB_RAM_ADDRESS_ALGINMENT_512) are only used for USB device stack.
+ * The USB device global variables are put into the section m_usb_global or m_usb_bdt by using the MACRO
+ * USB_GLOBAL and USB_BDT. In this way, the USB device global variables can be linked into USB dadicated RAM
+ * by changing the linker file. This feature can only be enabled when the USB dadicated RAM is not less than 2K Bytes.
+ */
+#if defined(__ICCARM__)
+
+#define USB_GLOBAL _Pragma("location = \"m_usb_global\"")
+#define USB_BDT _Pragma("location = \"m_usb_bdt\"")
+#define USB_RAM_ADDRESS_ALGINMENT_512 _Pragma("data_alignment = 512U")
+
+#elif defined(__CC_ARM)
+
+#define USB_GLOBAL __attribute__((section("m_usb_global"))) __attribute__((zero_init))
+#define USB_BDT __attribute__((section("m_usb_bdt"))) __attribute__((zero_init))
+#define USB_RAM_ADDRESS_ALGINMENT_512 __attribute__((aligned(512U)))
+
+#elif defined(__GNUC__)
+
+#define USB_GLOBAL __attribute__((section("m_usb_global")))
+#define USB_BDT __attribute__((section("m_usb_bdt")))
+#define USB_RAM_ADDRESS_ALGINMENT_512 __attribute__((aligned(512U)))
+
+#else
+#error The tool-chain is not supported.
+#endif
+
+#endif /* __USB_MISC_H__ */
diff --git a/usb_1.1.0/include/usb_spec.h b/usb_1.1.0/include/usb_spec.h
new file mode 100644
index 0000000..108b0c8
--- /dev/null
+++ b/usb_1.1.0/include/usb_spec.h
@@ -0,0 +1,254 @@
+/*
+ * Copyright (c) 2015 - 2016, Freescale Semiconductor, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * o Redistributions of source code must retain the above copyright notice, this list
+ * of conditions and the following disclaimer.
+ *
+ * o Redistributions in binary form must reproduce the above copyright notice, this
+ * list of conditions and the following disclaimer in the documentation and/or
+ * other materials provided with the distribution.
+ *
+ * o Neither the name of Freescale Semiconductor, Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __USB_SPEC_H__
+#define __USB_SPEC_H__
+
+/*******************************************************************************
+ * Definitions
+ ******************************************************************************/
+
+/* USB speed (the value cannot be changed because EHCI QH use the value directly)*/
+#define USB_SPEED_FULL (0x00U)
+#define USB_SPEED_LOW (0x01U)
+#define USB_SPEED_HIGH (0x02U)
+
+/* Set up packet structure */
+typedef struct _usb_setup_struct
+{
+ uint8_t bmRequestType;
+ uint8_t bRequest;
+ uint16_t wValue;
+ uint16_t wIndex;
+ uint16_t wLength;
+} usb_setup_struct_t;
+
+/* USB standard descriptor endpoint type */
+#define USB_ENDPOINT_CONTROL (0x00U)
+#define USB_ENDPOINT_ISOCHRONOUS (0x01U)
+#define USB_ENDPOINT_BULK (0x02U)
+#define USB_ENDPOINT_INTERRUPT (0x03U)
+
+/* USB standard descriptor transfer direction (cannot change the value because iTD use the value directly) */
+#define USB_OUT (0U)
+#define USB_IN (1U)
+
+/* USB standard descriptor length */
+#define USB_DESCRIPTOR_LENGTH_DEVICE (0x12U)
+#define USB_DESCRIPTOR_LENGTH_CONFIGURE (0x09U)
+#define USB_DESCRIPTOR_LENGTH_INTERFACE (0x09U)
+#define USB_DESCRIPTOR_LENGTH_ENDPOINT (0x07U)
+#define USB_DESCRIPTOR_LENGTH_DEVICE_QUALITIER (0x0AU)
+
+/* USB standard descriptor type */
+#define USB_DESCRIPTOR_TYPE_DEVICE (0x01U)
+#define USB_DESCRIPTOR_TYPE_CONFIGURE (0x02U)
+#define USB_DESCRIPTOR_TYPE_STRING (0x03U)
+#define USB_DESCRIPTOR_TYPE_INTERFACE (0x04U)
+#define USB_DESCRIPTOR_TYPE_ENDPOINT (0x05U)
+#define USB_DESCRIPTOR_TYPE_DEVICE_QUALITIER (0x06U)
+#define USB_DESCRIPTOR_TYPE_OTHER_SPEED_CONFIGURATION (0x07U)
+#define USB_DESCRIPTOR_TYPE_INTERFAACE_POWER (0x08U)
+#define USB_DESCRIPTOR_TYPE_OTG (0x09U)
+#define USB_DESCRIPTOR_TYPE_INTERFACE_ASSOCIATION (0x0BU)
+
+#define USB_DESCRIPTOR_TYPE_HID (0x21U)
+#define USB_DESCRIPTOR_TYPE_HID_REPORT (0x22U)
+#define USB_DESCRIPTOR_TYPE_HID_PHYSICAL (0x23U)
+
+/* USB standard request type */
+#define USB_REQUEST_TYPE_DIR_MASK (0x80U)
+#define USB_REQUEST_TYPE_DIR_SHIFT (7U)
+#define USB_REQUEST_TYPE_DIR_OUT (0x00U)
+#define USB_REQUEST_TYPE_DIR_IN (0x80U)
+
+#define USB_REQUEST_TYPE_TYPE_MASK (0x60U)
+#define USB_REQUEST_TYPE_TYPE_SHIFT (5U)
+#define USB_REQUEST_TYPE_TYPE_STANDARD (0U)
+#define USB_REQUEST_TYPE_TYPE_CLASS (0x20U)
+#define USB_REQUEST_TYPE_TYPE_VENDOR (0x40U)
+
+#define USB_REQUEST_TYPE_RECIPIENT_MASK (0x1FU)
+#define USB_REQUEST_TYPE_RECIPIENT_SHIFT (0U)
+#define USB_REQUEST_TYPE_RECIPIENT_DEVICE (0x00U)
+#define USB_REQUEST_TYPE_RECIPIENT_INTERFACE (0x01U)
+#define USB_REQUEST_TYPE_RECIPIENT_ENDPOINT (0x02U)
+#define USB_REQUEST_TYPE_RECIPIENT_OTHER (0x03U)
+
+/* USB standard request */
+#define USB_REQUEST_STANDARD_GET_STATUS (0x00U)
+#define USB_REQUEST_STANDARD_CLEAR_FEATURE (0x01U)
+#define USB_REQUEST_STANDARD_SET_FEATURE (0x03U)
+#define USB_REQUEST_STANDARD_SET_ADDRESS (0x05U)
+#define USB_REQUEST_STANDARD_GET_DESCRIPTOR (0x06U)
+#define USB_REQUEST_STANDARD_SET_DESCRIPTOR (0x07U)
+#define USB_REQUEST_STANDARD_GET_CONFIGURATION (0x08U)
+#define USB_REQUEST_STANDARD_SET_CONFIGURATION (0x09U)
+#define USB_REQUEST_STANDARD_GET_INTERFACE (0x0AU)
+#define USB_REQUEST_STANDARD_SET_INTERFACE (0x0BU)
+#define USB_REQUEST_STANDARD_SYNCH_FRAME (0x0CU)
+
+/* USB standard request GET Status */
+#define USB_REQUEST_STANDARD_GET_STATUS_DEVICE_SELF_POWERED_SHIFT (0U)
+#define USB_REQUEST_STANDARD_GET_STATUS_DEVICE_REMOTE_WARKUP_SHIFT (1U)
+
+#define USB_REQUEST_STANDARD_GET_STATUS_ENDPOINT_HALT_MASK (0x01U)
+#define USB_REQUEST_STANDARD_GET_STATUS_ENDPOINT_HALT_SHIFT (0U)
+
+/* USB standard request CLEAR/SET feature */
+#define USB_REQUEST_STANDARD_FEATURE_SELECTOR_ENDPOINT_HALT (0U)
+#define USB_REQUEST_STANDARD_FEATURE_SELECTOR_DEVICE_REMOTE_WAKEUP (1U)
+#define USB_REQUEST_STANDARD_FEATURE_SELECTOR_DEVICE_TEST_MODE (2U)
+
+/* USB standard descriptor configure bmAttributes */
+#define USB_DESCRIPTOR_CONFIGURE_ATTRIBUTE_D7_MASK (0x80U)
+#define USB_DESCRIPTOR_CONFIGURE_ATTRIBUTE_D7_SHIFT (7U)
+
+#define USB_DESCRIPTOR_CONFIGURE_ATTRIBUTE_SELF_POWERED_MASK (0x40U)
+#define USB_DESCRIPTOR_CONFIGURE_ATTRIBUTE_SELF_POWERED_SHIFT (6U)
+
+#define USB_DESCRIPTOR_CONFIGURE_ATTRIBUTE_REMOTE_WAKEUP_MASK (0x20U)
+#define USB_DESCRIPTOR_CONFIGURE_ATTRIBUTE_REMOTE_WAKEUP_SHIFT (5U)
+
+/* USB standard descriptor endpoint bmAttributes */
+#define USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_MASK (0x80U)
+#define USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_SHIFT (7U)
+#define USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_OUT (0U)
+#define USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_IN (0x80U)
+
+#define USB_DESCRIPTOR_ENDPOINT_ADDRESS_NUMBER_MASK (0x0FU)
+#define USB_DESCRIPTOR_ENDPOINT_ADDRESS_NUMBER_SHFIT (0U)
+
+#define USB_DESCRIPTOR_ENDPOINT_ATTRIBUTE_TYPE_MASK (0x03U)
+#define USB_DESCRIPTOR_ENDPOINT_ATTRIBUTE_NUMBER_SHFIT (0U)
+
+#define USB_DESCRIPTOR_ENDPOINT_ATTRIBUTE_SYNC_TYPE_MASK (0x0CU)
+#define USB_DESCRIPTOR_ENDPOINT_ATTRIBUTE_SYNC_TYPE_SHFIT (2U)
+#define USB_DESCRIPTOR_ENDPOINT_ATTRIBUTE_SYNC_TYPE_NO_SYNC (0x00U)
+#define USB_DESCRIPTOR_ENDPOINT_ATTRIBUTE_SYNC_TYPE_ASYNC (0x04U)
+#define USB_DESCRIPTOR_ENDPOINT_ATTRIBUTE_SYNC_TYPE_ADAPTIVE (0x08U)
+#define USB_DESCRIPTOR_ENDPOINT_ATTRIBUTE_SYNC_TYPE_SYNC (0x0CU)
+
+#define USB_DESCRIPTOR_ENDPOINT_ATTRIBUTE_USAGE_TYPE_MASK (0x30U)
+#define USB_DESCRIPTOR_ENDPOINT_ATTRIBUTE_USAGE_TYPE_SHFIT (4U)
+#define USB_DESCRIPTOR_ENDPOINT_ATTRIBUTE_USAGE_TYPE_DATA_ENDPOINT (0x00U)
+#define USB_DESCRIPTOR_ENDPOINT_ATTRIBUTE_USAGE_TYPE_FEEDBACK_ENDPOINT (0x10U)
+#define USB_DESCRIPTOR_ENDPOINT_ATTRIBUTE_USAGE_TYPE_IMPLICIT_FEEDBACK_DATA_ENDPOINT (0x20U)
+
+#define USB_DESCRIPTOR_ENDPOINT_MAXPACKETSIZE_SIZE_MASK (0x07FFu)
+#define USB_DESCRIPTOR_ENDPOINT_MAXPACKETSIZE_MULT_TRANSACTIONS_MASK (0x1800u)
+#define USB_DESCRIPTOR_ENDPOINT_MAXPACKETSIZE_MULT_TRANSACTIONS_SHFIT (11U)
+
+/* Language structure */
+typedef struct _usb_language
+{
+ uint8_t **string; /* The Strings descriptor array */
+ uint32_t *length; /* The strings descriptor length array */
+ uint16_t languageId; /* The language id of current language */
+} usb_language_t;
+
+typedef struct _usb_language_list
+{
+ uint8_t *languageString; /* The String 0U pointer */
+ uint32_t stringLength; /* The String 0U Length */
+ usb_language_t *languageList; /* The language list */
+ uint8_t count; /* The language count */
+} usb_language_list_t;
+
+typedef struct _usb_descriptor_common
+{
+ uint8_t bLength; /* Size of this descriptor in bytes */
+ uint8_t bDescriptorType; /* DEVICE Descriptor Type */
+ uint8_t bData[1]; /* Data */
+} usb_descriptor_common_t;
+
+typedef struct _usb_descriptor_device
+{
+ uint8_t bLength; /* Size of this descriptor in bytes */
+ uint8_t bDescriptorType; /* DEVICE Descriptor Type */
+ uint8_t bcdUSB[2]; /* UUSB Specification Release Number in Binary-Coded Decimal, e.g. 0x0200U */
+ uint8_t bDeviceClass; /* Class code */
+ uint8_t bDeviceSubClass; /* Sub-Class code */
+ uint8_t bDeviceProtocol; /* Protocol code */
+ uint8_t bMaxPacketSize0; /* Maximum packet size for endpoint zero */
+ uint8_t idVendor[2]; /* Vendor ID (assigned by the USB-IF) */
+ uint8_t idProduct[2]; /* Product ID (assigned by the manufacturer) */
+ uint8_t bcdDevice[2]; /* Device release number in binary-coded decimal */
+ uint8_t iManufacturer; /* Index of string descriptor describing manufacturer */
+ uint8_t iProduct; /* Index of string descriptor describing product */
+ uint8_t iSerialNumber; /* Index of string descriptor describing the device serial number */
+ uint8_t bNumConfigurations; /* Number of possible configurations */
+} usb_descriptor_device_t;
+
+typedef struct _usb_descriptor_configuration
+{
+ uint8_t bLength; /* Descriptor size in bytes = 9U */
+ uint8_t bDescriptorType; /* CONFIGURATION type = 2U or 7U */
+ uint8_t wTotalLength[2]; /* Length of concatenated descriptors */
+ uint8_t bNumInterfaces; /* Number of interfaces, this configuration. */
+ uint8_t bConfigurationValue; /* Value to set this configuration. */
+ uint8_t iConfiguration; /* Index to configuration string */
+ uint8_t bmAttributes; /* Configuration characteristics */
+ uint8_t bMaxPower; /* Maximum power from bus, 2 mA units */
+} usb_descriptor_configuration_t;
+
+typedef struct _usb_descriptor_interface
+{
+ uint8_t bLength;
+ uint8_t bDescriptorType;
+ uint8_t bInterfaceNumber;
+ uint8_t bAlternateSetting;
+ uint8_t bNumEndpoints;
+ uint8_t bInterfaceClass;
+ uint8_t bInterfaceSubClass;
+ uint8_t bInterfaceProtocol;
+ uint8_t iInterface;
+} usb_descriptor_interface_t;
+
+typedef struct _usb_descriptor_endpoint
+{
+ uint8_t bLength;
+ uint8_t bDescriptorType;
+ uint8_t bEndpointAddress;
+ uint8_t bmAttributes;
+ uint8_t wMaxPacketSize[2];
+ uint8_t bInterval;
+} usb_descriptor_endpoint_t;
+
+typedef union _usb_descriptor_union
+{
+ usb_descriptor_common_t common; /* Common descriptor */
+ usb_descriptor_device_t device; /* Device descriptor */
+ usb_descriptor_configuration_t configuration; /* Configuration descriptor */
+ usb_descriptor_interface_t interface; /* Interface descriptor */
+ usb_descriptor_endpoint_t endpoint; /* Endpoint descriptor */
+} usb_descriptor_union_t;
+
+#endif /* __USB_SPEC_H__ */
diff --git a/usb_1.1.0/osa/usb_osa.h b/usb_1.1.0/osa/usb_osa.h
new file mode 100644
index 0000000..ee898c3
--- /dev/null
+++ b/usb_1.1.0/osa/usb_osa.h
@@ -0,0 +1,578 @@
+/*
+ * Copyright (c) 2015, Freescale Semiconductor, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * o Redistributions of source code must retain the above copyright notice, this list
+ * of conditions and the following disclaimer.
+ *
+ * o Redistributions in binary form must reproduce the above copyright notice, this
+ * list of conditions and the following disclaimer in the documentation and/or
+ * other materials provided with the distribution.
+ *
+ * o Neither the name of Freescale Semiconductor, Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __USB_OSA_H__
+#define __USB_OSA_H__
+
+/*!
+ * @addtogroup usb_os_abstraction
+ * @{
+ */
+
+/*******************************************************************************
+ * Definitions
+ ******************************************************************************/
+
+/*! @brief Define big endian */
+#define BIG_ENDIAN (0U)
+/*! @brief Define little endian */
+#define LITTLE_ENDIAN (1U)
+
+/*! @brief Define current endian */
+#define ENDIANNESS LITTLE_ENDIAN
+
+/*! @brief Define USB OSA event handle */
+typedef void *usb_osa_event_handle;
+
+/*! @brief Define USB OSA semaphore handle */
+typedef void *usb_osa_sem_handle;
+
+/*! @brief Define USB OSA mutex handle */
+typedef void *usb_osa_mutex_handle;
+
+/*! @brief Define USB OSA message queue handle */
+typedef void *usb_osa_msgq_handle;
+
+/*! @brief USB OSA error code */
+typedef enum _usb_osa_status
+{
+ kStatus_USB_OSA_Success = 0x00U, /*!< Success */
+ kStatus_USB_OSA_Error, /*!< Failed */
+ kStatus_USB_OSA_TimeOut, /*!< Timeout occurs while waiting */
+} usb_osa_status_t;
+
+/*! @brief The event flags are cleared automatically or manually.*/
+typedef enum _usb_osa_event_mode
+{
+ kUSB_OsaEventManualClear = 0U, /*!< The flags of the event is cleared manually. */
+ kUSB_OsaEventAutoClear = 1U, /*!< The flags of the event is cleared automatically. */
+} usb_osa_event_mode_t;
+
+#define USB_STACK_FREERTOS
+/* Include required header file based on RTOS selection */
+#if defined(USB_STACK_BM)
+
+#include "usb_osa_bm.h"
+
+#elif defined(USB_STACK_FREERTOS)
+
+#include "usb_osa_freertos.h"
+
+#elif defined(USB_STACK_UCOSII)
+
+#include "usb_osa_ucosii.h"
+
+#elif defined(USB_STACK_UCOSIII)
+
+#include "usb_osa_ucosiii.h"
+
+#else
+
+#error Not define RTOS in file "usb_osa.h".
+
+#endif
+
+/*******************************************************************************
+ * API
+ ******************************************************************************/
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+/*!
+ * @name USB OSA Memory Management
+ * @{
+ */
+
+/*!
+ * @brief Reserves the requested amount of memory in bytes.
+ *
+ * The function is used to reserve the requested amount of memory in bytes and initializes it to 0.
+ *
+ * @param length Amount of bytes to reserve.
+ *
+ * @return Pointer to the reserved memory. NULL if memory can't be allocated.
+ */
+void *USB_OsaMemoryAllocate(uint32_t length);
+
+/*!
+ * @brief Frees the memory previously reserved.
+ *
+ * The function is used to free the memory block previously reserved.
+ *
+ * @param p Pointer to the start of the memory block previously reserved.
+ *
+ */
+extern void USB_OsaMemoryFree(void *p);
+
+/* @} */
+
+/*!
+ * @name USB OSA Event
+ * @{
+ */
+
+/*!
+ * @brief Creates an event object with all flags cleared.
+ *
+ * This function creates an event object and sets its clear mode. If the clear mode
+ * is kUSB_OsaEventAutoClear, when a task gets the event flags, these flags are
+ * cleared automatically. If the clear mode is kUSB_OsaEventManualClear, the flags must
+ * be cleared manually.
+ *
+ * @param handle It is an out parameter, which is used to return the pointer of the event object.
+ * @param flag The event is auto-clear or manual-clear. See the enumeration #usb_osa_event_mode_t.
+ *
+ * @return A USB OSA error code or kStatus_OSA_Success.
+ *
+ * Example:
+ @code
+ usb_osa_event_handle eventHandle;
+ usb_osa_status_t usbOsaStatus;
+ usbOsaStatus = USB_OsaEventCreate(&eventHandle, kUSB_OsaEventManualClear);
+ @endcode
+ *
+ */
+extern usb_osa_status_t USB_OsaEventCreate(usb_osa_event_handle *handle, uint32_t flag);
+
+/*!
+ * @brief Destroys a created event object.
+ *
+ * @param handle Pointer to the event object.
+ *
+ * @return A USB OSA error code or kStatus_OSA_Success.
+ *
+ * Example:
+ @code
+ usb_osa_status_t usbOsaStatus;
+ ...
+ usbOsaStatus = USB_OsaEventDestroy(eventHandle);
+ @endcode
+ *
+ */
+extern usb_osa_status_t USB_OsaEventDestroy(usb_osa_event_handle handle);
+
+/*!
+ * @brief Sets an event flag.
+ *
+ * Sets specified flags for an event object.
+ *
+ * @param handle Pointer to the event object.
+ * @param bitMask Event flags to be set.
+ *
+ * @return A USB OSA error code or kStatus_OSA_Success.
+ *
+ * Example:
+ @code
+ usb_osa_status_t usbOsaStatus;
+ ...
+ usbOsaStatus = USB_OsaEventSet(eventHandle, 0x01U);
+ @endcode
+ *
+ */
+extern usb_osa_status_t USB_OsaEventSet(usb_osa_event_handle handle, uint32_t bitMask);
+
+/*!
+ * @brief Waits for an event flag.
+ *
+ * This function waits for a combination of flags to be set in an event object.
+ * An applications can wait for any/all bits to be set. This function can
+ * get the flags that wake up the waiting task.
+ *
+ * @param handle Pointer to the event object.
+ * @param bitMask Event flags to wait.
+ * @param flag Wait all flags or any flag to be set. 0U - wait any flag, others, wait all flags.
+ * @param timeout The maximum number of milliseconds to wait for the event.
+ * If the wait condition is not met, passing 0U
+ * waits indefinitely when the environment is an RTOS and returns the kStatus_OSA_Timeout
+ * immediately. Pass any value for the bare metal.
+ * @param bitSet Flags that wake up the waiting task are obtained by this parameter.
+ *
+ * @return An USB OSA error code or kStatus_OSA_Success.
+ *
+ * Example:
+ @code
+ usb_osa_status_t usbOsaStatus;
+ uint32_t bitSet;
+ ...
+ usbOsaStatus = USB_OsaEventWait(eventHandle, 0x01U, 0U, 0U, &bitSet);
+ @endcode
+ *
+ */
+extern usb_osa_status_t USB_OsaEventWait(
+ usb_osa_event_handle handle, uint32_t bitMask, uint32_t flag, uint32_t timeout, uint32_t *bitSet);
+
+/*!
+ * @brief Checks an event flag.
+ *
+ * This function checks for a combination of flags to be set in an event object.
+ *
+ * @param handle Pointer to the event object.
+ * @param bitMask Event flags to check.
+ * @param bitSet Flags have been set.
+ *
+ * @return An USB OSA error code or kStatus_OSA_Success.
+ *
+ * Example:
+ @code
+ usb_osa_status_t usbOsaStatus;
+ uint32_t bitSet;
+ ...
+ usbOsaStatus = USB_OsaEventCheck(eventHandle, 0x01U, &bitSet);
+ @endcode
+ *
+ */
+extern usb_osa_status_t USB_OsaEventCheck(usb_osa_event_handle handle, uint32_t bitMask, uint32_t *bitSet);
+
+/*!
+ * @brief Clears an event flag.
+ *
+ * This function clears flags of an event object.
+ *
+ * @param handle Pointer to the event object
+ * @param bitMask Event flags to be cleared.
+ *
+ * @return An USB OSA error code or kStatus_OSA_Success.
+ *
+ * Example:
+ @code
+ usb_osa_status_t usbOsaStatus;
+ ...
+ usbOsaStatus = USB_OsaEventClear(eventHandle, 0x01U);
+ @endcode
+ */
+extern usb_osa_status_t USB_OsaEventClear(usb_osa_event_handle handle, uint32_t bitMask);
+/* @} */
+
+/*!
+ * @name USB OSA Semaphore
+ * @{
+ */
+
+/*!
+ * @brief Creates a semaphore with a given value.
+ *
+ * This function creates a semaphore and sets the default count.
+ *
+ * @param handle It is an out parameter, which is used to return pointer of the semaphore object.
+ * @param count Initializes a value of the semaphore.
+ *
+ * @return An USB OSA error code or kStatus_OSA_Success.
+ *
+ * Example:
+ @code
+ usb_osa_sem_handle semHandle;
+ usb_osa_status_t usbOsaStatus;
+ usbOsaStatus = USB_OsaSemCreate(&semHandle, 1U);
+ @endcode
+ *
+ */
+extern usb_osa_status_t USB_OsaSemCreate(usb_osa_sem_handle *handle, uint32_t count);
+
+/*!
+ * @brief Destroys a semaphore object.
+ *
+ * This function destroys a semaphore object.
+ *
+ * @param handle Pointer to the semaphore.
+ *
+ * @return An USB OSA error code or kStatus_OSA_Success.
+ *
+ * Example:
+ @code
+ usb_osa_sem_handle semHandle;
+ usb_osa_status_t usbOsaStatus;
+ ...
+ usbOsaStatus = USB_OsaSemDestroy(semHandle);
+ @endcode
+ *
+ */
+extern usb_osa_status_t USB_OsaSemDestroy(usb_osa_sem_handle handle);
+
+/*!
+ * @brief Posts a semaphore.
+ *
+ * This function wakes up a task waiting on the semaphore. If a task is not pending, increases the semaphore's
+ value.
+ *
+ * @param handle Pointer to the semaphore.
+ *
+ * @return A USB OSA error code or kStatus_OSA_Success.
+ *
+ * Example:
+ @code
+ usb_osa_sem_handle semHandle;
+ usb_osa_status_t usbOsaStatus;
+ ...
+ usbOsaStatus = USB_OsaSemPost(semHandle);
+ @endcode
+ *
+ */
+extern usb_osa_status_t USB_OsaSemPost(usb_osa_sem_handle handle);
+
+/*!
+ * @brief Waits on a semaphore.
+ *
+ * This function checks the semaphore's value. If it is positive, it decreases the semaphore's value and return
+ kStatus_OSA_Success.
+ *
+ * @param handle Pointer to the semaphore.
+ * @param timeout The maximum number of milliseconds to wait for the semaphore.
+ * If the wait condition is not met, pass 0U
+ * waits indefinitely when environment is RTOS. And return kStatus_OSA_Timeout
+ * immediately for bare metal no matter what value has been passed.
+ *
+ * @return A USB OSA error code or kStatus_OSA_Success.
+ *
+ * Example:
+ @code
+ usb_osa_sem_handle semHandle;
+ usb_osa_status_t usbOsaStatus;
+ ...
+ usbOsaStatus = USB_OsaSemWait(semHandle, 0U);
+ @endcode
+ *
+ */
+extern usb_osa_status_t USB_OsaSemWait(usb_osa_sem_handle handle, uint32_t timeout);
+/* @} */
+
+/*!
+ * @name USB OSA Mutex
+ * @{
+ */
+
+/*!
+ * @brief Creates a mutex.
+ *
+ * This function creates a mutex and sets it to an unlocked status.
+ *
+ * @param handle It is out parameter, which is used to return the pointer of the mutex object.
+ *
+ * @return A USB OSA error code or kStatus_OSA_Success.
+ *
+ * Example:
+ @code
+ usb_osa_mutex_handle mutexHandle;
+ usb_osa_status_t usbOsaStatus;
+ usbOsaStatus = USB_OsaMutexCreate(&mutexHandle);
+ @endcode
+ *
+ */
+extern usb_osa_status_t USB_OsaMutexCreate(usb_osa_mutex_handle *handle);
+
+/*!
+ * @brief Destroys a mutex.
+ *
+ * This function destroys a mutex and sets it to an unlocked status.
+ *
+ * @param handle Pointer to the mutex.
+ *
+ * @return A USB OSA error code or kStatus_OSA_Success.
+ *
+ * Example:
+ @code
+ usb_osa_mutex_handle mutexHandle;
+ usb_osa_status_t usbOsaStatus;
+ ...
+ usbOsaStatus = USB_OsaMutexDestroy(mutexHandle);
+ @endcode
+ *
+ */
+extern usb_osa_status_t USB_OsaMutexDestroy(usb_osa_mutex_handle handle);
+
+/*!
+ * @brief Waits for a mutex and locks it.
+ *
+ * This function checks the mutex status. If it is unlocked, it locks it and returns the
+ * kStatus_OSA_Success. Otherwise, it waits forever to lock in RTOS and returns the
+ * kStatus_OSA_Success immediately for bare metal.
+ *
+ * @param handle Pointer to the mutex.
+ *
+ * @return A USB OSA error code or kStatus_OSA_Success.
+ *
+ * Example:
+ @code
+ usb_osa_mutex_handle mutexHandle;
+ usb_osa_status_t usbOsaStatus;
+ ...
+ usbOsaStatus = USB_OsaMutexLock(mutexHandle);
+ @endcode
+ *
+ */
+extern usb_osa_status_t USB_OsaMutexLock(usb_osa_mutex_handle handle);
+
+/*!
+ * @brief Unlocks a mutex.
+ *
+ * This function unlocks a mutex.
+ *
+ * @param handle Pointer to the mutex.
+ *
+ * @return A USB OSA error code or kStatus_OSA_Success.
+ *
+ * Example:
+ @code
+ usb_osa_mutex_handle mutexHandle;
+ usb_osa_status_t usbOsaStatus;
+ ...
+ usbOsaStatus = USB_OsaMutexUnlock(mutexHandle);
+ @endcode
+ *
+ */
+extern usb_osa_status_t USB_OsaMutexUnlock(usb_osa_mutex_handle handle);
+/* @} */
+
+/*!
+ * @name USB OSA Message Queue
+ * @{
+ */
+
+/*!
+ * @brief Creates a message queue.
+ *
+ * This function creates a message queue.
+ *
+ * @param handle It is an out parameter, which is used to return a pointer of the message queue object.
+ * @param count The count of elements in the queue.
+ * @param size Size of every elements in words.
+ *
+ * @return A USB OSA error code or kStatus_OSA_Success.
+ *
+ * Example:
+ @code
+ usb_osa_msgq_handle msgqHandle;
+ usb_osa_status_t usbOsaStatus;
+ usbOsaStatus = USB_OsaMsgqCreate(msgqHandle, 8U, 4U);
+ @endcode
+ *
+ */
+extern usb_osa_status_t USB_OsaMsgqCreate(usb_osa_msgq_handle *handle, uint32_t count, uint32_t size);
+
+/*!
+ * @brief Destroys a message queue.
+ *
+ * This function destroys a message queue.
+ *
+ * @param handle Pointer to a message queue.
+ *
+ * @return A USB OSA error code or kStatus_OSA_Success.
+ *
+ * Example:
+ @code
+ usb_osa_msgq_handle msgqHandle;
+ usb_osa_status_t usbOsaStatus;
+ ...
+ usbOsaStatus = USB_OsaMsgqDestroy(msgqHandle);
+ @endcode
+ *
+ */
+extern usb_osa_status_t USB_OsaMsgqDestroy(usb_osa_msgq_handle handle);
+
+/*!
+ * @brief Sends a message.
+ *
+ * This function sends a message to the tail of the message queue.
+ *
+ * @param handle Pointer to a message queue.
+ * @param msg The pointer to a message to be put into the queue.
+ *
+ * @return A USB OSA error code or kStatus_OSA_Success.
+ *
+ * Example:
+ @code
+ usb_osa_msgq_handle msgqHandle;
+ message_struct_t message;
+ usb_osa_status_t usbOsaStatus;
+ ...
+ usbOsaStatus = USB_OsaMsgqSend(msgqHandle, &message);
+ @endcode
+ *
+ */
+extern usb_osa_status_t USB_OsaMsgqSend(usb_osa_msgq_handle handle, void *msg);
+
+/*!
+ * @brief Receives a message.
+ *
+ * This function receives a message from the head of the message queue.
+ *
+ * @param handle Pointer to a message queue.
+ * @param msg The pointer to save a received message.
+ * @param timeout The maximum number of milliseconds to wait for a message.
+ * If the wait condition is not met, passing 0U
+ * waits indefinitely when an environment is RTOS and returns the kStatus_OSA_Timeout
+ * immediately for bare metal.
+ *
+ * @return A USB OSA error code or kStatus_OSA_Success.
+ *
+ * Example:
+ @code
+ usb_osa_msgq_handle msgqHandle;
+ message_struct_t message;
+ usb_osa_status_t usbOsaStatus;
+ ...
+ usbOsaStatus = USB_OsaMsgqRecv(msgqHandle, &message, 0U);
+ @endcode
+ *
+ */
+extern usb_osa_status_t USB_OsaMsgqRecv(usb_osa_msgq_handle handle, void *msg, uint32_t timeout);
+
+/*!
+ * @brief Checks a message queue and receives a message if the queue is not empty.
+ *
+ * This function checks a message queue and receives a message if the queue is not empty.
+ *
+ * @param handle Pointer to a message queue.
+ * @param msg The pointer to save a received message.
+ *
+ * @return A USB OSA error code or kStatus_OSA_Success.
+ *
+ * Example:
+ @code
+ usb_osa_msgq_handle msgqHandle;
+ message_struct_t message;
+ usb_osa_status_t usbOsaStatus;
+ ...
+ usbOsaStatus = USB_OsaMsgqCheck(msgqHandle, &message);
+ @endcode
+ *
+ */
+extern usb_osa_status_t USB_OsaMsgqCheck(usb_osa_msgq_handle handle, void *msg);
+
+/* @} */
+
+#if defined(__cplusplus)
+}
+#endif
+
+/* @} */
+
+#endif /* __USB_OSA_H__ */
diff --git a/usb_1.1.0/osa/usb_osa_bm.c b/usb_1.1.0/osa/usb_osa_bm.c
new file mode 100644
index 0000000..01e45ff
--- /dev/null
+++ b/usb_1.1.0/osa/usb_osa_bm.c
@@ -0,0 +1,538 @@
+/*
+ * Copyright (c) 2015 - 2016, Freescale Semiconductor, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * o Redistributions of source code must retain the above copyright notice, this list
+ * of conditions and the following disclaimer.
+ *
+ * o Redistributions in binary form must reproduce the above copyright notice, this
+ * list of conditions and the following disclaimer in the documentation and/or
+ * other materials provided with the distribution.
+ *
+ * o Neither the name of Freescale Semiconductor, Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#include "stdint.h"
+#include "usb.h"
+#include "usb_osa.h"
+#include "stdlib.h"
+#include "fsl_device_registers.h"
+
+/*******************************************************************************
+ * Definitions
+ ******************************************************************************/
+#define USB_OSA_BM_EVENT_COUNT (2U)
+#define USB_OSA_BM_SEM_COUNT (1U)
+#define USB_OSA_BM_MSGQ_COUNT (1U)
+#define USB_OSA_BM_MSG_COUNT (8U)
+#define USB_OSA_BM_MSG_SIZE (4U)
+
+/* BM Event status structure */
+typedef struct _usb_osa_event_struct
+{
+ uint32_t value; /* Event mask */
+ uint32_t flag; /* Event flags, includes auto clear flag */
+ uint8_t isUsed; /* Is used */
+} usb_osa_event_struct_t;
+
+/* BM semaphore status structure */
+typedef struct _usb_osa_sem_struct
+{
+ uint32_t value; /* Semaphore count */
+ uint8_t isUsed; /* Is used */
+} usb_osa_sem_struct_t;
+
+/* BM msg status structure */
+typedef struct _usb_osa_msg_struct
+{
+ uint32_t msg[USB_OSA_BM_MSG_SIZE]; /* Message entity pointer */
+} usb_osa_msg_struct_t;
+
+/* BM msgq status structure */
+typedef struct _usb_osa_msgq_struct
+{
+ usb_osa_msg_struct_t msgs[USB_OSA_BM_MSG_COUNT]; /* Message entity list */
+ uint32_t count; /* Max message entity count */
+ uint32_t msgSize; /* Size of each message */
+ uint32_t msgCount; /* Valid messages */
+ uint32_t index; /* The first empty message entity index */
+ uint32_t current; /* The vaild message index */
+ uint8_t isUsed; /* Is used */
+} usb_osa_msgq_struct_t;
+
+/*******************************************************************************
+ * Prototypes
+ ******************************************************************************/
+
+/*******************************************************************************
+ * Variables
+ ******************************************************************************/
+
+USB_GLOBAL static usb_osa_sem_struct_t s_UsbBmSemStruct[USB_OSA_BM_SEM_COUNT];
+USB_GLOBAL static usb_osa_event_struct_t s_UsbBmEventStruct[USB_OSA_BM_EVENT_COUNT];
+USB_GLOBAL static usb_osa_msgq_struct_t s_UsbBmMsgqStruct[USB_OSA_BM_MSGQ_COUNT];
+
+/*******************************************************************************
+ * Code
+ ******************************************************************************/
+
+void *USB_OsaMemoryAllocate(uint32_t length)
+{
+ void *p = (void *)malloc(length);
+ uint8_t *temp = (uint8_t *)p;
+ if (p)
+ {
+ for (uint32_t count = 0U; count < length; count++)
+ {
+ temp[count] = 0U;
+ }
+ }
+ return p;
+}
+
+void USB_OsaMemoryFree(void *p)
+{
+ free(p);
+}
+
+void USB_OsaEnterCritical(uint8_t *sr)
+{
+ *sr = __get_PRIMASK();
+ __ASM("CPSID I");
+}
+
+void USB_OsaExitCritical(uint8_t sr)
+{
+ __set_PRIMASK(sr);
+}
+
+usb_osa_status_t USB_OsaEventCreate(usb_osa_event_handle *handle, uint32_t flag)
+{
+ usb_osa_event_struct_t *event = NULL;
+ USB_OSA_SR_ALLOC();
+
+ if (!handle)
+ {
+ return kStatus_USB_OSA_Error;
+ }
+
+ USB_OSA_ENTER_CRITICAL();
+ for (uint32_t i = 0; i < USB_OSA_BM_EVENT_COUNT; i++)
+ {
+ if (0 == s_UsbBmEventStruct[i].isUsed)
+ {
+ event = &s_UsbBmEventStruct[i];
+ break;
+ }
+ }
+
+ if (NULL == event)
+ {
+ USB_OSA_EXIT_CRITICAL();
+ return kStatus_USB_OSA_Error;
+ }
+
+ event->value = 0U;
+ event->flag = flag;
+ event->isUsed = 1;
+ *handle = event;
+ USB_OSA_EXIT_CRITICAL();
+ return kStatus_USB_OSA_Success;
+}
+
+usb_osa_status_t USB_OsaEventDestroy(usb_osa_event_handle handle)
+{
+ usb_osa_event_struct_t *event = (usb_osa_event_struct_t *)handle;
+ USB_OSA_SR_ALLOC();
+
+ if (handle)
+ {
+ USB_OSA_ENTER_CRITICAL();
+ event->isUsed = 0;
+ USB_OSA_EXIT_CRITICAL();
+ return kStatus_USB_OSA_Success;
+ }
+ return kStatus_USB_OSA_Error;
+}
+
+usb_osa_status_t USB_OsaEventSet(usb_osa_event_handle handle, uint32_t bitMask)
+{
+ usb_osa_event_struct_t *event = (usb_osa_event_struct_t *)handle;
+ USB_OSA_SR_ALLOC();
+
+ if (handle)
+ {
+ USB_OSA_ENTER_CRITICAL();
+ event->value |= bitMask;
+ USB_OSA_EXIT_CRITICAL();
+ return kStatus_USB_OSA_Success;
+ }
+ return kStatus_USB_OSA_Error;
+}
+
+usb_osa_status_t USB_OsaEventWait(
+ usb_osa_event_handle handle, uint32_t bitMask, uint32_t flag, uint32_t timeout, uint32_t *bitSet)
+{
+ usb_osa_event_struct_t *event = (usb_osa_event_struct_t *)handle;
+ uint32_t bits;
+ USB_OSA_SR_ALLOC();
+
+ if (handle)
+ {
+ USB_OSA_ENTER_CRITICAL();
+ bits = event->value & bitMask;
+ if (flag)
+ {
+ if (bits != bitMask)
+ {
+ USB_OSA_EXIT_CRITICAL();
+ return kStatus_USB_OSA_TimeOut;
+ }
+ }
+ else
+ {
+ if (!bits)
+ {
+ USB_OSA_EXIT_CRITICAL();
+ return kStatus_USB_OSA_TimeOut;
+ }
+ }
+ if (bitSet)
+ {
+ *bitSet = bits;
+ }
+ if (event->flag)
+ {
+ event->value &= ~bits;
+ }
+ USB_OSA_EXIT_CRITICAL();
+ return kStatus_USB_OSA_Success;
+ }
+ return kStatus_USB_OSA_Error;
+}
+
+usb_osa_status_t USB_OsaEventCheck(usb_osa_event_handle handle, uint32_t bitMask, uint32_t *bitSet)
+{
+ usb_osa_event_struct_t *event = (usb_osa_event_struct_t *)handle;
+ uint32_t bits;
+ USB_OSA_SR_ALLOC();
+
+ if (handle)
+ {
+ USB_OSA_ENTER_CRITICAL();
+ bits = event->value & bitMask;
+
+ if (!bits)
+ {
+ USB_OSA_EXIT_CRITICAL();
+ return kStatus_USB_OSA_Error;
+ }
+
+ if (bitSet)
+ {
+ *bitSet = bits;
+ }
+ USB_OSA_EXIT_CRITICAL();
+ return kStatus_USB_OSA_Success;
+ }
+ return kStatus_USB_OSA_Error;
+}
+
+usb_osa_status_t USB_OsaEventClear(usb_osa_event_handle handle, uint32_t bitMask)
+{
+ usb_osa_event_struct_t *event = (usb_osa_event_struct_t *)handle;
+ uint32_t bits;
+ USB_OSA_SR_ALLOC();
+
+ if (handle)
+ {
+ USB_OSA_ENTER_CRITICAL();
+ bits = event->value & bitMask;
+ event->value &= ~bits;
+ USB_OSA_EXIT_CRITICAL();
+ return kStatus_USB_OSA_Success;
+ }
+ return kStatus_USB_OSA_Error;
+}
+
+usb_osa_status_t USB_OsaSemCreate(usb_osa_sem_handle *handle, uint32_t count)
+{
+ usb_osa_sem_struct_t *sem = NULL;
+ USB_OSA_SR_ALLOC();
+
+ if (!handle)
+ {
+ return kStatus_USB_OSA_Error;
+ }
+
+ USB_OSA_ENTER_CRITICAL();
+ for (uint32_t i = 0; i < USB_OSA_BM_SEM_COUNT; i++)
+ {
+ if (0 == s_UsbBmSemStruct[i].isUsed)
+ {
+ sem = &s_UsbBmSemStruct[i];
+ break;
+ }
+ }
+ if (NULL == sem)
+ {
+ USB_OSA_EXIT_CRITICAL();
+ return kStatus_USB_OSA_Error;
+ }
+
+ sem->value = count;
+ sem->isUsed = 1;
+ *handle = sem;
+ USB_OSA_EXIT_CRITICAL();
+ return kStatus_USB_OSA_Success;
+}
+
+usb_osa_status_t USB_OsaSemDestroy(usb_osa_sem_handle handle)
+{
+ usb_osa_sem_struct_t *sem = (usb_osa_sem_struct_t *)handle;
+ USB_OSA_SR_ALLOC();
+
+ if (handle)
+ {
+ USB_OSA_ENTER_CRITICAL();
+ sem->isUsed = 0;
+ USB_OSA_EXIT_CRITICAL();
+ return kStatus_USB_OSA_Success;
+ }
+ return kStatus_USB_OSA_Error;
+}
+
+usb_osa_status_t USB_OsaSemPost(usb_osa_sem_handle handle)
+{
+ usb_osa_sem_struct_t *sem = (usb_osa_sem_struct_t *)handle;
+ USB_OSA_SR_ALLOC();
+
+ if (!handle)
+ {
+ return kStatus_USB_OSA_Error;
+ }
+
+ USB_OSA_ENTER_CRITICAL();
+ sem->value++;
+ USB_OSA_EXIT_CRITICAL();
+ return kStatus_USB_OSA_Success;
+}
+
+usb_osa_status_t USB_OsaSemWait(usb_osa_sem_handle handle, uint32_t timeout)
+{
+ usb_osa_sem_struct_t *sem = (usb_osa_sem_struct_t *)handle;
+ USB_OSA_SR_ALLOC();
+
+ if (!handle)
+ {
+ return kStatus_USB_OSA_Error;
+ }
+
+ USB_OSA_ENTER_CRITICAL();
+ if (sem->value)
+ {
+ sem->value--;
+ }
+ else
+ {
+ USB_OSA_EXIT_CRITICAL();
+ return kStatus_USB_OSA_TimeOut;
+ }
+ USB_OSA_EXIT_CRITICAL();
+ return kStatus_USB_OSA_Success;
+}
+
+usb_osa_status_t USB_OsaMutexCreate(usb_osa_mutex_handle *handle)
+{
+ if (!handle)
+ {
+ return kStatus_USB_OSA_Error;
+ }
+ *handle = (usb_osa_mutex_handle)0xFFFF0000U;
+ return kStatus_USB_OSA_Success;
+}
+
+usb_osa_status_t USB_OsaMutexDestroy(usb_osa_mutex_handle handle)
+{
+ return kStatus_USB_OSA_Success;
+}
+usb_osa_status_t USB_OsaMutexLock(usb_osa_mutex_handle handle)
+{
+ return kStatus_USB_OSA_Success;
+}
+usb_osa_status_t USB_OsaMutexUnlock(usb_osa_mutex_handle handle)
+{
+ return kStatus_USB_OSA_Success;
+}
+
+usb_osa_status_t USB_OsaMsgqCreate(usb_osa_msgq_handle *handle, uint32_t count, uint32_t size)
+{
+ usb_osa_msgq_struct_t *msgq = NULL;
+ USB_OSA_SR_ALLOC();
+
+ if (!handle)
+ {
+ return kStatus_USB_OSA_Error;
+ }
+ USB_OSA_ENTER_CRITICAL();
+
+ for (uint32_t i = 0; i < USB_OSA_BM_MSGQ_COUNT; i++)
+ {
+ if (0 == s_UsbBmMsgqStruct[i].isUsed)
+ {
+ msgq = &s_UsbBmMsgqStruct[i];
+ break;
+ }
+ }
+ if ((NULL == msgq) || (count > USB_OSA_BM_MSG_COUNT) || (size > USB_OSA_BM_MSG_SIZE))
+ {
+ USB_OSA_EXIT_CRITICAL();
+ return kStatus_USB_OSA_Error;
+ }
+ msgq->count = count;
+ msgq->msgSize = size;
+ msgq->msgCount = 0U;
+ msgq->index = 0U;
+ msgq->current = 0U;
+ msgq->isUsed = 1;
+ *handle = msgq;
+ USB_OSA_EXIT_CRITICAL();
+ return kStatus_USB_OSA_Success;
+}
+
+usb_osa_status_t USB_OsaMsgqDestroy(usb_osa_msgq_handle handle)
+{
+ usb_osa_msgq_struct_t *msgq = (usb_osa_msgq_struct_t *)handle;
+ USB_OSA_SR_ALLOC();
+
+ if (!handle)
+ {
+ return kStatus_USB_OSA_Error;
+ }
+ USB_OSA_ENTER_CRITICAL();
+ msgq->isUsed = 0;
+ USB_OSA_EXIT_CRITICAL();
+ return kStatus_USB_OSA_Success;
+}
+
+usb_osa_status_t USB_OsaMsgqSend(usb_osa_msgq_handle handle, void *msg)
+{
+ usb_osa_msgq_struct_t *msgq = (usb_osa_msgq_struct_t *)handle;
+ usb_osa_msg_struct_t *msgEntity;
+ uint32_t *p;
+ uint32_t *q;
+ uint32_t count;
+ USB_OSA_SR_ALLOC();
+
+ if (!handle)
+ {
+ return kStatus_USB_OSA_Error;
+ }
+ USB_OSA_ENTER_CRITICAL();
+ if (msgq->msgCount >= msgq->count)
+ {
+ USB_OSA_EXIT_CRITICAL();
+ return kStatus_USB_OSA_Error;
+ }
+
+ msgEntity = &msgq->msgs[msgq->index];
+ p = (uint32_t *)&msgEntity->msg[0];
+ q = (uint32_t *)msg;
+
+ for (count = 0U; count < msgq->msgSize; count++)
+ {
+ p[count] = q[count];
+ }
+
+ if (0U == msgq->msgCount)
+ {
+ msgq->current = msgq->index;
+ }
+
+ msgq->msgCount++;
+ msgq->index++;
+ msgq->index = msgq->index % msgq->count;
+
+ USB_OSA_EXIT_CRITICAL();
+
+ return kStatus_USB_OSA_Success;
+}
+
+usb_osa_status_t USB_OsaMsgqRecv(usb_osa_msgq_handle handle, void *msg, uint32_t timeout)
+{
+ usb_osa_msgq_struct_t *msgq = (usb_osa_msgq_struct_t *)handle;
+ usb_osa_msg_struct_t *msgEntity;
+ uint32_t *p;
+ uint32_t *q;
+ uint32_t count;
+ USB_OSA_SR_ALLOC();
+
+ if (!handle)
+ {
+ return kStatus_USB_OSA_Error;
+ }
+ USB_OSA_ENTER_CRITICAL();
+ if (msgq->msgCount < 1U)
+ {
+ USB_OSA_EXIT_CRITICAL();
+ return kStatus_USB_OSA_TimeOut;
+ }
+
+ msgEntity = &msgq->msgs[msgq->current];
+ q = (uint32_t *)&msgEntity->msg[0];
+ p = (uint32_t *)msg;
+
+ for (count = 0U; count < msgq->msgSize; count++)
+ {
+ p[count] = q[count];
+ }
+
+ msgq->msgCount--;
+ msgq->current++;
+ msgq->current = msgq->current % msgq->count;
+
+ USB_OSA_EXIT_CRITICAL();
+
+ return kStatus_USB_OSA_Success;
+}
+
+usb_osa_status_t USB_OsaMsgqCheck(usb_osa_msgq_handle handle, void *msg)
+{
+ usb_osa_msgq_struct_t *msgq = (usb_osa_msgq_struct_t *)handle;
+ uint32_t msgCount;
+ USB_OSA_SR_ALLOC();
+
+ if (!handle)
+ {
+ return kStatus_USB_OSA_Error;
+ }
+
+ USB_OSA_ENTER_CRITICAL();
+ msgCount = msgq->msgCount;
+ USB_OSA_EXIT_CRITICAL();
+
+ if (msgCount)
+ {
+ if (kStatus_USB_OSA_Success == USB_OsaMsgqRecv(msgq, msg, 0U))
+ {
+ return kStatus_USB_OSA_Success;
+ }
+ }
+
+ return kStatus_USB_OSA_Error;
+}
diff --git a/usb_1.1.0/osa/usb_osa_bm.h b/usb_1.1.0/osa/usb_osa_bm.h
new file mode 100644
index 0000000..e3232d3
--- /dev/null
+++ b/usb_1.1.0/osa/usb_osa_bm.h
@@ -0,0 +1,57 @@
+/*
+ * Copyright (c) 2015 - 2016, Freescale Semiconductor, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * o Redistributions of source code must retain the above copyright notice, this list
+ * of conditions and the following disclaimer.
+ *
+ * o Redistributions in binary form must reproduce the above copyright notice, this
+ * list of conditions and the following disclaimer in the documentation and/or
+ * other materials provided with the distribution.
+ *
+ * o Neither the name of Freescale Semiconductor, Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __USB_OSA_BM_H__
+#define __USB_OSA_BM_H__
+
+/*******************************************************************************
+ * Definitions
+ ******************************************************************************/
+
+#define USB_OSA_SR_ALLOC() uint8_t usbOsaCurrentSr;
+#define USB_OSA_ENTER_CRITICAL() USB_OsaEnterCritical(&usbOsaCurrentSr)
+#define USB_OSA_EXIT_CRITICAL() USB_OsaExitCritical(usbOsaCurrentSr)
+
+/*******************************************************************************
+ * API
+ ******************************************************************************/
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+extern void USB_OsaEnterCritical(uint8_t *sr);
+extern void USB_OsaExitCritical(uint8_t sr);
+
+#if defined(__cplusplus)
+}
+#endif
+
+#endif /* __USB_OSA_BM_H__ */
diff --git a/usb_1.1.0/osa/usb_osa_freertos.c b/usb_1.1.0/osa/usb_osa_freertos.c
new file mode 100644
index 0000000..0fcaabb
--- /dev/null
+++ b/usb_1.1.0/osa/usb_osa_freertos.c
@@ -0,0 +1,490 @@
+/*
+ * Copyright (c) 2015, Freescale Semiconductor, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * o Redistributions of source code must retain the above copyright notice, this list
+ * of conditions and the following disclaimer.
+ *
+ * o Redistributions in binary form must reproduce the above copyright notice, this
+ * list of conditions and the following disclaimer in the documentation and/or
+ * other materials provided with the distribution.
+ *
+ * o Neither the name of Freescale Semiconductor, Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "stdint.h"
+#include "fsl_device_registers.h"
+#include "usb.h"
+#include "usb_osa.h"
+
+/*******************************************************************************
+ * Definitions
+ ******************************************************************************/
+
+#define MSEC_TO_TICK(msec) ((1000L + ((uint32_t)configTICK_RATE_HZ * (uint32_t)(msec - 1U))) / 1000L)
+#define TICKS_TO_MSEC(tick) ((tick)*1000uL / (uint32_t)configTICK_RATE_HZ)
+
+/* FreeRTOS Event status structure */
+typedef struct _usb_osa_event_struct
+{
+ EventGroupHandle_t handle; /* The event handle */
+ uint32_t flag; /* Event flags, includes auto clear flag */
+} usb_osa_event_struct_t;
+
+/*******************************************************************************
+ * Prototypes
+ ******************************************************************************/
+
+/*******************************************************************************
+ * Variables
+ ******************************************************************************/
+
+/*******************************************************************************
+ * Code
+ ******************************************************************************/
+
+void *USB_OsaMemoryAllocate(uint32_t length)
+{
+ void *p = (void *)pvPortMalloc(length);
+ uint8_t *temp = (uint8_t *)p;
+ if (p)
+ {
+ for (uint32_t count = 0U; count < length; count++)
+ {
+ temp[count] = 0U;
+ }
+ }
+ return p;
+}
+
+void USB_OsaMemoryFree(void *p)
+{
+ vPortFree(p);
+}
+void USB_OsaEnterCritical(uint8_t *sr)
+{
+ if (__get_IPSR())
+ {
+ *sr = portSET_INTERRUPT_MASK_FROM_ISR();
+ }
+ else
+ {
+ portENTER_CRITICAL();
+ }
+}
+
+void USB_OsaExitCritical(uint8_t sr)
+{
+ if (__get_IPSR())
+ {
+ portCLEAR_INTERRUPT_MASK_FROM_ISR(sr);
+ }
+ else
+ {
+ portEXIT_CRITICAL();
+ }
+}
+
+usb_osa_status_t USB_OsaEventCreate(usb_osa_event_handle *handle, uint32_t flag)
+{
+ usb_osa_event_struct_t *event;
+
+ if (!handle)
+ {
+ return kStatus_USB_OSA_Error;
+ }
+ event = (usb_osa_event_struct_t *)USB_OsaMemoryAllocate(sizeof(usb_osa_event_struct_t));
+ if (NULL == event)
+ {
+ return kStatus_USB_OSA_Error;
+ }
+
+ event->handle = xEventGroupCreate();
+ if (NULL == event->handle)
+ {
+ USB_OsaMemoryFree(event);
+ return kStatus_USB_OSA_Error;
+ }
+ event->flag = flag;
+ *handle = event;
+ return kStatus_USB_OSA_Success;
+}
+
+usb_osa_status_t USB_OsaEventDestroy(usb_osa_event_handle handle)
+{
+ usb_osa_event_struct_t *event = (usb_osa_event_struct_t *)handle;
+ if (handle)
+ {
+ if (event->handle)
+ {
+ vEventGroupDelete(event->handle);
+ }
+ USB_OsaMemoryFree(handle);
+ return kStatus_USB_OSA_Success;
+ }
+ return kStatus_USB_OSA_Error;
+}
+
+usb_osa_status_t USB_OsaEventSet(usb_osa_event_handle handle, uint32_t bitMask)
+{
+ usb_osa_event_struct_t *event = (usb_osa_event_struct_t *)handle;
+ portBASE_TYPE taskToWake = pdFALSE;
+ if (handle)
+ {
+ if (__get_IPSR())
+ {
+ if (pdPASS == xEventGroupSetBitsFromISR(event->handle, (EventBits_t)bitMask, &taskToWake))
+ {
+ portYIELD_FROM_ISR(taskToWake);
+ }
+ }
+ else
+ {
+ xEventGroupSetBits(event->handle, (EventBits_t)bitMask);
+ }
+ return kStatus_USB_OSA_Success;
+ }
+ return kStatus_USB_OSA_Error;
+}
+
+usb_osa_status_t USB_OsaEventWait(
+ usb_osa_event_handle handle, uint32_t bitMask, uint32_t flag, uint32_t timeout, uint32_t *bitSet)
+{
+ usb_osa_event_struct_t *event = (usb_osa_event_struct_t *)handle;
+ BaseType_t autoClear;
+ EventBits_t bits;
+
+ if (handle)
+ {
+ if (!timeout)
+ {
+ timeout = portMAX_DELAY;
+ }
+ else
+ {
+ timeout = MSEC_TO_TICK(timeout);
+ }
+
+ if (event->flag)
+ {
+ autoClear = pdTRUE;
+ }
+ else
+ {
+ autoClear = pdFALSE;
+ }
+
+ bits = xEventGroupWaitBits(event->handle, (EventBits_t)bitMask, autoClear, (BaseType_t)flag, timeout);
+
+ if (bitSet)
+ {
+ *bitSet = bits & ((EventBits_t)bitMask);
+ if (*bitSet)
+ {
+ return kStatus_USB_OSA_Success;
+ }
+ return kStatus_USB_OSA_TimeOut;
+ }
+ }
+ return kStatus_USB_OSA_Error;
+}
+
+usb_osa_status_t USB_OsaEventCheck(usb_osa_event_handle handle, uint32_t bitMask, uint32_t *bitSet)
+{
+ usb_osa_event_struct_t *event = (usb_osa_event_struct_t *)handle;
+ EventBits_t bits;
+
+ if (handle)
+ {
+ if (__get_IPSR())
+ {
+ bits = xEventGroupGetBitsFromISR(event->handle);
+ }
+ else
+ {
+ bits = xEventGroupGetBits(event->handle);
+ }
+ bits = (bits & bitMask);
+ if (bits)
+ {
+ if (bitSet)
+ {
+ *bitSet = bits & ((EventBits_t)bitMask);
+ }
+ return kStatus_USB_OSA_Success;
+ }
+ }
+ return kStatus_USB_OSA_Error;
+}
+
+usb_osa_status_t USB_OsaEventClear(usb_osa_event_handle handle, uint32_t bitMask)
+{
+ EventBits_t ev;
+ usb_osa_event_struct_t *event = (usb_osa_event_struct_t *)handle;
+
+ if (handle)
+ {
+ if (__get_IPSR())
+ {
+ xEventGroupClearBitsFromISR(event->handle, (EventBits_t)bitMask);
+ }
+ else
+ {
+ ev = xEventGroupClearBits(event->handle, (EventBits_t)bitMask);
+ if (ev == 0)
+ {
+ return kStatus_USB_OSA_Error;
+ }
+ }
+ return kStatus_USB_OSA_Success;
+ }
+ return kStatus_USB_OSA_Error;
+}
+
+usb_osa_status_t USB_OsaSemCreate(usb_osa_sem_handle *handle, uint32_t count)
+{
+ if (!handle)
+ {
+ return kStatus_USB_OSA_Error;
+ }
+
+ *handle = (usb_osa_sem_handle)xSemaphoreCreateCounting(0xFFU, count);
+ if (NULL == (*handle))
+ {
+ return kStatus_USB_OSA_Error;
+ }
+ return kStatus_USB_OSA_Success;
+}
+
+usb_osa_status_t USB_OsaSemDestroy(usb_osa_sem_handle handle)
+{
+ if (handle)
+ {
+ vSemaphoreDelete(handle);
+ return kStatus_USB_OSA_Success;
+ }
+ return kStatus_USB_OSA_Error;
+}
+
+usb_osa_status_t USB_OsaSemPost(usb_osa_sem_handle handle)
+{
+ xSemaphoreHandle sem = (xSemaphoreHandle)handle;
+ portBASE_TYPE taskToWake = pdFALSE;
+
+ if (!handle)
+ {
+ return kStatus_USB_OSA_Error;
+ }
+
+ if (__get_IPSR())
+ {
+ if (pdPASS == xSemaphoreGiveFromISR(sem, &taskToWake))
+ {
+ portYIELD_FROM_ISR(taskToWake);
+ return kStatus_USB_OSA_Success;
+ }
+ }
+ else
+ {
+ if (pdTRUE == xSemaphoreGive(sem))
+ {
+ return kStatus_USB_OSA_Success;
+ }
+ }
+ return kStatus_USB_OSA_Error;
+}
+
+usb_osa_status_t USB_OsaSemWait(usb_osa_sem_handle handle, uint32_t timeout)
+{
+ xSemaphoreHandle sem = (xSemaphoreHandle)handle;
+
+ if (!handle)
+ {
+ return kStatus_USB_OSA_Error;
+ }
+
+ if (!timeout)
+ {
+ timeout = portMAX_DELAY;
+ }
+ else
+ {
+ timeout = MSEC_TO_TICK(timeout);
+ }
+
+ if (pdFALSE == xSemaphoreTake(sem, timeout))
+ {
+ return kStatus_USB_OSA_TimeOut;
+ }
+ return kStatus_USB_OSA_Success;
+}
+
+usb_osa_status_t USB_OsaMutexCreate(usb_osa_mutex_handle *handle)
+{
+ if (!handle)
+ {
+ return kStatus_USB_OSA_Error;
+ }
+ *handle = (usb_osa_mutex_handle)xSemaphoreCreateRecursiveMutex();
+ if (NULL == *handle)
+ {
+ return kStatus_USB_OSA_Error;
+ }
+ return kStatus_USB_OSA_Success;
+}
+
+usb_osa_status_t USB_OsaMutexDestroy(usb_osa_mutex_handle handle)
+{
+ if (!handle)
+ {
+ return kStatus_USB_OSA_Error;
+ }
+ vSemaphoreDelete((xSemaphoreHandle)handle);
+ return kStatus_USB_OSA_Success;
+}
+
+usb_osa_status_t USB_OsaMutexLock(usb_osa_mutex_handle handle)
+{
+ xSemaphoreHandle mutex = (xSemaphoreHandle)handle;
+
+ if (!handle)
+ {
+ return kStatus_USB_OSA_Error;
+ }
+
+ if (xSemaphoreTakeRecursive(mutex, portMAX_DELAY) == pdFALSE)
+ {
+ return kStatus_USB_OSA_TimeOut;
+ }
+
+ return kStatus_USB_OSA_Success;
+}
+
+usb_osa_status_t USB_OsaMutexUnlock(usb_osa_mutex_handle handle)
+{
+ xSemaphoreHandle mutex = (xSemaphoreHandle)handle;
+
+ if (!handle)
+ {
+ return kStatus_USB_OSA_Error;
+ }
+
+ if (xSemaphoreGiveRecursive(mutex) == pdFALSE)
+ {
+ return kStatus_USB_OSA_Error;
+ }
+ return kStatus_USB_OSA_Success;
+}
+
+usb_osa_status_t USB_OsaMsgqCreate(usb_osa_msgq_handle *handle, uint32_t count, uint32_t size)
+{
+ if (!handle)
+ {
+ return kStatus_USB_OSA_Error;
+ }
+ *handle = xQueueCreate(count, size * sizeof(uint32_t));
+ if (NULL == *handle)
+ {
+ return kStatus_USB_OSA_Error;
+ }
+
+ return kStatus_USB_OSA_Success;
+}
+
+usb_osa_status_t USB_OsaMsgqDestroy(usb_osa_msgq_handle handle)
+{
+ if (!handle)
+ {
+ return kStatus_USB_OSA_Error;
+ }
+ vQueueDelete((xQueueHandle)handle);
+ return kStatus_USB_OSA_Success;
+}
+
+usb_osa_status_t USB_OsaMsgqSend(usb_osa_msgq_handle handle, void *msg)
+{
+ xQueueHandle msgq = (xQueueHandle)handle;
+ portBASE_TYPE taskToWake = pdFALSE;
+
+ if (!handle)
+ {
+ return kStatus_USB_OSA_Error;
+ }
+
+ if (__get_IPSR())
+ {
+ if (pdPASS == xQueueSendToBackFromISR(msgq, msg, &taskToWake))
+ {
+ portYIELD_FROM_ISR(taskToWake);
+ return kStatus_USB_OSA_Success;
+ }
+ }
+ else
+ {
+ if (pdPASS == xQueueSendToBack(msgq, msg, 0U))
+ {
+ return kStatus_USB_OSA_Success;
+ }
+ }
+ return kStatus_USB_OSA_Error;
+}
+
+usb_osa_status_t USB_OsaMsgqRecv(usb_osa_msgq_handle handle, void *msg, uint32_t timeout)
+{
+ xQueueHandle msgq = (xQueueHandle)handle;
+
+ if (!handle)
+ {
+ return kStatus_USB_OSA_Error;
+ }
+
+ if (!timeout)
+ {
+ timeout = portMAX_DELAY;
+ }
+ else
+ {
+ timeout = MSEC_TO_TICK(timeout);
+ }
+ if (pdPASS != xQueueReceive(msgq, msg, timeout))
+ {
+ return kStatus_USB_OSA_TimeOut;
+ }
+ return kStatus_USB_OSA_Success;
+}
+
+usb_osa_status_t USB_OsaMsgqCheck(usb_osa_msgq_handle handle, void *msg)
+{
+ xQueueHandle msgq = (xQueueHandle)handle;
+
+ if (!handle)
+ {
+ return kStatus_USB_OSA_Error;
+ }
+
+ if (uxQueueMessagesWaiting(msgq))
+ {
+ if (pdPASS == xQueueReceive(msgq, msg, 1U))
+ {
+ return kStatus_USB_OSA_Success;
+ }
+ }
+
+ return kStatus_USB_OSA_Error;
+}
diff --git a/usb_1.1.0/osa/usb_osa_freertos.h b/usb_1.1.0/osa/usb_osa_freertos.h
new file mode 100644
index 0000000..b6f7bb1
--- /dev/null
+++ b/usb_1.1.0/osa/usb_osa_freertos.h
@@ -0,0 +1,111 @@
+/*
+ * Copyright (c) 2015, Freescale Semiconductor, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * o Redistributions of source code must retain the above copyright notice, this list
+ * of conditions and the following disclaimer.
+ *
+ * o Redistributions in binary form must reproduce the above copyright notice, this
+ * list of conditions and the following disclaimer in the documentation and/or
+ * other materials provided with the distribution.
+ *
+ * o Neither the name of Freescale Semiconductor, Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __USB_OSA_FREERTOS_H__
+#define __USB_OSA_FREERTOS_H__
+
+#if defined(__IAR_SYSTEMS_ICC__)
+/**
+ * Workaround to disable MISRA C message suppress warnings for IAR compiler.
+ * http://supp.iar.com/Support/?note=24725
+ */
+#define MISRAC_DISABLE \
+ _Pragma( \
+ "diag_suppress= \
+ Pm001,Pm002,Pm003,Pm004,Pm005,Pm006,Pm007,Pm008,Pm009,Pm010,Pm011,\
+ Pm012,Pm013,Pm014,Pm015,Pm016,Pm017,Pm018,Pm019,Pm020,Pm021,Pm022,\
+ Pm023,Pm024,Pm025,Pm026,Pm027,Pm028,Pm029,Pm030,Pm031,Pm032,Pm033,\
+ Pm034,Pm035,Pm036,Pm037,Pm038,Pm039,Pm040,Pm041,Pm042,Pm043,Pm044,\
+ Pm045,Pm046,Pm047,Pm048,Pm049,Pm050,Pm051,Pm052,Pm053,Pm054,Pm055,\
+ Pm056,Pm057,Pm058,Pm059,Pm060,Pm061,Pm062,Pm063,Pm064,Pm065,Pm066,\
+ Pm067,Pm068,Pm069,Pm070,Pm071,Pm072,Pm073,Pm074,Pm075,Pm076,Pm077,\
+ Pm078,Pm079,Pm080,Pm081,Pm082,Pm083,Pm084,Pm085,Pm086,Pm087,Pm088,\
+ Pm089,Pm090,Pm091,Pm092,Pm093,Pm094,Pm095,Pm096,Pm097,Pm098,Pm099,\
+ Pm100,Pm101,Pm102,Pm103,Pm104,Pm105,Pm106,Pm107,Pm108,Pm109,Pm110,\
+ Pm111,Pm112,Pm113,Pm114,Pm115,Pm116,Pm117,Pm118,Pm119,Pm120,Pm121,\
+ Pm122,Pm123,Pm124,Pm125,Pm126,Pm127,Pm128,Pm129,Pm130,Pm131,Pm132,\
+ Pm133,Pm134,Pm135,Pm136,Pm137,Pm138,Pm139,Pm140,Pm141,Pm142,Pm143,\
+ Pm144,Pm145,Pm146,Pm147,Pm148,Pm149,Pm150,Pm151,Pm152,Pm153,Pm154,\
+ Pm155")
+
+#define MISRAC_ENABLE \
+ _Pragma( \
+ "diag_default= \
+ Pm001,Pm002,Pm003,Pm004,Pm005,Pm006,Pm007,Pm008,Pm009,Pm010,Pm011,\
+ Pm012,Pm013,Pm014,Pm015,Pm016,Pm017,Pm018,Pm019,Pm020,Pm021,Pm022,\
+ Pm023,Pm024,Pm025,Pm026,Pm027,Pm028,Pm029,Pm030,Pm031,Pm032,Pm033,\
+ Pm034,Pm035,Pm036,Pm037,Pm038,Pm039,Pm040,Pm041,Pm042,Pm043,Pm044,\
+ Pm045,Pm046,Pm047,Pm048,Pm049,Pm050,Pm051,Pm052,Pm053,Pm054,Pm055,\
+ Pm056,Pm057,Pm058,Pm059,Pm060,Pm061,Pm062,Pm063,Pm064,Pm065,Pm066,\
+ Pm067,Pm068,Pm069,Pm070,Pm071,Pm072,Pm073,Pm074,Pm075,Pm076,Pm077,\
+ Pm078,Pm079,Pm080,Pm081,Pm082,Pm083,Pm084,Pm085,Pm086,Pm087,Pm088,\
+ Pm089,Pm090,Pm091,Pm092,Pm093,Pm094,Pm095,Pm096,Pm097,Pm098,Pm099,\
+ Pm100,Pm101,Pm102,Pm103,Pm104,Pm105,Pm106,Pm107,Pm108,Pm109,Pm110,\
+ Pm111,Pm112,Pm113,Pm114,Pm115,Pm116,Pm117,Pm118,Pm119,Pm120,Pm121,\
+ Pm122,Pm123,Pm124,Pm125,Pm126,Pm127,Pm128,Pm129,Pm130,Pm131,Pm132,\
+ Pm133,Pm134,Pm135,Pm136,Pm137,Pm138,Pm139,Pm140,Pm141,Pm142,Pm143,\
+ Pm144,Pm145,Pm146,Pm147,Pm148,Pm149,Pm150,Pm151,Pm152,Pm153,Pm154,\
+ Pm155")
+#else
+/* Empty MISRA C macros for other toolchains. */
+#define MISRAC_DISABLE
+#define MISRAC_ENABLE
+#endif
+
+MISRAC_DISABLE
+#include "FreeRTOS.h"
+#include "semphr.h"
+#include "event_groups.h"
+MISRAC_ENABLE
+
+/*******************************************************************************
+ * Definitions
+ ******************************************************************************/
+
+#define USB_OSA_SR_ALLOC() uint8_t usbOsaCurrentSr;
+#define USB_OSA_ENTER_CRITICAL() USB_OsaEnterCritical(&usbOsaCurrentSr)
+#define USB_OSA_EXIT_CRITICAL() USB_OsaExitCritical(usbOsaCurrentSr)
+
+/*******************************************************************************
+ * API
+ ******************************************************************************/
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+extern void USB_OsaEnterCritical(uint8_t *sr);
+extern void USB_OsaExitCritical(uint8_t sr);
+
+#if defined(__cplusplus)
+}
+#endif
+
+#endif /* __USB_OSA_FREERTOS_H__ */