summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDominik Sliwa <dominik.sliwa@toradex.com>2016-06-28 09:51:29 +0200
committerDominik Sliwa <dominik.sliwa@toradex.com>2017-01-25 16:49:22 +0100
commitf7cd9b461ca33845339f4a11f49bdc142696827a (patch)
tree058f5e4f20307f26bf4d7d811047d4c90a25522e
parentfc8127294072ecff476706f073314738512ec1c9 (diff)
Apalis_TK1_K20: SPI Communication, ADC, TSC, GPIOapalis-tk1-k20-freertos-v8
Support for Communication between TK1 SoC and K20 MCU This patch includes ADC, TSC and GPIO functionality. Signed-off-by: Dominik Sliwa <dominik.sliwa@toradex.com>
-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)(lo