parent
7a8206f026
commit
e527810411
@ -0,0 +1,312 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<?fileVersion 4.0.0?><cproject storage_type_id="org.eclipse.cdt.core.XmlProjectDescriptionStorage">
|
||||
<storageModule moduleId="org.eclipse.cdt.core.settings">
|
||||
<cconfiguration id="ilg.gnuarmeclipse.managedbuild.cross.config.elf.debug.110983800">
|
||||
<storageModule buildSystemId="org.eclipse.cdt.managedbuilder.core.configurationDataProvider" id="ilg.gnuarmeclipse.managedbuild.cross.config.elf.debug.110983800" moduleId="org.eclipse.cdt.core.settings" name="Debug">
|
||||
<externalSettings/>
|
||||
<extensions>
|
||||
<extension id="org.eclipse.cdt.core.ELF" point="org.eclipse.cdt.core.BinaryParser"/>
|
||||
<extension id="org.eclipse.cdt.core.GCCErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
|
||||
<extension id="org.eclipse.cdt.core.GASErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
|
||||
<extension id="org.eclipse.cdt.core.GLDErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
|
||||
<extension id="org.eclipse.cdt.core.GmakeErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
|
||||
<extension id="org.eclipse.cdt.core.CWDLocator" point="org.eclipse.cdt.core.ErrorParser"/>
|
||||
</extensions>
|
||||
</storageModule>
|
||||
<storageModule moduleId="cdtBuildSystem" version="4.0.0">
|
||||
<configuration artifactName="${ProjName}" buildArtefactType="org.eclipse.cdt.build.core.buildArtefactType.exe" buildProperties="org.eclipse.cdt.build.core.buildArtefactType=org.eclipse.cdt.build.core.buildArtefactType.exe,org.eclipse.cdt.build.core.buildType=org.eclipse.cdt.build.core.buildType.debug" cleanCommand="${cross_rm} -rf" description="" id="ilg.gnuarmeclipse.managedbuild.cross.config.elf.debug.110983800" name="Debug" parent="ilg.gnuarmeclipse.managedbuild.cross.config.elf.debug" postbuildStep="${cross_prefix}objcopy -O binary ${ProjName}.${BuildArtifactFileExt} ${ProjName}.bin">
|
||||
<folderInfo id="ilg.gnuarmeclipse.managedbuild.cross.config.elf.debug.110983800." name="/" resourcePath="">
|
||||
<toolChain id="ilg.gnuarmeclipse.managedbuild.cross.toolchain.elf.debug.1271795031" name="Cross ARM GCC" nonInternalBuilderId="ilg.gnuarmeclipse.managedbuild.cross.builder" superClass="ilg.gnuarmeclipse.managedbuild.cross.toolchain.elf.debug">
|
||||
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.optimization.level.2140590766" name="Optimization Level" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.optimization.level" useByScannerDiscovery="true" value="ilg.gnuarmeclipse.managedbuild.cross.option.optimization.level.debug" valueType="enumerated"/>
|
||||
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.optimization.messagelength.1655246483" name="Message length (-fmessage-length=0)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.optimization.messagelength" useByScannerDiscovery="true" value="true" valueType="boolean"/>
|
||||
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.optimization.signedchar.1912399695" name="'char' is signed (-fsigned-char)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.optimization.signedchar" useByScannerDiscovery="true" value="true" valueType="boolean"/>
|
||||
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.optimization.functionsections.2097677227" name="Function sections (-ffunction-sections)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.optimization.functionsections" useByScannerDiscovery="true" value="true" valueType="boolean"/>
|
||||
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.optimization.datasections.1364848851" name="Data sections (-fdata-sections)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.optimization.datasections" useByScannerDiscovery="true" value="true" valueType="boolean"/>
|
||||
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.debugging.level.728815383" name="Debug level" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.debugging.level" useByScannerDiscovery="true" value="ilg.gnuarmeclipse.managedbuild.cross.option.debugging.level.max" valueType="enumerated"/>
|
||||
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.debugging.format.973313256" name="Debug format" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.debugging.format" useByScannerDiscovery="true"/>
|
||||
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.toolchain.name.859574207" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.toolchain.name" useByScannerDiscovery="false" value="GNU Tools for ARM Embedded Processors" valueType="string"/>
|
||||
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.architecture.1378373916" name="Architecture" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.architecture" useByScannerDiscovery="false" value="ilg.gnuarmeclipse.managedbuild.cross.option.architecture.arm" valueType="enumerated"/>
|
||||
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.arm.target.family.1657788080" name="ARM family" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.arm.target.family" useByScannerDiscovery="false" value="ilg.gnuarmeclipse.managedbuild.cross.option.arm.target.mcpu.cortex-m4" valueType="enumerated"/>
|
||||
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.arm.target.instructionset.21974397" name="Instruction set" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.arm.target.instructionset" useByScannerDiscovery="false" value="ilg.gnuarmeclipse.managedbuild.cross.option.arm.target.instructionset.thumb" valueType="enumerated"/>
|
||||
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.command.prefix.195914210" name="Prefix" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.command.prefix" useByScannerDiscovery="false" value="arm-none-eabi-" valueType="string"/>
|
||||
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.command.c.1353241937" name="C compiler" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.command.c" useByScannerDiscovery="false" value="gcc" valueType="string"/>
|
||||
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.command.cpp.935285285" name="C++ compiler" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.command.cpp" useByScannerDiscovery="false" value="g++" valueType="string"/>
|
||||
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.command.ar.799920162" name="Archiver" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.command.ar" useByScannerDiscovery="false" value="ar" valueType="string"/>
|
||||
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.command.objcopy.495282384" name="Hex/Bin converter" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.command.objcopy" useByScannerDiscovery="false" value="objcopy" valueType="string"/>
|
||||
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.command.objdump.687084139" name="Listing generator" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.command.objdump" useByScannerDiscovery="false" value="objdump" valueType="string"/>
|
||||
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.command.size.760453142" name="Size command" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.command.size" useByScannerDiscovery="false" value="size" valueType="string"/>
|
||||
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.command.make.539315105" name="Build command" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.command.make" useByScannerDiscovery="false" value="make" valueType="string"/>
|
||||
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.command.rm.751122475" name="Remove command" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.command.rm" useByScannerDiscovery="false" value="rm" valueType="string"/>
|
||||
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.addtools.createflash.1606753881" name="Create flash image" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.addtools.createflash" useByScannerDiscovery="false" value="true" valueType="boolean"/>
|
||||
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.addtools.printsize.1592639420" name="Print size" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.addtools.printsize" useByScannerDiscovery="false" value="true" valueType="boolean"/>
|
||||
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.warnings.uninitialized.1570781551" name="Warn on uninitialized variables (-Wuninitialised)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.warnings.uninitialized" useByScannerDiscovery="true" value="true" valueType="boolean"/>
|
||||
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.warnings.unused.405290154" name="Warn on various unused elements (-Wunused)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.warnings.unused" useByScannerDiscovery="true" value="true" valueType="boolean"/>
|
||||
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.warnings.allwarn.2061379866" name="Enable all common warnings (-Wall)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.warnings.allwarn" useByScannerDiscovery="true" value="true" valueType="boolean"/>
|
||||
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.warnings.extrawarn.235340212" name="Enable extra warnings (-Wextra)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.warnings.extrawarn" useByScannerDiscovery="true" value="true" valueType="boolean"/>
|
||||
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.warnings.conversion.19359341" name="Warn on implicit conversions (-Wconversion)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.warnings.conversion" useByScannerDiscovery="true" value="false" valueType="boolean"/>
|
||||
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.warnings.logicalop.1966851850" name="Warn if suspicious logical ops (-Wlogical-op)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.warnings.logicalop" useByScannerDiscovery="true" value="true" valueType="boolean"/>
|
||||
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.warnings.pointerarith.1529172556" name="Warn if pointer arithmetic (-Wpointer-arith)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.warnings.pointerarith" useByScannerDiscovery="true" value="true" valueType="boolean"/>
|
||||
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.arm.target.fpu.abi.481456479" name="Float ABI" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.arm.target.fpu.abi" useByScannerDiscovery="true" value="ilg.gnuarmeclipse.managedbuild.cross.option.arm.target.fpu.abi.hard" valueType="enumerated"/>
|
||||
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.arm.target.fpu.unit.2034326975" name="FPU Type" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.arm.target.fpu.unit" useByScannerDiscovery="true" value="ilg.gnuarmeclipse.managedbuild.cross.option.arm.target.fpu.unit.fpv4spd16" valueType="enumerated"/>
|
||||
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.toolchain.id.1727424018" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.toolchain.id" useByScannerDiscovery="false" value="1287942917" valueType="string"/>
|
||||
<targetPlatform archList="all" binaryParser="org.eclipse.cdt.core.ELF" id="ilg.gnuarmeclipse.managedbuild.cross.targetPlatform.1042769951" isAbstract="false" osList="all" superClass="ilg.gnuarmeclipse.managedbuild.cross.targetPlatform"/>
|
||||
<builder buildPath="${workspace_loc:/Downstream}/Debug" id="ilg.gnuarmeclipse.managedbuild.cross.builder.2070257479" keepEnvironmentInBuildfile="false" name="Gnu Make Builder" parallelBuildOn="true" parallelizationNumber="optimal" superClass="ilg.gnuarmeclipse.managedbuild.cross.builder"/>
|
||||
<tool id="ilg.gnuarmeclipse.managedbuild.cross.tool.assembler.789837881" name="Cross ARM GNU Assembler" superClass="ilg.gnuarmeclipse.managedbuild.cross.tool.assembler">
|
||||
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.assembler.usepreprocessor.1524992420" name="Use preprocessor" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.assembler.usepreprocessor" useByScannerDiscovery="false" value="true" valueType="boolean"/>
|
||||
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.assembler.defs.559716966" name="Defined symbols (-D)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.assembler.defs" useByScannerDiscovery="true" valueType="definedSymbols">
|
||||
<listOptionValue builtIn="false" value="STM32F401xC"/>
|
||||
</option>
|
||||
<inputType id="ilg.gnuarmeclipse.managedbuild.cross.tool.assembler.input.1659311775" superClass="ilg.gnuarmeclipse.managedbuild.cross.tool.assembler.input"/>
|
||||
</tool>
|
||||
<tool id="ilg.gnuarmeclipse.managedbuild.cross.tool.c.compiler.1693581131" name="Cross ARM C Compiler" superClass="ilg.gnuarmeclipse.managedbuild.cross.tool.c.compiler">
|
||||
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.c.compiler.include.paths.822026556" name="Include paths (-I)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.c.compiler.include.paths" useByScannerDiscovery="false" valueType="includePath">
|
||||
<listOptionValue builtIn="false" value=""${workspace_loc:/Downstream/Drivers/STM32F4xx_HAL_Driver/Inc}""/>
|
||||
<listOptionValue builtIn="false" value=""${workspace_loc:/Downstream/Drivers/CMSIS/Device/ST/STM32F4xx/Include}""/>
|
||||
<listOptionValue builtIn="false" value=""${workspace_loc:/Downstream/Inc}""/>
|
||||
<listOptionValue builtIn="false" value=""${workspace_loc:/Downstream/Drivers/CMSIS/Include}""/>
|
||||
<listOptionValue builtIn="false" value=""${workspace_loc:/Downstream/Middlewares/ST/STM32_USB_Host_Library/Core/Inc}""/>
|
||||
<listOptionValue builtIn="false" value=""${workspace_loc:/Downstream/Middlewares/ST/STM32_USB_Host_Library/Class/MSC/Inc}""/>
|
||||
<listOptionValue builtIn="false" value=""${workspace_loc:/Downstream/Middlewares/ST/STM32_USB_Host_Library/Class/HID/Inc}""/>
|
||||
</option>
|
||||
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.c.compiler.defs.914524327" name="Defined symbols (-D)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.c.compiler.defs" useByScannerDiscovery="false" valueType="definedSymbols">
|
||||
<listOptionValue builtIn="false" value="STM32F401xC"/>
|
||||
</option>
|
||||
<inputType id="ilg.gnuarmeclipse.managedbuild.cross.tool.c.compiler.input.1745725913" superClass="ilg.gnuarmeclipse.managedbuild.cross.tool.c.compiler.input"/>
|
||||
</tool>
|
||||
<tool id="ilg.gnuarmeclipse.managedbuild.cross.tool.cpp.compiler.1707231517" name="Cross ARM C++ Compiler" superClass="ilg.gnuarmeclipse.managedbuild.cross.tool.cpp.compiler"/>
|
||||
<tool id="ilg.gnuarmeclipse.managedbuild.cross.tool.c.linker.254208823" name="Cross ARM C Linker" superClass="ilg.gnuarmeclipse.managedbuild.cross.tool.c.linker">
|
||||
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.c.linker.gcsections.19615684" name="Remove unused sections (-Xlinker --gc-sections)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.c.linker.gcsections" useByScannerDiscovery="false" value="true" valueType="boolean"/>
|
||||
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.c.linker.usenewlibnano.1093194778" name="Use newlib-nano (--specs=nano.specs)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.c.linker.usenewlibnano" useByScannerDiscovery="false" value="true" valueType="boolean"/>
|
||||
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.c.linker.nostart.1226941524" name="Do not use standard start files (-nostartfiles)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.c.linker.nostart" useByScannerDiscovery="false" value="true" valueType="boolean"/>
|
||||
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.c.linker.scriptfile.2018055305" name="Script files (-T)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.c.linker.scriptfile" useByScannerDiscovery="false" valueType="stringList">
|
||||
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/gcc_arm_stm32f401.ld}""/>
|
||||
</option>
|
||||
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.c.linker.usenewlibnosys.473764979" name="Do not use syscalls (--specs=nosys.specs)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.c.linker.usenewlibnosys" useByScannerDiscovery="false" value="true" valueType="boolean"/>
|
||||
<inputType id="ilg.gnuarmeclipse.managedbuild.cross.tool.c.linker.input.1124786404" superClass="ilg.gnuarmeclipse.managedbuild.cross.tool.c.linker.input">
|
||||
<additionalInput kind="additionalinputdependency" paths="$(USER_OBJS)"/>
|
||||
<additionalInput kind="additionalinput" paths="$(LIBS)"/>
|
||||
</inputType>
|
||||
</tool>
|
||||
<tool id="ilg.gnuarmeclipse.managedbuild.cross.tool.cpp.linker.975001742" name="Cross ARM C++ Linker" superClass="ilg.gnuarmeclipse.managedbuild.cross.tool.cpp.linker">
|
||||
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.cpp.linker.gcsections.2071573630" 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.533761955" 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.scriptfile.2117286361" name="Script files (-T)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.cpp.linker.scriptfile" valueType="stringList">
|
||||
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/gcc_arm_stm32f401.ld}""/>
|
||||
</option>
|
||||
</tool>
|
||||
<tool id="ilg.gnuarmeclipse.managedbuild.cross.tool.archiver.2092748559" name="Cross ARM GNU Archiver" superClass="ilg.gnuarmeclipse.managedbuild.cross.tool.archiver"/>
|
||||
<tool id="ilg.gnuarmeclipse.managedbuild.cross.tool.createflash.2147256520" name="Cross ARM GNU Create Flash Image" superClass="ilg.gnuarmeclipse.managedbuild.cross.tool.createflash"/>
|
||||
<tool id="ilg.gnuarmeclipse.managedbuild.cross.tool.createlisting.952474437" name="Cross ARM GNU Create Listing" superClass="ilg.gnuarmeclipse.managedbuild.cross.tool.createlisting">
|
||||
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.createlisting.source.1884468527" 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.1480743382" 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.1214841688" 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.186728271" 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.409648956" 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.2134899522" name="Cross ARM GNU Print Size" superClass="ilg.gnuarmeclipse.managedbuild.cross.tool.printsize">
|
||||
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.printsize.format.596374317" name="Size format" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.printsize.format" useByScannerDiscovery="false"/>
|
||||
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.printsize.totals.878347212" name="Show totals" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.printsize.totals" useByScannerDiscovery="false" value="false" valueType="boolean"/>
|
||||
</tool>
|
||||
</toolChain>
|
||||
</folderInfo>
|
||||
<sourceEntries>
|
||||
<entry excluding="Middlewares/ST/STM32_USB_Host_Library/Class/HID/Src/usbh_hid_keybd.c|Middlewares/ST/STM32_USB_Host_Library/Class/HID/Src/usbh_hid_mouse.c|Middlewares/ST/STM32_USB_Host_Library/Class/HID/Src/usbh_hid_parser.c|Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_pwr.c|Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_pwr_ex.c|Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_dma_ex.c|Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_flash.c|Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_flash_ex.c|Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_flash_ramfunc.c|Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_rcc_ex.c|Middlewares/ST/STM32_USB_Host_Library/Core/Src/usbh_conf_template.c|Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_ll_sdmmc.c|Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_ll_fsmc.c|Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_ll_fmc.c|Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_wwdg.c|Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_usart.c|Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_uart.c|Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_tim.c|Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_tim_ex.c|Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_sram.c|Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_spdifrx.c|Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_smartcard.c|Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_sdram.c|Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_sd.c|Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_sai.c|Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_sai_ex.c|Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_rtc.c|Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_rtc_ex.c|Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_rng.c|Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_qspi.c|Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_pcd.c|Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_pcd_ex.c|Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_pccard.c|Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_nor.c|Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_nand.c|Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_msp_template.c|Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_ltdc.c|Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_iwdg.c|Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_irda.c|Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_i2s.c|Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_i2s_ex.c|Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_i2c.c|Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_i2c_ex.c|Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_hash.c|Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_hash_ex.c|Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_fmpi2c.c|Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_fmpi2c_ex.c|Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_eth.c|Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_dma2d.c|Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_dcmi.c|Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_dcmi_ex.c|Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_dac.c|Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_dac_ex.c|Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_cryp.c|Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_cryp_ex.c|Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_crc.c|Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_cec.c|Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_can.c|Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_adc.c|Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_adc_ex.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">
|
||||
<option id="cmsis.device.name" value="STM32F401RC"/>
|
||||
<option id="cmsis.subfamily.name" value="STM32F401"/>
|
||||
<option id="cmsis.family.name" value="STM32F4 Series"/>
|
||||
<option id="cmsis.device.vendor.name" value="STMicroelectronics"/>
|
||||
<option id="cmsis.device.vendor.id" value="13"/>
|
||||
<option id="cmsis.device.pack.vendor" value="Keil"/>
|
||||
<option id="cmsis.device.pack.name" value="STM32F4xx_DFP"/>
|
||||
<option id="cmsis.device.pack.version" value="2.4.0"/>
|
||||
<option id="cmsis.core.name" value="Cortex-M4"/>
|
||||
<option id="cmsis.compiler.define" value="STM32F401xC"/>
|
||||
<memory section="IRAM1" size="0x10000" start="0x20000000" startup="0"/>
|
||||
<memory section="IROM1" size="0x40000" start="0x08000000" startup="1"/>
|
||||
</storageModule>
|
||||
<storageModule moduleId="ilg.gnumcueclipse.managedbuild.packs">
|
||||
<option id="cmsis.device.name" value="STM32F401RB"/>
|
||||
<option id="cmsis.subfamily.name" value="STM32F401"/>
|
||||
<option id="cmsis.family.name" value="STM32F4 Series"/>
|
||||
<option id="cmsis.device.vendor.name" value="STMicroelectronics"/>
|
||||
<option id="cmsis.device.vendor.id" value="13"/>
|
||||
<option id="cmsis.device.pack.vendor" value="Keil"/>
|
||||
<option id="cmsis.device.pack.name" value="STM32F4xx_DFP"/>
|
||||
<option id="cmsis.device.pack.version" value="2.11.0"/>
|
||||
<option id="cmsis.core.name" value="Cortex-M4"/>
|
||||
<option id="cmsis.compiler.define" value="STM32F401xC"/>
|
||||
<memory section="IRAM1" size="0x10000" start="0x20000000" startup="0"/>
|
||||
<memory section="IROM1" size="0x20000" start="0x08000000" startup="1"/>
|
||||
</storageModule>
|
||||
</cconfiguration>
|
||||
<cconfiguration id="ilg.gnuarmeclipse.managedbuild.cross.config.elf.release.1300395207">
|
||||
<storageModule buildSystemId="org.eclipse.cdt.managedbuilder.core.configurationDataProvider" id="ilg.gnuarmeclipse.managedbuild.cross.config.elf.release.1300395207" moduleId="org.eclipse.cdt.core.settings" name="Release">
|
||||
<externalSettings/>
|
||||
<extensions>
|
||||
<extension id="org.eclipse.cdt.core.ELF" point="org.eclipse.cdt.core.BinaryParser"/>
|
||||
<extension id="org.eclipse.cdt.core.GCCErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
|
||||
<extension id="org.eclipse.cdt.core.GASErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
|
||||
<extension id="org.eclipse.cdt.core.GLDErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
|
||||
<extension id="org.eclipse.cdt.core.GmakeErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
|
||||
<extension id="org.eclipse.cdt.core.CWDLocator" point="org.eclipse.cdt.core.ErrorParser"/>
|
||||
</extensions>
|
||||
</storageModule>
|
||||
<storageModule moduleId="cdtBuildSystem" version="4.0.0">
|
||||
<configuration artifactName="${ProjName}" buildArtefactType="org.eclipse.cdt.build.core.buildArtefactType.exe" buildProperties="org.eclipse.cdt.build.core.buildArtefactType=org.eclipse.cdt.build.core.buildArtefactType.exe,org.eclipse.cdt.build.core.buildType=org.eclipse.cdt.build.core.buildType.release" cleanCommand="${cross_rm} -rf" description="" id="ilg.gnuarmeclipse.managedbuild.cross.config.elf.release.1300395207" name="Release" parent="ilg.gnuarmeclipse.managedbuild.cross.config.elf.release" postbuildStep="${cross_prefix}objcopy -O binary ${ProjName}.${BuildArtifactFileExt} ${ProjName}.bin">
|
||||
<folderInfo id="ilg.gnuarmeclipse.managedbuild.cross.config.elf.release.1300395207." name="/" resourcePath="">
|
||||
<toolChain id="ilg.gnuarmeclipse.managedbuild.cross.toolchain.elf.release.14803562" name="Cross ARM GCC" nonInternalBuilderId="ilg.gnuarmeclipse.managedbuild.cross.builder" superClass="ilg.gnuarmeclipse.managedbuild.cross.toolchain.elf.release">
|
||||
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.optimization.level.900298893" name="Optimization Level" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.optimization.level" useByScannerDiscovery="true" value="ilg.gnuarmeclipse.managedbuild.cross.option.optimization.level.most" valueType="enumerated"/>
|
||||
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.optimization.messagelength.1083811839" name="Message length (-fmessage-length=0)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.optimization.messagelength" useByScannerDiscovery="true" value="true" valueType="boolean"/>
|
||||
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.optimization.signedchar.1983172660" name="'char' is signed (-fsigned-char)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.optimization.signedchar" useByScannerDiscovery="true" value="true" valueType="boolean"/>
|
||||
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.optimization.functionsections.413875025" name="Function sections (-ffunction-sections)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.optimization.functionsections" useByScannerDiscovery="true" value="true" valueType="boolean"/>
|
||||
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.optimization.datasections.797056914" name="Data sections (-fdata-sections)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.optimization.datasections" useByScannerDiscovery="true" value="true" valueType="boolean"/>
|
||||
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.debugging.level.1607820960" name="Debug level" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.debugging.level" useByScannerDiscovery="true"/>
|
||||
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.debugging.format.753446064" name="Debug format" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.debugging.format" useByScannerDiscovery="true"/>
|
||||
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.toolchain.name.871783047" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.toolchain.name" useByScannerDiscovery="false" value="GNU Tools for ARM Embedded Processors" valueType="string"/>
|
||||
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.architecture.980964112" name="Architecture" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.architecture" useByScannerDiscovery="false" value="ilg.gnuarmeclipse.managedbuild.cross.option.architecture.arm" valueType="enumerated"/>
|
||||
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.arm.target.family.1722001019" name="ARM family" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.arm.target.family" useByScannerDiscovery="false" value="ilg.gnuarmeclipse.managedbuild.cross.option.arm.target.mcpu.cortex-m4" valueType="enumerated"/>
|
||||
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.arm.target.instructionset.311057983" name="Instruction set" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.arm.target.instructionset" useByScannerDiscovery="false" value="ilg.gnuarmeclipse.managedbuild.cross.option.arm.target.instructionset.thumb" valueType="enumerated"/>
|
||||
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.command.prefix.985310446" name="Prefix" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.command.prefix" useByScannerDiscovery="false" value="arm-none-eabi-" valueType="string"/>
|
||||
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.command.c.2064369703" name="C compiler" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.command.c" useByScannerDiscovery="false" value="gcc" valueType="string"/>
|
||||
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.command.cpp.2113985058" name="C++ compiler" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.command.cpp" useByScannerDiscovery="false" value="g++" valueType="string"/>
|
||||
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.command.ar.492854105" name="Archiver" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.command.ar" useByScannerDiscovery="false" value="ar" valueType="string"/>
|
||||
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.command.objcopy.1405530795" name="Hex/Bin converter" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.command.objcopy" useByScannerDiscovery="false" value="objcopy" valueType="string"/>
|
||||
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.command.objdump.674464443" name="Listing generator" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.command.objdump" useByScannerDiscovery="false" value="objdump" valueType="string"/>
|
||||
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.command.size.733095594" name="Size command" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.command.size" useByScannerDiscovery="false" value="size" valueType="string"/>
|
||||
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.command.make.1656691734" name="Build command" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.command.make" useByScannerDiscovery="false" value="make" valueType="string"/>
|
||||
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.command.rm.969460679" name="Remove command" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.command.rm" useByScannerDiscovery="false" value="rm" valueType="string"/>
|
||||
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.addtools.createflash.345738649" name="Create flash image" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.addtools.createflash" useByScannerDiscovery="false" value="true" valueType="boolean"/>
|
||||
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.addtools.printsize.2110677739" name="Print size" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.addtools.printsize" useByScannerDiscovery="false" value="true" valueType="boolean"/>
|
||||
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.warnings.unused.507402152" name="Warn on various unused elements (-Wunused)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.warnings.unused" useByScannerDiscovery="true" value="true" valueType="boolean"/>
|
||||
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.warnings.uninitialized.711919668" name="Warn on uninitialized variables (-Wuninitialised)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.warnings.uninitialized" useByScannerDiscovery="true" value="true" valueType="boolean"/>
|
||||
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.warnings.allwarn.144133984" name="Enable all common warnings (-Wall)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.warnings.allwarn" useByScannerDiscovery="true" value="true" valueType="boolean"/>
|
||||
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.warnings.extrawarn.1473585294" name="Enable extra warnings (-Wextra)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.warnings.extrawarn" useByScannerDiscovery="true" value="true" valueType="boolean"/>
|
||||
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.warnings.pointerarith.1192110404" name="Warn if pointer arithmetic (-Wpointer-arith)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.warnings.pointerarith" useByScannerDiscovery="true" value="true" valueType="boolean"/>
|
||||
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.warnings.logicalop.322411367" name="Warn if suspicious logical ops (-Wlogical-op)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.warnings.logicalop" useByScannerDiscovery="true" value="true" valueType="boolean"/>
|
||||
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.arm.target.fpu.abi.1624213557" name="Float ABI" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.arm.target.fpu.abi" useByScannerDiscovery="true" value="ilg.gnuarmeclipse.managedbuild.cross.option.arm.target.fpu.abi.hard" valueType="enumerated"/>
|
||||
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.arm.target.fpu.unit.1977148493" name="FPU Type" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.arm.target.fpu.unit" useByScannerDiscovery="true" value="ilg.gnuarmeclipse.managedbuild.cross.option.arm.target.fpu.unit.fpv4spd16" valueType="enumerated"/>
|
||||
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.toolchain.id.993230501" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.toolchain.id" useByScannerDiscovery="false" value="1287942917" valueType="string"/>
|
||||
<targetPlatform archList="all" binaryParser="org.eclipse.cdt.core.ELF" id="ilg.gnuarmeclipse.managedbuild.cross.targetPlatform.777514892" isAbstract="false" osList="all" superClass="ilg.gnuarmeclipse.managedbuild.cross.targetPlatform"/>
|
||||
<builder buildPath="${workspace_loc:/Downstream}/Release" id="ilg.gnuarmeclipse.managedbuild.cross.builder.1006388187" keepEnvironmentInBuildfile="false" name="Gnu Make Builder" parallelBuildOn="true" parallelizationNumber="optimal" superClass="ilg.gnuarmeclipse.managedbuild.cross.builder"/>
|
||||
<tool id="ilg.gnuarmeclipse.managedbuild.cross.tool.assembler.314526004" name="Cross ARM GNU Assembler" superClass="ilg.gnuarmeclipse.managedbuild.cross.tool.assembler">
|
||||
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.assembler.usepreprocessor.2143421487" name="Use preprocessor" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.assembler.usepreprocessor" useByScannerDiscovery="false" value="true" valueType="boolean"/>
|
||||
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.assembler.defs.1659712048" name="Defined symbols (-D)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.assembler.defs" useByScannerDiscovery="true" valueType="definedSymbols">
|
||||
<listOptionValue builtIn="false" value="STM32F401xC"/>
|
||||
</option>
|
||||
<inputType id="ilg.gnuarmeclipse.managedbuild.cross.tool.assembler.input.2143048963" superClass="ilg.gnuarmeclipse.managedbuild.cross.tool.assembler.input"/>
|
||||
</tool>
|
||||
<tool id="ilg.gnuarmeclipse.managedbuild.cross.tool.c.compiler.464951680" name="Cross ARM C Compiler" superClass="ilg.gnuarmeclipse.managedbuild.cross.tool.c.compiler">
|
||||
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.c.compiler.include.paths.1491964591" name="Include paths (-I)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.c.compiler.include.paths" useByScannerDiscovery="false" valueType="includePath">
|
||||
<listOptionValue builtIn="false" value=""${workspace_loc:/Downstream/Drivers/STM32F4xx_HAL_Driver/Inc}""/>
|
||||
<listOptionValue builtIn="false" value=""${workspace_loc:/Downstream/Drivers/CMSIS/Device/ST/STM32F4xx/Include}""/>
|
||||
<listOptionValue builtIn="false" value=""${workspace_loc:/Downstream/Inc}""/>
|
||||
<listOptionValue builtIn="false" value=""${workspace_loc:/Downstream/Drivers/CMSIS/Include}""/>
|
||||
<listOptionValue builtIn="false" value=""${workspace_loc:/Downstream/Middlewares/ST/STM32_USB_Host_Library/Core/Inc}""/>
|
||||
<listOptionValue builtIn="false" value=""${workspace_loc:/Downstream/Middlewares/ST/STM32_USB_Host_Library/Class/MSC/Inc}""/>
|
||||
<listOptionValue builtIn="false" value=""${workspace_loc:/Downstream/Middlewares/ST/STM32_USB_Host_Library/Class/HID/Inc}""/>
|
||||
</option>
|
||||
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.c.compiler.defs.569825136" name="Defined symbols (-D)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.c.compiler.defs" useByScannerDiscovery="false" valueType="definedSymbols">
|
||||
<listOptionValue builtIn="false" value="STM32F401xC"/>
|
||||
</option>
|
||||
<inputType id="ilg.gnuarmeclipse.managedbuild.cross.tool.c.compiler.input.37132336" superClass="ilg.gnuarmeclipse.managedbuild.cross.tool.c.compiler.input"/>
|
||||
</tool>
|
||||
<tool id="ilg.gnuarmeclipse.managedbuild.cross.tool.cpp.compiler.118177754" name="Cross ARM C++ Compiler" superClass="ilg.gnuarmeclipse.managedbuild.cross.tool.cpp.compiler"/>
|
||||
<tool id="ilg.gnuarmeclipse.managedbuild.cross.tool.c.linker.517364889" name="Cross ARM C Linker" superClass="ilg.gnuarmeclipse.managedbuild.cross.tool.c.linker">
|
||||
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.c.linker.gcsections.961434630" name="Remove unused sections (-Xlinker --gc-sections)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.c.linker.gcsections" useByScannerDiscovery="false" value="true" valueType="boolean"/>
|
||||
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.c.linker.nostart.655825353" name="Do not use standard start files (-nostartfiles)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.c.linker.nostart" useByScannerDiscovery="false" value="true" valueType="boolean"/>
|
||||
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.c.linker.scriptfile.773899963" name="Script files (-T)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.c.linker.scriptfile" useByScannerDiscovery="false" valueType="stringList">
|
||||
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/gcc_arm_stm32f401.ld}""/>
|
||||
</option>
|
||||
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.c.linker.usenewlibnano.1318058184" name="Use newlib-nano (--specs=nano.specs)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.c.linker.usenewlibnano" useByScannerDiscovery="false" value="true" valueType="boolean"/>
|
||||
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.c.linker.usenewlibnosys.1401331857" name="Do not use syscalls (--specs=nosys.specs)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.c.linker.usenewlibnosys" useByScannerDiscovery="false" value="true" valueType="boolean"/>
|
||||
<inputType id="ilg.gnuarmeclipse.managedbuild.cross.tool.c.linker.input.447256356" superClass="ilg.gnuarmeclipse.managedbuild.cross.tool.c.linker.input">
|
||||
<additionalInput kind="additionalinputdependency" paths="$(USER_OBJS)"/>
|
||||
<additionalInput kind="additionalinput" paths="$(LIBS)"/>
|
||||
</inputType>
|
||||
</tool>
|
||||
<tool id="ilg.gnuarmeclipse.managedbuild.cross.tool.cpp.linker.426760484" name="Cross ARM C++ Linker" superClass="ilg.gnuarmeclipse.managedbuild.cross.tool.cpp.linker">
|
||||
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.cpp.linker.gcsections.880923175" 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.464992520" 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.scriptfile.1888266216" name="Script files (-T)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.cpp.linker.scriptfile" valueType="stringList">
|
||||
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/gcc_arm_stm32f401.ld}""/>
|
||||
</option>
|
||||
</tool>
|
||||
<tool id="ilg.gnuarmeclipse.managedbuild.cross.tool.archiver.1866465855" name="Cross ARM GNU Archiver" superClass="ilg.gnuarmeclipse.managedbuild.cross.tool.archiver"/>
|
||||
<tool id="ilg.gnuarmeclipse.managedbuild.cross.tool.createflash.1030031530" name="Cross ARM GNU Create Flash Image" superClass="ilg.gnuarmeclipse.managedbuild.cross.tool.createflash"/>
|
||||
<tool id="ilg.gnuarmeclipse.managedbuild.cross.tool.createlisting.1578819914" name="Cross ARM GNU Create Listing" superClass="ilg.gnuarmeclipse.managedbuild.cross.tool.createlisting">
|
||||
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.createlisting.source.1760059993" 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.776514180" 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.1214988650" 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.2091080948" 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.320970754" 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.1434556593" name="Cross ARM GNU Print Size" superClass="ilg.gnuarmeclipse.managedbuild.cross.tool.printsize">
|
||||
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.printsize.format.1187784576" name="Size format" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.printsize.format" useByScannerDiscovery="false"/>
|
||||
</tool>
|
||||
</toolChain>
|
||||
</folderInfo>
|
||||
<sourceEntries>
|
||||
<entry excluding="Middlewares/ST/STM32_USB_Host_Library/Class/HID/Src/usbh_hid_keybd.c|Middlewares/ST/STM32_USB_Host_Library/Class/HID/Src/usbh_hid_mouse.c|Middlewares/ST/STM32_USB_Host_Library/Class/HID/Src/usbh_hid_parser.c|Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_pwr.c|Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_pwr_ex.c|Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_dma_ex.c|Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_flash.c|Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_flash_ex.c|Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_flash_ramfunc.c|Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_rcc_ex.c|Middlewares/ST/STM32_USB_Host_Library/Core/Src/usbh_conf_template.c|Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_ll_sdmmc.c|Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_ll_fsmc.c|Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_ll_fmc.c|Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_wwdg.c|Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_usart.c|Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_uart.c|Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_tim.c|Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_tim_ex.c|Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_sram.c|Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_spdifrx.c|Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_smartcard.c|Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_sdram.c|Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_sd.c|Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_sai.c|Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_sai_ex.c|Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_rtc.c|Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_rtc_ex.c|Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_rng.c|Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_qspi.c|Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_pcd.c|Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_pcd_ex.c|Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_pccard.c|Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_nor.c|Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_nand.c|Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_msp_template.c|Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_ltdc.c|Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_iwdg.c|Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_irda.c|Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_i2s.c|Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_i2s_ex.c|Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_i2c.c|Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_i2c_ex.c|Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_hash.c|Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_hash_ex.c|Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_fmpi2c.c|Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_fmpi2c_ex.c|Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_eth.c|Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_dma2d.c|Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_dcmi.c|Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_dcmi_ex.c|Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_dac.c|Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_dac_ex.c|Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_cryp.c|Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_cryp_ex.c|Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_crc.c|Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_cec.c|Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_can.c|Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_adc.c|Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_adc_ex.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">
|
||||
<option id="cmsis.device.name" value="STM32F401RC"/>
|
||||
<option id="cmsis.subfamily.name" value="STM32F401"/>
|
||||
<option id="cmsis.family.name" value="STM32F4 Series"/>
|
||||
<option id="cmsis.device.vendor.name" value="STMicroelectronics"/>
|
||||
<option id="cmsis.device.vendor.id" value="13"/>
|
||||
<option id="cmsis.device.pack.vendor" value="Keil"/>
|
||||
<option id="cmsis.device.pack.name" value="STM32F4xx_DFP"/>
|
||||
<option id="cmsis.device.pack.version" value="2.4.0"/>
|
||||
<option id="cmsis.core.name" value="Cortex-M4"/>
|
||||
<option id="cmsis.compiler.define" value="STM32F401xC"/>
|
||||
<memory section="IRAM1" size="0x10000" start="0x20000000" startup="0"/>
|
||||
<memory section="IROM1" size="0x40000" start="0x08000000" startup="1"/>
|
||||
</storageModule>
|
||||
<storageModule moduleId="ilg.gnumcueclipse.managedbuild.packs">
|
||||
<option id="cmsis.device.name" value="STM32F401RB"/>
|
||||
<option id="cmsis.subfamily.name" value="STM32F401"/>
|
||||
<option id="cmsis.family.name" value="STM32F4 Series"/>
|
||||
<option id="cmsis.device.vendor.name" value="STMicroelectronics"/>
|
||||
<option id="cmsis.device.vendor.id" value="13"/>
|
||||
<option id="cmsis.device.pack.vendor" value="Keil"/>
|
||||
<option id="cmsis.device.pack.name" value="STM32F4xx_DFP"/>
|
||||
<option id="cmsis.device.pack.version" value="2.11.0"/>
|
||||
<option id="cmsis.core.name" value="Cortex-M4"/>
|
||||
<option id="cmsis.compiler.define" value="STM32F401xC"/>
|
||||
<memory section="IRAM1" size="0x10000" start="0x20000000" startup="0"/>
|
||||
<memory section="IROM1" size="0x20000" start="0x08000000" startup="1"/>
|
||||
</storageModule>
|
||||
</cconfiguration>
|
||||
</storageModule>
|
||||
<storageModule moduleId="cdtBuildSystem" version="4.0.0">
|
||||
<project id="Downstream.ilg.gnuarmeclipse.managedbuild.cross.target.elf.1348817548" name="Executable" projectType="ilg.gnuarmeclipse.managedbuild.cross.target.elf"/>
|
||||
</storageModule>
|
||||
<storageModule moduleId="scannerConfiguration">
|
||||
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
|
||||
<scannerConfigBuildInfo instanceId="ilg.gnuarmeclipse.managedbuild.cross.config.elf.debug.110983800;ilg.gnuarmeclipse.managedbuild.cross.config.elf.debug.110983800.;ilg.gnuarmeclipse.managedbuild.cross.tool.c.compiler.1693581131;ilg.gnuarmeclipse.managedbuild.cross.tool.c.compiler.input.1745725913">
|
||||
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
|
||||
</scannerConfigBuildInfo>
|
||||
<scannerConfigBuildInfo instanceId="ilg.gnuarmeclipse.managedbuild.cross.config.elf.release.1300395207;ilg.gnuarmeclipse.managedbuild.cross.config.elf.release.1300395207.;ilg.gnuarmeclipse.managedbuild.cross.tool.c.compiler.464951680;ilg.gnuarmeclipse.managedbuild.cross.tool.c.compiler.input.37132336">
|
||||
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
|
||||
</scannerConfigBuildInfo>
|
||||
</storageModule>
|
||||
<storageModule moduleId="org.eclipse.cdt.core.LanguageSettingsProviders"/>
|
||||
<storageModule moduleId="refreshScope" versionNumber="2">
|
||||
<configuration configurationName="Debug">
|
||||
<resource resourceType="PROJECT" workspacePath="/Downstream"/>
|
||||
</configuration>
|
||||
<configuration configurationName="Release">
|
||||
<resource resourceType="PROJECT" workspacePath="/Downstream"/>
|
||||
</configuration>
|
||||
</storageModule>
|
||||
<storageModule moduleId="org.eclipse.cdt.internal.ui.text.commentOwnerProjectMappings"/>
|
||||
<storageModule moduleId="org.eclipse.cdt.make.core.buildtargets"/>
|
||||
</cproject>
|
@ -0,0 +1,2 @@
|
||||
/Debug/
|
||||
/Release/
|
@ -0,0 +1,26 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<projectDescription>
|
||||
<name>Downstream</name>
|
||||
<comment></comment>
|
||||
<projects>
|
||||
</projects>
|
||||
<buildSpec>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.cdt.managedbuilder.core.genmakebuilder</name>
|
||||
<triggers>clean,full,incremental,</triggers>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder</name>
|
||||
<triggers>full,incremental,</triggers>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
</buildSpec>
|
||||
<natures>
|
||||
<nature>org.eclipse.cdt.core.cnature</nature>
|
||||
<nature>org.eclipse.cdt.managedbuilder.core.managedBuildNature</nature>
|
||||
<nature>org.eclipse.cdt.managedbuilder.core.ScannerConfigNature</nature>
|
||||
</natures>
|
||||
</projectDescription>
|
@ -0,0 +1,25 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<project>
|
||||
<configuration id="ilg.gnuarmeclipse.managedbuild.cross.config.elf.debug.110983800" name="Debug">
|
||||
<extension point="org.eclipse.cdt.core.LanguageSettingsProvider">
|
||||
<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="1119754748549797289" 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 "${INPUTS}"" prefer-non-shared="true">
|
||||
<language-scope id="org.eclipse.cdt.core.gcc"/>
|
||||
<language-scope id="org.eclipse.cdt.core.g++"/>
|
||||
</provider>
|
||||
</extension>
|
||||
</configuration>
|
||||
<configuration id="ilg.gnuarmeclipse.managedbuild.cross.config.elf.release.1300395207" name="Release">
|
||||
<extension point="org.eclipse.cdt.core.LanguageSettingsProvider">
|
||||
<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="1102788320777581571" 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 "${INPUTS}"" prefer-non-shared="true">
|
||||
<language-scope id="org.eclipse.cdt.core.gcc"/>
|
||||
<language-scope id="org.eclipse.cdt.core.g++"/>
|
||||
</provider>
|
||||
</extension>
|
||||
</configuration>
|
||||
</project>
|
@ -0,0 +1,71 @@
|
||||
eclipse.preferences.version=1
|
||||
org.eclipse.cdt.codan.checkers.errnoreturn=Warning
|
||||
org.eclipse.cdt.codan.checkers.errnoreturn.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},implicit\=>false}
|
||||
org.eclipse.cdt.codan.checkers.errreturnvalue=Error
|
||||
org.eclipse.cdt.codan.checkers.errreturnvalue.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}}
|
||||
org.eclipse.cdt.codan.checkers.nocommentinside=-Error
|
||||
org.eclipse.cdt.codan.checkers.nocommentinside.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}}
|
||||
org.eclipse.cdt.codan.checkers.nolinecomment=-Error
|
||||
org.eclipse.cdt.codan.checkers.nolinecomment.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}}
|
||||
org.eclipse.cdt.codan.checkers.noreturn=Error
|
||||
org.eclipse.cdt.codan.checkers.noreturn.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},implicit\=>false}
|
||||
org.eclipse.cdt.codan.internal.checkers.AbstractClassCreation=Error
|
||||
org.eclipse.cdt.codan.internal.checkers.AbstractClassCreation.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}}
|
||||
org.eclipse.cdt.codan.internal.checkers.AmbiguousProblem=Error
|
||||
org.eclipse.cdt.codan.internal.checkers.AmbiguousProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}}
|
||||
org.eclipse.cdt.codan.internal.checkers.AssignmentInConditionProblem=Warning
|
||||
org.eclipse.cdt.codan.internal.checkers.AssignmentInConditionProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}}
|
||||
org.eclipse.cdt.codan.internal.checkers.AssignmentToItselfProblem=Error
|
||||
org.eclipse.cdt.codan.internal.checkers.AssignmentToItselfProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}}
|
||||
org.eclipse.cdt.codan.internal.checkers.CaseBreakProblem=Warning
|
||||
org.eclipse.cdt.codan.internal.checkers.CaseBreakProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},no_break_comment\=>"no break",last_case_param\=>false,empty_case_param\=>false}
|
||||
org.eclipse.cdt.codan.internal.checkers.CatchByReference=Warning
|
||||
org.eclipse.cdt.codan.internal.checkers.CatchByReference.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},unknown\=>false,exceptions\=>()}
|
||||
org.eclipse.cdt.codan.internal.checkers.CircularReferenceProblem=Error
|
||||
org.eclipse.cdt.codan.internal.checkers.CircularReferenceProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}}
|
||||
org.eclipse.cdt.codan.internal.checkers.ClassMembersInitialization=Warning
|
||||
org.eclipse.cdt.codan.internal.checkers.ClassMembersInitialization.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},skip\=>true}
|
||||
org.eclipse.cdt.codan.internal.checkers.FieldResolutionProblem=Error
|
||||
org.eclipse.cdt.codan.internal.checkers.FieldResolutionProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}}
|
||||
org.eclipse.cdt.codan.internal.checkers.FunctionResolutionProblem=Error
|
||||
org.eclipse.cdt.codan.internal.checkers.FunctionResolutionProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}}
|
||||
org.eclipse.cdt.codan.internal.checkers.InvalidArguments=Error
|
||||
org.eclipse.cdt.codan.internal.checkers.InvalidArguments.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}}
|
||||
org.eclipse.cdt.codan.internal.checkers.InvalidTemplateArgumentsProblem=Error
|
||||
org.eclipse.cdt.codan.internal.checkers.InvalidTemplateArgumentsProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}}
|
||||
org.eclipse.cdt.codan.internal.checkers.LabelStatementNotFoundProblem=Error
|
||||
org.eclipse.cdt.codan.internal.checkers.LabelStatementNotFoundProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}}
|
||||
org.eclipse.cdt.codan.internal.checkers.MemberDeclarationNotFoundProblem=Error
|
||||
org.eclipse.cdt.codan.internal.checkers.MemberDeclarationNotFoundProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}}
|
||||
org.eclipse.cdt.codan.internal.checkers.MethodResolutionProblem=Error
|
||||
org.eclipse.cdt.codan.internal.checkers.MethodResolutionProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}}
|
||||
org.eclipse.cdt.codan.internal.checkers.NamingConventionFunctionChecker=-Info
|
||||
org.eclipse.cdt.codan.internal.checkers.NamingConventionFunctionChecker.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},pattern\=>"^[a-z]",macro\=>true,exceptions\=>()}
|
||||
org.eclipse.cdt.codan.internal.checkers.NonVirtualDestructorProblem=Warning
|
||||
org.eclipse.cdt.codan.internal.checkers.NonVirtualDestructorProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}}
|
||||
org.eclipse.cdt.codan.internal.checkers.OverloadProblem=Error
|
||||
org.eclipse.cdt.codan.internal.checkers.OverloadProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}}
|
||||
org.eclipse.cdt.codan.internal.checkers.RedeclarationProblem=Error
|
||||
org.eclipse.cdt.codan.internal.checkers.RedeclarationProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}}
|
||||
org.eclipse.cdt.codan.internal.checkers.RedefinitionProblem=Error
|
||||
org.eclipse.cdt.codan.internal.checkers.RedefinitionProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}}
|
||||
org.eclipse.cdt.codan.internal.checkers.ReturnStyleProblem=-Warning
|
||||
org.eclipse.cdt.codan.internal.checkers.ReturnStyleProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}}
|
||||
org.eclipse.cdt.codan.internal.checkers.ScanfFormatStringSecurityProblem=-Warning
|
||||
org.eclipse.cdt.codan.internal.checkers.ScanfFormatStringSecurityProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}}
|
||||
org.eclipse.cdt.codan.internal.checkers.StatementHasNoEffectProblem=Warning
|
||||
org.eclipse.cdt.codan.internal.checkers.StatementHasNoEffectProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},macro\=>true,exceptions\=>()}
|
||||
org.eclipse.cdt.codan.internal.checkers.SuggestedParenthesisProblem=Warning
|
||||
org.eclipse.cdt.codan.internal.checkers.SuggestedParenthesisProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},paramNot\=>false}
|
||||
org.eclipse.cdt.codan.internal.checkers.SuspiciousSemicolonProblem=Warning
|
||||
org.eclipse.cdt.codan.internal.checkers.SuspiciousSemicolonProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},else\=>false,afterelse\=>false}
|
||||
org.eclipse.cdt.codan.internal.checkers.TypeResolutionProblem=Error
|
||||
org.eclipse.cdt.codan.internal.checkers.TypeResolutionProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}}
|
||||
org.eclipse.cdt.codan.internal.checkers.UnusedFunctionDeclarationProblem=Warning
|
||||
org.eclipse.cdt.codan.internal.checkers.UnusedFunctionDeclarationProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},macro\=>true}
|
||||
org.eclipse.cdt.codan.internal.checkers.UnusedStaticFunctionProblem=Warning
|
||||
org.eclipse.cdt.codan.internal.checkers.UnusedStaticFunctionProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},macro\=>true}
|
||||
org.eclipse.cdt.codan.internal.checkers.UnusedVariableDeclarationProblem=Warning
|
||||
org.eclipse.cdt.codan.internal.checkers.UnusedVariableDeclarationProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},macro\=>true,exceptions\=>("@(\#)","$Id")}
|
||||
org.eclipse.cdt.codan.internal.checkers.VariableResolutionProblem=Error
|
||||
org.eclipse.cdt.codan.internal.checkers.VariableResolutionProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}}
|
@ -0,0 +1,21 @@
|
||||
eclipse.preferences.version=1
|
||||
environment/buildEnvironmentInclude/ilg.gnuarmeclipse.managedbuild.cross.config.elf.debug.110983800/CPATH/delimiter=\:
|
||||
environment/buildEnvironmentInclude/ilg.gnuarmeclipse.managedbuild.cross.config.elf.debug.110983800/CPATH/operation=remove
|
||||
environment/buildEnvironmentInclude/ilg.gnuarmeclipse.managedbuild.cross.config.elf.debug.110983800/C_INCLUDE_PATH/delimiter=\:
|
||||
environment/buildEnvironmentInclude/ilg.gnuarmeclipse.managedbuild.cross.config.elf.debug.110983800/C_INCLUDE_PATH/operation=remove
|
||||
environment/buildEnvironmentInclude/ilg.gnuarmeclipse.managedbuild.cross.config.elf.debug.110983800/append=true
|
||||
environment/buildEnvironmentInclude/ilg.gnuarmeclipse.managedbuild.cross.config.elf.debug.110983800/appendContributed=true
|
||||
environment/buildEnvironmentInclude/ilg.gnuarmeclipse.managedbuild.cross.config.elf.release.1300395207/CPATH/delimiter=\:
|
||||
environment/buildEnvironmentInclude/ilg.gnuarmeclipse.managedbuild.cross.config.elf.release.1300395207/CPATH/operation=remove
|
||||
environment/buildEnvironmentInclude/ilg.gnuarmeclipse.managedbuild.cross.config.elf.release.1300395207/C_INCLUDE_PATH/delimiter=\:
|
||||
environment/buildEnvironmentInclude/ilg.gnuarmeclipse.managedbuild.cross.config.elf.release.1300395207/C_INCLUDE_PATH/operation=remove
|
||||
environment/buildEnvironmentInclude/ilg.gnuarmeclipse.managedbuild.cross.config.elf.release.1300395207/append=true
|
||||
environment/buildEnvironmentInclude/ilg.gnuarmeclipse.managedbuild.cross.config.elf.release.1300395207/appendContributed=true
|
||||
environment/buildEnvironmentLibrary/ilg.gnuarmeclipse.managedbuild.cross.config.elf.debug.110983800/LIBRARY_PATH/delimiter=\:
|
||||
environment/buildEnvironmentLibrary/ilg.gnuarmeclipse.managedbuild.cross.config.elf.debug.110983800/LIBRARY_PATH/operation=remove
|
||||
environment/buildEnvironmentLibrary/ilg.gnuarmeclipse.managedbuild.cross.config.elf.debug.110983800/append=true
|
||||
environment/buildEnvironmentLibrary/ilg.gnuarmeclipse.managedbuild.cross.config.elf.debug.110983800/appendContributed=true
|
||||
environment/buildEnvironmentLibrary/ilg.gnuarmeclipse.managedbuild.cross.config.elf.release.1300395207/LIBRARY_PATH/delimiter=\:
|
||||
environment/buildEnvironmentLibrary/ilg.gnuarmeclipse.managedbuild.cross.config.elf.release.1300395207/LIBRARY_PATH/operation=remove
|
||||
environment/buildEnvironmentLibrary/ilg.gnuarmeclipse.managedbuild.cross.config.elf.release.1300395207/append=true
|
||||
environment/buildEnvironmentLibrary/ilg.gnuarmeclipse.managedbuild.cross.config.elf.release.1300395207/appendContributed=true
|
@ -0,0 +1,64 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<launchConfiguration type="ilg.gnumcueclipse.debug.gdbjtag.openocd.launchConfigurationType">
|
||||
<booleanAttribute key="ilg.gnumcueclipse.debug.gdbjtag.openocd.doContinue" value="true"/>
|
||||
<booleanAttribute key="ilg.gnumcueclipse.debug.gdbjtag.openocd.doDebugInRam" value="false"/>
|
||||
<booleanAttribute key="ilg.gnumcueclipse.debug.gdbjtag.openocd.doFirstReset" value="true"/>
|
||||
<booleanAttribute key="ilg.gnumcueclipse.debug.gdbjtag.openocd.doGdbServerAllocateConsole" value="true"/>
|
||||
<booleanAttribute key="ilg.gnumcueclipse.debug.gdbjtag.openocd.doGdbServerAllocateTelnetConsole" value="false"/>
|
||||
<booleanAttribute key="ilg.gnumcueclipse.debug.gdbjtag.openocd.doSecondReset" value="true"/>
|
||||
<booleanAttribute key="ilg.gnumcueclipse.debug.gdbjtag.openocd.doStartGdbCLient" value="true"/>
|
||||
<booleanAttribute key="ilg.gnumcueclipse.debug.gdbjtag.openocd.doStartGdbServer" value="true"/>
|
||||
<booleanAttribute key="ilg.gnumcueclipse.debug.gdbjtag.openocd.enableSemihosting" value="true"/>
|
||||
<stringAttribute key="ilg.gnumcueclipse.debug.gdbjtag.openocd.firstResetType" value="init"/>
|
||||
<stringAttribute key="ilg.gnumcueclipse.debug.gdbjtag.openocd.gdbClientOtherCommands" value="set mem inaccessible-by-default off"/>
|
||||
<stringAttribute key="ilg.gnumcueclipse.debug.gdbjtag.openocd.gdbClientOtherOptions" value=""/>
|
||||
<stringAttribute key="ilg.gnumcueclipse.debug.gdbjtag.openocd.gdbServerConnectionAddress" value=""/>
|
||||
<stringAttribute key="ilg.gnumcueclipse.debug.gdbjtag.openocd.gdbServerExecutable" value="${openocd_path}/${openocd_executable}"/>
|
||||
<intAttribute key="ilg.gnumcueclipse.debug.gdbjtag.openocd.gdbServerGdbPortNumber" value="3333"/>
|
||||
<stringAttribute key="ilg.gnumcueclipse.debug.gdbjtag.openocd.gdbServerLog" value=""/>
|
||||
<stringAttribute key="ilg.gnumcueclipse.debug.gdbjtag.openocd.gdbServerOther" value="-f interface/stlink.cfg -f ../OpenOCD_scripts/board/OpenOCD_USG_v1.0.cfg"/>
|
||||
<stringAttribute key="ilg.gnumcueclipse.debug.gdbjtag.openocd.gdbServerTclPortNumber" value="6666"/>
|
||||
<intAttribute key="ilg.gnumcueclipse.debug.gdbjtag.openocd.gdbServerTelnetPortNumber" value="4444"/>
|
||||
<stringAttribute key="ilg.gnumcueclipse.debug.gdbjtag.openocd.otherInitCommands" value=""/>
|
||||
<stringAttribute key="ilg.gnumcueclipse.debug.gdbjtag.openocd.otherRunCommands" value=""/>
|
||||
<stringAttribute key="ilg.gnumcueclipse.debug.gdbjtag.openocd.secondResetType" value="halt"/>
|
||||
<stringAttribute key="ilg.gnumcueclipse.debug.gdbjtag.svdPath" value=""/>
|
||||
<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 MCU OpenOCD"/>
|
||||
<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="3333"/>
|
||||
<booleanAttribute key="org.eclipse.cdt.debug.gdbjtag.core.setPcRegister" value="false"/>
|
||||
<booleanAttribute key="org.eclipse.cdt.debug.gdbjtag.core.setResume" 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="/home/antonlysak/opt/gcc-arm-none-eabi-10-2020-q4-major/bin/arm-none-eabi-gdb"/>
|
||||
<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.COREFILE_PATH" value=""/>
|
||||
<stringAttribute key="org.eclipse.cdt.launch.PROGRAM_NAME" value="Debug/Downstream.elf"/>
|
||||
<stringAttribute key="org.eclipse.cdt.launch.PROJECT_ATTR" value="Downstream"/>
|
||||
<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="ilg.gnuarmeclipse.managedbuild.cross.config.elf.debug.110983800"/>
|
||||
<listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_PATHS">
|
||||
<listEntry value="/Downstream"/>
|
||||
</listAttribute>
|
||||
<listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_TYPES">
|
||||
<listEntry value="4"/>
|
||||
</listAttribute>
|
||||
<listAttribute key="org.eclipse.debug.ui.favoriteGroups">
|
||||
<listEntry value="org.eclipse.debug.ui.launchGroup.debug"/>
|
||||
</listAttribute>
|
||||
<stringAttribute key="org.eclipse.dsf.launch.MEMORY_BLOCKS" value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <memoryBlockExpressionList context="Context string"/> "/>
|
||||
<stringAttribute key="process_factory_id" value="org.eclipse.cdt.dsf.gdb.GdbProcessFactory"/>
|
||||
</launchConfiguration>
|
@ -0,0 +1,64 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<launchConfiguration type="ilg.gnumcueclipse.debug.gdbjtag.openocd.launchConfigurationType">
|
||||
<booleanAttribute key="ilg.gnumcueclipse.debug.gdbjtag.openocd.doContinue" value="true"/>
|
||||
<booleanAttribute key="ilg.gnumcueclipse.debug.gdbjtag.openocd.doDebugInRam" value="false"/>
|
||||
<booleanAttribute key="ilg.gnumcueclipse.debug.gdbjtag.openocd.doFirstReset" value="true"/>
|
||||
<booleanAttribute key="ilg.gnumcueclipse.debug.gdbjtag.openocd.doGdbServerAllocateConsole" value="true"/>
|
||||
<booleanAttribute key="ilg.gnumcueclipse.debug.gdbjtag.openocd.doGdbServerAllocateTelnetConsole" value="false"/>
|
||||
<booleanAttribute key="ilg.gnumcueclipse.debug.gdbjtag.openocd.doSecondReset" value="true"/>
|
||||
<booleanAttribute key="ilg.gnumcueclipse.debug.gdbjtag.openocd.doStartGdbCLient" value="true"/>
|
||||
<booleanAttribute key="ilg.gnumcueclipse.debug.gdbjtag.openocd.doStartGdbServer" value="true"/>
|
||||
<booleanAttribute key="ilg.gnumcueclipse.debug.gdbjtag.openocd.enableSemihosting" value="true"/>
|
||||
<stringAttribute key="ilg.gnumcueclipse.debug.gdbjtag.openocd.firstResetType" value="init"/>
|
||||
<stringAttribute key="ilg.gnumcueclipse.debug.gdbjtag.openocd.gdbClientOtherCommands" value="set mem inaccessible-by-default off"/>
|
||||
<stringAttribute key="ilg.gnumcueclipse.debug.gdbjtag.openocd.gdbClientOtherOptions" value=""/>
|
||||
<stringAttribute key="ilg.gnumcueclipse.debug.gdbjtag.openocd.gdbServerConnectionAddress" value=""/>
|
||||
<stringAttribute key="ilg.gnumcueclipse.debug.gdbjtag.openocd.gdbServerExecutable" value="${openocd_path}/${openocd_executable}"/>
|
||||
<intAttribute key="ilg.gnumcueclipse.debug.gdbjtag.openocd.gdbServerGdbPortNumber" value="3333"/>
|
||||
<stringAttribute key="ilg.gnumcueclipse.debug.gdbjtag.openocd.gdbServerLog" value=""/>
|
||||
<stringAttribute key="ilg.gnumcueclipse.debug.gdbjtag.openocd.gdbServerOther" value="-f interface/ftdi/olimex-arm-usb-tiny-h.cfg -f ../OpenOCD_scripts/board/OpenOCD_USG_v1.0.cfg"/>
|
||||
<stringAttribute key="ilg.gnumcueclipse.debug.gdbjtag.openocd.gdbServerTclPortNumber" value="6666"/>
|
||||
<intAttribute key="ilg.gnumcueclipse.debug.gdbjtag.openocd.gdbServerTelnetPortNumber" value="4444"/>
|
||||
<stringAttribute key="ilg.gnumcueclipse.debug.gdbjtag.openocd.otherInitCommands" value=""/>
|
||||
<stringAttribute key="ilg.gnumcueclipse.debug.gdbjtag.openocd.otherRunCommands" value=""/>
|
||||
<stringAttribute key="ilg.gnumcueclipse.debug.gdbjtag.openocd.secondResetType" value="halt"/>
|
||||
<stringAttribute key="ilg.gnumcueclipse.debug.gdbjtag.svdPath" value=""/>
|
||||
<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 MCU OpenOCD"/>
|
||||
<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="3333"/>
|
||||
<booleanAttribute key="org.eclipse.cdt.debug.gdbjtag.core.setPcRegister" value="false"/>
|
||||
<booleanAttribute key="org.eclipse.cdt.debug.gdbjtag.core.setResume" 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.COREFILE_PATH" value=""/>
|
||||
<stringAttribute key="org.eclipse.cdt.launch.PROGRAM_NAME" value="Debug/Downstream.elf"/>
|
||||
<stringAttribute key="org.eclipse.cdt.launch.PROJECT_ATTR" value="Downstream"/>
|
||||
<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="ilg.gnuarmeclipse.managedbuild.cross.config.elf.debug.110983800"/>
|
||||
<listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_PATHS">
|
||||
<listEntry value="/Downstream"/>
|
||||
</listAttribute>
|
||||
<listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_TYPES">
|
||||
<listEntry value="4"/>
|
||||
</listAttribute>
|
||||
<listAttribute key="org.eclipse.debug.ui.favoriteGroups">
|
||||
<listEntry value="org.eclipse.debug.ui.launchGroup.debug"/>
|
||||
</listAttribute>
|
||||
<stringAttribute key="org.eclipse.dsf.launch.MEMORY_BLOCKS" value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <memoryBlockExpressionList context="Context string"/> "/>
|
||||
<stringAttribute key="process_factory_id" value="org.eclipse.cdt.dsf.gdb.GdbProcessFactory"/>
|
||||
</launchConfiguration>
|
@ -0,0 +1,64 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<launchConfiguration type="ilg.gnumcueclipse.debug.gdbjtag.openocd.launchConfigurationType">
|
||||
<booleanAttribute key="ilg.gnumcueclipse.debug.gdbjtag.openocd.doContinue" value="true"/>
|
||||
<booleanAttribute key="ilg.gnumcueclipse.debug.gdbjtag.openocd.doDebugInRam" value="false"/>
|
||||
<booleanAttribute key="ilg.gnumcueclipse.debug.gdbjtag.openocd.doFirstReset" value="true"/>
|
||||
<booleanAttribute key="ilg.gnumcueclipse.debug.gdbjtag.openocd.doGdbServerAllocateConsole" value="true"/>
|
||||
<booleanAttribute key="ilg.gnumcueclipse.debug.gdbjtag.openocd.doGdbServerAllocateTelnetConsole" value="false"/>
|
||||
<booleanAttribute key="ilg.gnumcueclipse.debug.gdbjtag.openocd.doSecondReset" value="true"/>
|
||||
<booleanAttribute key="ilg.gnumcueclipse.debug.gdbjtag.openocd.doStartGdbCLient" value="true"/>
|
||||
<booleanAttribute key="ilg.gnumcueclipse.debug.gdbjtag.openocd.doStartGdbServer" value="true"/>
|
||||
<booleanAttribute key="ilg.gnumcueclipse.debug.gdbjtag.openocd.enableSemihosting" value="true"/>
|
||||
<stringAttribute key="ilg.gnumcueclipse.debug.gdbjtag.openocd.firstResetType" value="init"/>
|
||||
<stringAttribute key="ilg.gnumcueclipse.debug.gdbjtag.openocd.gdbClientOtherCommands" value="set mem inaccessible-by-default off"/>
|
||||
<stringAttribute key="ilg.gnumcueclipse.debug.gdbjtag.openocd.gdbClientOtherOptions" value=""/>
|
||||
<stringAttribute key="ilg.gnumcueclipse.debug.gdbjtag.openocd.gdbServerConnectionAddress" value=""/>
|
||||
<stringAttribute key="ilg.gnumcueclipse.debug.gdbjtag.openocd.gdbServerExecutable" value="${openocd_path}/${openocd_executable}"/>
|
||||
<intAttribute key="ilg.gnumcueclipse.debug.gdbjtag.openocd.gdbServerGdbPortNumber" value="3333"/>
|
||||
<stringAttribute key="ilg.gnumcueclipse.debug.gdbjtag.openocd.gdbServerLog" value=""/>
|
||||
<stringAttribute key="ilg.gnumcueclipse.debug.gdbjtag.openocd.gdbServerOther" value="-f interface/ftdi/olimex-arm-usb-tiny-h.cfg -f ../OpenOCD_scripts/board/OpenOCD_USG_v1.0.cfg"/>
|
||||
<stringAttribute key="ilg.gnumcueclipse.debug.gdbjtag.openocd.gdbServerTclPortNumber" value="6666"/>
|
||||
<intAttribute key="ilg.gnumcueclipse.debug.gdbjtag.openocd.gdbServerTelnetPortNumber" value="4444"/>
|
||||
<stringAttribute key="ilg.gnumcueclipse.debug.gdbjtag.openocd.otherInitCommands" value=""/>
|
||||
<stringAttribute key="ilg.gnumcueclipse.debug.gdbjtag.openocd.otherRunCommands" value=""/>
|
||||
<stringAttribute key="ilg.gnumcueclipse.debug.gdbjtag.openocd.secondResetType" value="halt"/>
|
||||
<stringAttribute key="ilg.gnumcueclipse.debug.gdbjtag.svdPath" value=""/>
|
||||
<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 MCU OpenOCD"/>
|
||||
<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="3333"/>
|
||||
<booleanAttribute key="org.eclipse.cdt.debug.gdbjtag.core.setPcRegister" value="false"/>
|
||||
<booleanAttribute key="org.eclipse.cdt.debug.gdbjtag.core.setResume" 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.COREFILE_PATH" value=""/>
|
||||
<stringAttribute key="org.eclipse.cdt.launch.PROGRAM_NAME" value="Release/Downstream.elf"/>
|
||||
<stringAttribute key="org.eclipse.cdt.launch.PROJECT_ATTR" value="Downstream"/>
|
||||
<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="ilg.gnuarmeclipse.managedbuild.cross.config.elf.release.1300395207"/>
|
||||
<listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_PATHS">
|
||||
<listEntry value="/Downstream"/>
|
||||
</listAttribute>
|
||||
<listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_TYPES">
|
||||
<listEntry value="4"/>
|
||||
</listAttribute>
|
||||
<listAttribute key="org.eclipse.debug.ui.favoriteGroups">
|
||||
<listEntry value="org.eclipse.debug.ui.launchGroup.debug"/>
|
||||
</listAttribute>
|
||||
<stringAttribute key="org.eclipse.dsf.launch.MEMORY_BLOCKS" value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <memoryBlockExpressionList context="Context string"/> "/>
|
||||
<stringAttribute key="process_factory_id" value="org.eclipse.cdt.dsf.gdb.GdbProcessFactory"/>
|
||||
</launchConfiguration>
|
@ -0,0 +1,61 @@
|
||||
/*
|
||||
* board_config.h
|
||||
*
|
||||
* Created on: 25/03/2015
|
||||
* Author: Robert Fisk
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
|
||||
#ifndef INC_BOARD_CONFIG_H_
|
||||
#define INC_BOARD_CONFIG_H_
|
||||
|
||||
|
||||
#define BSRR_SHIFT_HIGH 0
|
||||
#define BSRR_SHIFT_LOW 16
|
||||
|
||||
#define PA_JTMS GPIO_PIN_13
|
||||
#define PA_JTCK GPIO_PIN_14
|
||||
#define PA_JTDI GPIO_PIN_15
|
||||
#define PB_JTDO GPIO_PIN_3
|
||||
#define PB_NJTRST GPIO_PIN_4
|
||||
|
||||
#define FAULT_LED_PIN GPIO_PIN_13
|
||||
#define FAULT_LED_PORT GPIOC
|
||||
#define FAULT_LED_ON (FAULT_LED_PORT->BSRR = (FAULT_LED_PIN << BSRR_SHIFT_LOW)) //Fault LED is active-low
|
||||
#define FAULT_LED_OFF (FAULT_LED_PORT->BSRR = (FAULT_LED_PIN << BSRR_SHIFT_HIGH))
|
||||
|
||||
#define H405_FAULT_LED_PIN GPIO_PIN_12 //Fault LED on Olimex H405 board
|
||||
#define H405_FAULT_LED_ON (FAULT_LED_PORT->BSRR = (H405_FAULT_LED_PIN << BSRR_SHIFT_LOW))
|
||||
|
||||
#define INT_ACTIVE_PIN GPIO_PIN_2 //Temporary indicator of SPI (or whatever) activity
|
||||
#define INT_ACTIVE_PORT GPIOA
|
||||
#define INT_ACTIVE_ON INT_ACTIVE_PORT->BSRR = (INT_ACTIVE_PIN << BSRR_SHIFT_HIGH)
|
||||
#define INT_ACTIVE_OFF INT_ACTIVE_PORT->BSRR = (INT_ACTIVE_PIN << BSRR_SHIFT_LOW)
|
||||
|
||||
//#define SPI1_NSS_PIN GPIO_PIN_4
|
||||
//#define SPI1_NSS_PORT GPIOA
|
||||
|
||||
#define UPSTREAM_TX_REQUEST_PIN GPIO_PIN_3
|
||||
#define UPSTREAM_TX_REQUEST_PORT GPIOA
|
||||
#define UPSTREAM_TX_REQUEST_ASSERT (UPSTREAM_TX_REQUEST_PORT->BSRR = (UPSTREAM_TX_REQUEST_PIN << BSRR_SHIFT_LOW))
|
||||
#define UPSTREAM_TX_REQUEST_DEASSERT (UPSTREAM_TX_REQUEST_PORT->BSRR = (UPSTREAM_TX_REQUEST_PIN << BSRR_SHIFT_HIGH))
|
||||
|
||||
#define DBGMCU_IDCODE_DEV_ID_405_407_415_417 0x413
|
||||
#define DBGMCU_IDCODE_DEV_ID_401xB_xC 0x423
|
||||
|
||||
#define BOARD_REV_PIN_MASK 0xE000
|
||||
#define BOARD_ID_PIN_MASK 0x1000
|
||||
#define BOARD_REV_ID_PORT GPIOB
|
||||
|
||||
#define BOARD_REV_1_0_BETA 0
|
||||
#define BOARD_REV_1_0_BETA_3 1
|
||||
|
||||
#define BOARD_REV_1_0_BETA_FREQ 8
|
||||
#define BOARD_REV_1_0_BETA_3_FREQ 16
|
||||
|
||||
|
||||
#endif /* INC_BOARD_CONFIG_H_ */
|
@ -0,0 +1,29 @@
|
||||
/*
|
||||
* build_config.h
|
||||
*
|
||||
* Created on: Jun 20, 2017
|
||||
* Author: Robert Fisk
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
#ifndef INC_BUILD_CONFIG_H_
|
||||
#define INC_BUILD_CONFIG_H_
|
||||
|
||||
|
||||
#define CONFIG_MASS_STORAGE_ENABLED
|
||||
#define CONFIG_MASS_STORAGE_WRITES_PERMITTED
|
||||
|
||||
#define CONFIG_KEYBOARD_ENABLED
|
||||
#define CONFIG_MOUSE_ENABLED
|
||||
|
||||
#define CONFIG_READ_FLASH_TIME_MS 3000 //Enable read LED flashes for the specified length of time
|
||||
|
||||
#define CONFIG_USB_ID_ENABLED
|
||||
|
||||
#define CONFIG_FLASH_RDP_ENABLE
|
||||
|
||||
|
||||
#endif /* INC_BUILD_CONFIG_H_ */
|
@ -0,0 +1,70 @@
|
||||
/*
|
||||
* downstream_hid.h
|
||||
*
|
||||
* Created on: Apr 10, 2016
|
||||
* Author: Robert Fisk
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
#ifndef INC_DOWNSTREAM_HID_H_
|
||||
#define INC_DOWNSTREAM_HID_H_
|
||||
|
||||
|
||||
#include "downstream_interface_def.h"
|
||||
#include "downstream_spi.h"
|
||||
#include "usbh_def.h"
|
||||
|
||||
|
||||
#define HID_MAX_REPORT_LEN 8
|
||||
|
||||
//These defines are duplicated in upstream_hid.h. Keep them in sync!
|
||||
#define HID_MOUSE_INPUT_DATA_LEN 4
|
||||
#define HID_MOUSE_OUTPUT_DATA_LEN 0
|
||||
#define HID_MOUSE_MAX_BUTTONS 3
|
||||
|
||||
#define HID_KEYBOARD_INPUT_DATA_LEN 8
|
||||
#define HID_KEYBOARD_OUTPUT_DATA_LEN 1
|
||||
#define HID_KEYBOARD_MAX_KEY 101 //Also set in Upstream's HID report descriptor
|
||||
#define HID_KEYBOARD_MAX_LED 3
|
||||
|
||||
|
||||
//Stuff for parsing HID descriptors:
|
||||
#define HID_ITEM_LONG 0xFC
|
||||
#define HID_ITEM_MASK 0xFC
|
||||
#define HID_ITEM_LENGTH_MASK 0x03
|
||||
|
||||
#define HID_ITEM_USAGE_PAGE 0x04 //'global' usage page
|
||||
#define HID_ITEM_USAGE_PAGE_BUTTON 0x09
|
||||
#define HID_ITEM_USAGE_PAGE_DESKTOP 0x01
|
||||
|
||||
#define HID_ITEM_COLLECTION 0xA0
|
||||
#define HID_ITEM_COLLECTION_PHYS 0x00
|
||||
#define HID_ITEM_END_COLLECTION 0xC0
|
||||
|
||||
#define HID_ITEM_USAGE 0x08 //'local' usage
|
||||
#define HID_ITEM_USAGE_X 0x30
|
||||
#define HID_ITEM_USAGE_Y 0x31
|
||||
#define HID_ITEM_USAGE_WHEEL 0x38
|
||||
|
||||
#define HID_ITEM_REPORT_SIZE 0x74 //'global' report size
|
||||
#define HID_ITEM_REPORT_COUNT 0x94 //'global' report count
|
||||
#define HID_ITEM_REPORT_ID 0x84
|
||||
|
||||
#define HID_ITEM_INPUT 0x80 //'main' input
|
||||
#define HID_ITEM_INPUT_ABS 0x02
|
||||
#define HID_ITEM_INPUT_REL 0x06
|
||||
|
||||
|
||||
typedef void (*TransactionCompleteCallbackTypeDef)(USBH_StatusTypeDef result);
|
||||
|
||||
InterfaceCommandClassTypeDef Downstream_HID_ApproveConnectedDevice(void);
|
||||
void Downstream_HID_PacketProcessor(DownstreamPacketTypeDef* receivedPacket);
|
||||
void Downstream_HID_InterruptReportCallback(USBH_StatusTypeDef result);
|
||||
void Downstream_HID_SendReportCallback(USBH_StatusTypeDef result);
|
||||
|
||||
|
||||
|
||||
#endif /* INC_DOWNSTREAM_HID_H_ */
|
@ -0,0 +1,77 @@
|
||||
/*
|
||||
* downstream_interface_def.h
|
||||
*
|
||||
* Created on: 24/07/2015
|
||||
* Author: Robert Fisk
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
#ifndef INC_DOWNSTREAM_INTERFACE_DEF_H_
|
||||
#define INC_DOWNSTREAM_INTERFACE_DEF_H_
|
||||
|
||||
|
||||
//***************
|
||||
// Attention!
|
||||
// Keep this file synchronised with upstream_interface_def.h
|
||||
// in the Upstream project.
|
||||
//***************
|
||||
|
||||
|
||||
|
||||
#define COMMAND_CLASS_DATA_FLAG 0x80
|
||||
#define COMMAND_CLASS_MASK ((uint8_t)(~COMMAND_CLASS_DATA_FLAG))
|
||||
|
||||
|
||||
typedef enum
|
||||
{
|
||||
COMMAND_CLASS_INTERFACE,
|
||||
COMMAND_CLASS_MASS_STORAGE,
|
||||
COMMAND_CLASS_HID_MOUSE,
|
||||
COMMAND_CLASS_HID_KEYBOARD,
|
||||
//...
|
||||
COMMAND_CLASS_ERROR
|
||||
}
|
||||
InterfaceCommandClassTypeDef;
|
||||
|
||||
|
||||
typedef enum
|
||||
{
|
||||
COMMAND_INTERFACE_ECHO, //Returns echo packet including all data
|
||||
COMMAND_INTERFACE_NOTIFY_DEVICE //Returns COMMAND_CLASS_*** byte when downstream USB device is connected
|
||||
}
|
||||
InterfaceCommandInterfaceTypeDef;
|
||||
|
||||
|
||||
typedef enum
|
||||
{
|
||||
COMMAND_MSC_TEST_UNIT_READY, //Returns HAL_StatusTypeDef result
|
||||
COMMAND_MSC_GET_CAPACITY, //Returns uint32_t blk_nbr, uint32_t blk_size
|
||||
COMMAND_MSC_READ, //Returns data stream or error packet
|
||||
COMMAND_MSC_WRITE, //Waits for data stream or returns error packet
|
||||
COMMAND_MSC_DISCONNECT, //Returns same packet after sending Stop command to device
|
||||
COMMAND_MSC_POLL_DISCONNECT //Returns same packet if device is still connected
|
||||
}
|
||||
InterfaceCommandMscTypeDef;
|
||||
|
||||
|
||||
typedef enum
|
||||
{
|
||||
COMMAND_HID_GET_REPORT, //Returns HID report from device
|
||||
COMMAND_HID_SET_REPORT //Sends HID report to device. Simple ack packet contains no data.
|
||||
}
|
||||
InterfaceCommandHidTypeDef;
|
||||
|
||||
|
||||
typedef enum
|
||||
{
|
||||
COMMAND_ERROR_GENERIC, //Something went wrong, time to FREAKOUT
|
||||
COMMAND_ERROR_DEVICE_DISCONNECTED, //Device unexpectedly disconnected
|
||||
}
|
||||
InterfaceCommandErrorTypeDef;
|
||||
|
||||
|
||||
|
||||
#endif /* INC_DOWNSTREAM_INTERFACE_DEF_H_ */
|
@ -0,0 +1,36 @@
|
||||
/*
|
||||
* downstream_msc.h
|
||||
*
|
||||
* Created on: 8/08/2015
|
||||
* Author: Robert Fisk
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
#ifndef INC_DOWNSTREAM_MSC_H_
|
||||
#define INC_DOWNSTREAM_MSC_H_
|
||||
|
||||
|
||||
#include "downstream_interface_def.h"
|
||||
#include "downstream_spi.h"
|
||||
|
||||
|
||||
#define MSC_SUPPORTED_BLOCK_SIZE 512
|
||||
#define MSC_FIXED_LUN 0
|
||||
|
||||
|
||||
typedef void (*DownstreamMSCCallbackPacketTypeDef)(DownstreamPacketTypeDef* receivedPacket,
|
||||
uint16_t dataLength8);
|
||||
|
||||
|
||||
InterfaceCommandClassTypeDef Downstream_MSC_ApproveConnectedDevice(void);
|
||||
void Downstream_MSC_PacketProcessor(DownstreamPacketTypeDef* receivedPacket);
|
||||
HAL_StatusTypeDef Downstream_MSC_PutStreamDataPacket(DownstreamPacketTypeDef* packetToSend,
|
||||
uint32_t dataLength8);
|
||||
HAL_StatusTypeDef Downstream_MSC_GetStreamDataPacket(DownstreamMSCCallbackPacketTypeDef callback);
|
||||
|
||||
|
||||
|
||||
#endif /* INC_DOWNSTREAM_MSC_H_ */
|
@ -0,0 +1,84 @@
|
||||
/*
|
||||
* downstream_spi.h
|
||||
*
|
||||
* Created on: 24/07/2015
|
||||
* Author: Robert Fisk
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
#ifndef INC_DOWNSTREAM_SPI_H_
|
||||
#define INC_DOWNSTREAM_SPI_H_
|
||||
|
||||
|
||||
#include "usbh_config.h"
|
||||
|
||||
|
||||
#define DOWNSTREAM_PACKET_HEADER_LEN (2) //Min length = CommandClass & Command bytes
|
||||
#define DOWNSTREAM_PACKET_LEN (DOWNSTREAM_PACKET_HEADER_LEN + BOT_PAGE_LENGTH)
|
||||
#define DOWNSTREAM_PACKET_LEN_MIN (DOWNSTREAM_PACKET_HEADER_LEN)
|
||||
|
||||
#define DOWNSTREAM_PACKET_HEADER_LEN_16 (DOWNSTREAM_PACKET_HEADER_LEN / 2)
|
||||
#define DOWNSTREAM_PACKET_LEN_16 (DOWNSTREAM_PACKET_LEN / 2)
|
||||
#define DOWNSTREAM_PACKET_LEN_MIN_16 (DOWNSTREAM_PACKET_LEN_MIN / 2)
|
||||
|
||||
#define DOWNSTREAM_SPI_FREAKOUT \
|
||||
do { \
|
||||
Downstream_PacketProcessor_FreakOut(); \
|
||||
DownstreamInterfaceState = DOWNSTREAM_INTERFACE_ERROR; \
|
||||
while (1); \
|
||||
} while (0);
|
||||
|
||||
|
||||
|
||||
typedef enum
|
||||
{
|
||||
DOWNSTREAM_INTERFACE_IDLE,
|
||||
DOWNSTREAM_INTERFACE_RX_SIZE_WAIT,
|
||||
DOWNSTREAM_INTERFACE_RX_PACKET_WAIT,
|
||||
DOWNSTREAM_INTERFACE_TX_SIZE_WAIT,
|
||||
DOWNSTREAM_INTERFACE_TX_PACKET_WAIT,
|
||||
DOWNSTREAM_INTERFACE_ERROR
|
||||
}
|
||||
InterfaceStateTypeDef;
|
||||
|
||||
|
||||
typedef enum
|
||||
{
|
||||
NOT_BUSY,
|
||||
BUSY
|
||||
}
|
||||
PacketBusyTypeDef;
|
||||
|
||||
|
||||
typedef struct
|
||||
{
|
||||
PacketBusyTypeDef Busy; //Everything after Busy should be word-aligned
|
||||
uint16_t Length16 __ALIGN_END; //Packet length includes CommandClass, Command, and Data
|
||||
uint8_t CommandClass;
|
||||
uint8_t Command;
|
||||
uint8_t Data[BOT_PAGE_LENGTH]; //Should (must?) be word-aligned, for USB copy routine
|
||||
}
|
||||
DownstreamPacketTypeDef;
|
||||
|
||||
|
||||
|
||||
typedef void (*FreePacketCallbackTypeDef)(DownstreamPacketTypeDef* freePacket);
|
||||
typedef void (*SpiPacketReceivedCallbackTypeDef)(DownstreamPacketTypeDef* receivedPacket);
|
||||
|
||||
|
||||
void Downstream_InitSPI(void);
|
||||
HAL_StatusTypeDef Downstream_GetFreePacket(FreePacketCallbackTypeDef callback);
|
||||
DownstreamPacketTypeDef* Downstream_GetFreePacketImmediately(void);
|
||||
void Downstream_ReleasePacket(DownstreamPacketTypeDef* packetToRelease);
|
||||
HAL_StatusTypeDef Downstream_ReceivePacket(SpiPacketReceivedCallbackTypeDef callback);
|
||||
HAL_StatusTypeDef Downstream_TransmitPacket(DownstreamPacketTypeDef* packetToWrite);
|
||||
void Downstream_SPIProcess(void);
|
||||
|
||||
void HAL_SPI_TxRxCpltCallback(SPI_HandleTypeDef *hspi);
|
||||
void HAL_SPI_ErrorCallback(SPI_HandleTypeDef *hspi);
|
||||
|
||||
|
||||
#endif /* INC_DOWNSTREAM_SPI_H_ */
|
@ -0,0 +1,54 @@
|
||||
/*
|
||||
* downstream_statemachine.h
|
||||
*
|
||||
* Created on: 2/08/2015
|
||||
* Author: Robert Fisk
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
#ifndef INC_DOWNSTREAM_STATEMACHINE_H_
|
||||
#define INC_DOWNSTREAM_STATEMACHINE_H_
|
||||
|
||||
|
||||
#include "usbh_def.h"
|
||||
#include "usb_host.h"
|
||||
#include "downstream_spi.h"
|
||||
|
||||
|
||||
typedef enum
|
||||
{
|
||||
STATE_DEVICE_NOT_READY,
|
||||
STATE_DEVICE_READY, //Go here if HOST_USER_CLASS_ACTIVE callback arrives first
|
||||
STATE_WAIT_DEVICE_READY, //Go here if COMMAND_INTERFACE_NOTIFY_DEVICE message arrives first
|
||||
STATE_ACTIVE,
|
||||
STATE_ERROR
|
||||
} DownstreamStateTypeDef;
|
||||
|
||||
|
||||
|
||||
#define DOWNSTREAM_STATEMACHINE_FREAKOUT \
|
||||
do { \
|
||||
USB_Host_Disconnect(); \
|
||||
LED_SetState(LED_STATUS_FLASH_ERROR); \
|
||||
/*DownstreamState = STATE_ERROR; */ \
|
||||
while (1); \
|
||||
} while (0);
|
||||
|
||||
|
||||
|
||||
|
||||
void Downstream_InitStateMachine(void);
|
||||
void Downstream_HostUserCallback(USBH_HandleTypeDef *phost, uint8_t id);
|
||||
void Downstream_PacketProcessor(DownstreamPacketTypeDef* receivedPacket);
|
||||
void Downstream_PacketProcessor_GenericErrorReply(DownstreamPacketTypeDef* replyPacket);
|
||||
void Downstream_PacketProcessor_ClassReply(DownstreamPacketTypeDef* replyPacket);
|
||||
void Downstream_PacketProcessor_NotifyDisconnectReplyRequired(void);
|
||||
void Downstream_PacketProcessor_CheckNotifyDisconnectReply(void);
|
||||
void Downstream_PacketProcessor_SetErrorState(void);
|
||||
void Downstream_PacketProcessor_FreakOut(void);
|
||||
|
||||
|
||||
#endif /* INC_DOWNSTREAM_STATEMACHINE_H_ */
|
@ -0,0 +1,423 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file stm32f4xx_hal_conf.h
|
||||
* @brief HAL configuration file.
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* <h2><center>© COPYRIGHT(c) 2015 STMicroelectronics</center></h2>
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* 2. 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.
|
||||
* 3. Neither the name of STMicroelectronics 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.
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
/* Define to prevent recursive inclusion -------------------------------------*/
|
||||
#ifndef __STM32F4xx_HAL_CONF_H
|
||||
#define __STM32F4xx_HAL_CONF_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Exported types ------------------------------------------------------------*/
|
||||
/* Exported constants --------------------------------------------------------*/
|
||||
|
||||
/* ########################## Module Selection ############################## */
|
||||
/**
|
||||
* @brief This is the list of modules to be used in the HAL driver
|
||||
*/
|
||||
#define HAL_MODULE_ENABLED
|
||||
|
||||
//#define HAL_ADC_MODULE_ENABLED
|
||||
//#define HAL_CAN_MODULE_ENABLED
|
||||
//#define HAL_CRC_MODULE_ENABLED
|
||||
//#define HAL_CRYP_MODULE_ENABLED
|
||||
//#define HAL_DAC_MODULE_ENABLED
|
||||
//#define HAL_DCMI_MODULE_ENABLED
|
||||
//#define HAL_DMA2D_MODULE_ENABLED
|
||||
//#define HAL_ETH_MODULE_ENABLED
|
||||
//#define HAL_NAND_MODULE_ENABLED
|
||||
//#define HAL_NOR_MODULE_ENABLED
|
||||
//#define HAL_PCCARD_MODULE_ENABLED
|
||||
//#define HAL_SRAM_MODULE_ENABLED
|
||||
//#define HAL_SDRAM_MODULE_ENABLED
|
||||
//#define HAL_HASH_MODULE_ENABLED
|
||||
//#define HAL_I2C_MODULE_ENABLED
|
||||
//#define HAL_I2S_MODULE_ENABLED
|
||||
//#define HAL_IWDG_MODULE_ENABLED
|
||||
//#define HAL_LTDC_MODULE_ENABLED
|
||||
//#define HAL_RNG_MODULE_ENABLED
|
||||
//#define HAL_RTC_MODULE_ENABLED
|
||||
//#define HAL_SAI_MODULE_ENABLED
|
||||
//#define HAL_SD_MODULE_ENABLED
|
||||
#define HAL_SPI_MODULE_ENABLED
|
||||
//#define HAL_TIM_MODULE_ENABLED
|
||||
//#define HAL_UART_MODULE_ENABLED
|
||||
//#define HAL_USART_MODULE_ENABLED
|
||||
//#define HAL_IRDA_MODULE_ENABLED
|
||||
//#define HAL_SMARTCARD_MODULE_ENABLED
|
||||
//#define HAL_WWDG_MODULE_ENABLED
|
||||
//#define HAL_PCD_MODULE_ENABLED
|
||||
#define HAL_HCD_MODULE_ENABLED
|
||||
//#define HAL_QSPI_MODULE_ENABLED
|
||||
//#define HAL_QSPI_MODULE_ENABLED
|
||||
//#define HAL_CEC_MODULE_ENABLED
|
||||
//#define HAL_FMPI2C_MODULE_ENABLED
|
||||
//#define HAL_SPDIFRX_MODULE_ENABLED
|
||||
#define HAL_GPIO_MODULE_ENABLED
|
||||
#define HAL_DMA_MODULE_ENABLED
|
||||
#define HAL_RCC_MODULE_ENABLED
|
||||
#define HAL_FLASH_MODULE_ENABLED
|
||||
#define HAL_PWR_MODULE_ENABLED
|
||||
#define HAL_CORTEX_MODULE_ENABLED
|
||||
|
||||
/* ########################## HSE/HSI Values adaptation ##################### */
|
||||
/**
|
||||
* @brief Adjust the value of External High Speed oscillator (HSE) used in your application.
|
||||
* This value is used by the RCC HAL module to compute the system frequency
|
||||
* (when HSE is used as system clock source, directly or through the PLL).
|
||||
*/
|
||||
#if !defined (HSE_VALUE)
|
||||
#define HSE_VALUE ((uint32_t)8000000) /*!< Value of the External oscillator in Hz */
|
||||
#endif /* HSE_VALUE */
|
||||
|
||||
#if !defined (HSE_STARTUP_TIMEOUT)
|
||||
#define HSE_STARTUP_TIMEOUT ((uint32_t)5000) /*!< Time out for HSE start up, in ms */
|
||||
#endif /* HSE_STARTUP_TIMEOUT */
|
||||
|
||||
/**
|
||||
* @brief Internal High Speed oscillator (HSI) value.
|
||||
* This value is used by the RCC HAL module to compute the system frequency
|
||||
* (when HSI is used as system clock source, directly or through the PLL).
|
||||
*/
|
||||
#if !defined (HSI_VALUE)
|
||||
#define HSI_VALUE ((uint32_t)16000000) /*!< Value of the Internal oscillator in Hz*/
|
||||
#endif /* HSI_VALUE */
|
||||
|
||||
/**
|
||||
* @brief Internal Low Speed oscillator (LSI) value.
|
||||
*/
|
||||
#if !defined (LSI_VALUE)
|
||||
#define LSI_VALUE ((uint32_t)32000)
|
||||
#endif /* LSI_VALUE */ /*!< Value of the Internal Low Speed oscillator in Hz
|
||||
The real value may vary depending on the variations
|
||||
in voltage and temperature. */
|
||||
/**
|
||||
* @brief External Low Speed oscillator (LSE) value.
|
||||
*/
|
||||
#if !defined (LSE_VALUE)
|
||||
#define LSE_VALUE ((uint32_t)32768) /*!< Value of the External Low Speed oscillator in Hz */
|
||||
#endif /* LSE_VALUE */
|
||||
|
||||
/**
|
||||
* @brief External clock source for I2S peripheral
|
||||
* This value is used by the I2S HAL module to compute the I2S clock source
|
||||
* frequency, this source is inserted directly through I2S_CKIN pad.
|
||||
*/
|
||||
#if !defined (EXTERNAL_CLOCK_VALUE)
|
||||
#define EXTERNAL_CLOCK_VALUE ((uint32_t)12288000) /*!< Value of the External audio frequency in Hz*/
|
||||
#endif /* EXTERNAL_CLOCK_VALUE */
|
||||
|
||||
/* Tip: To avoid modifying this file each time you need to use different HSE,
|
||||
=== you can define the HSE value in your toolchain compiler preprocessor. */
|
||||
|
||||
/* ########################### System Configuration ######################### */
|
||||
/**
|
||||
* @brief This is the HAL system configuration section
|
||||
*/
|
||||
|
||||
#define VDD_VALUE ((uint32_t)3300) /*!< Value of VDD in mv */
|
||||
#define TICK_INT_PRIORITY ((uint32_t)0) /*!< tick interrupt priority */
|
||||
#define USE_RTOS 0
|
||||
#define PREFETCH_ENABLE 1
|
||||
#define INSTRUCTION_CACHE_ENABLE 1
|
||||
#define DATA_CACHE_ENABLE 1
|
||||
|
||||
/* ########################## Assert Selection ############################## */
|
||||
/**
|
||||
* @brief Uncomment the line below to expanse the "assert_param" macro in the
|
||||
* HAL drivers code
|
||||
*/
|
||||
/* #define USE_FULL_ASSERT 1 */
|
||||
|
||||
/* ################## Ethernet peripheral configuration ##################### */
|
||||
|
||||
/* Section 1 : Ethernet peripheral configuration */
|
||||
|
||||
/* MAC ADDRESS: MAC_ADDR0:MAC_ADDR1:MAC_ADDR2:MAC_ADDR3:MAC_ADDR4:MAC_ADDR5 */
|
||||
#define MAC_ADDR0 2
|
||||
#define MAC_ADDR1 0
|
||||
#define MAC_ADDR2 0
|
||||
#define MAC_ADDR3 0
|
||||
#define MAC_ADDR4 0
|
||||
#define MAC_ADDR5 0
|
||||
|
||||
/* Definition of the Ethernet driver buffers size and count */
|
||||
#define ETH_RX_BUF_SIZE ETH_MAX_PACKET_SIZE /* buffer size for receive */
|
||||
#define ETH_TX_BUF_SIZE ETH_MAX_PACKET_SIZE /* buffer size for transmit */
|
||||
#define ETH_RXBUFNB ((uint32_t)4) /* 4 Rx buffers of size ETH_RX_BUF_SIZE */
|
||||
#define ETH_TXBUFNB ((uint32_t)4) /* 4 Tx buffers of size ETH_TX_BUF_SIZE */
|
||||
|
||||
/* Section 2: PHY configuration section */
|
||||
|
||||
/* DP83848 PHY Address*/
|
||||
#define DP83848_PHY_ADDRESS 0x01
|
||||
/* PHY Reset delay these values are based on a 1 ms Systick interrupt*/
|
||||
#define PHY_RESET_DELAY ((uint32_t)0x000000FF)
|
||||
/* PHY Configuration delay */
|
||||
#define PHY_CONFIG_DELAY ((uint32_t)0x00000FFF)
|
||||
|
||||
#define PHY_READ_TO ((uint32_t)0x0000FFFF)
|
||||
#define PHY_WRITE_TO ((uint32_t)0x0000FFFF)
|
||||
|
||||
/* Section 3: Common PHY Registers */
|
||||
|
||||
#define PHY_BCR ((uint16_t)0x00) /*!< Transceiver Basic Control Register */
|
||||
#define PHY_BSR ((uint16_t)0x01) /*!< Transceiver Basic Status Register */
|
||||
|
||||
#define PHY_RESET ((uint16_t)0x8000) /*!< PHY Reset */
|
||||
#define PHY_LOOPBACK ((uint16_t)0x4000) /*!< Select loop-back mode */
|
||||
#define PHY_FULLDUPLEX_100M ((uint16_t)0x2100) /*!< Set the full-duplex mode at 100 Mb/s */
|
||||
#define PHY_HALFDUPLEX_100M ((uint16_t)0x2000) /*!< Set the half-duplex mode at 100 Mb/s */
|
||||
#define PHY_FULLDUPLEX_10M ((uint16_t)0x0100) /*!< Set the full-duplex mode at 10 Mb/s */
|
||||
#define PHY_HALFDUPLEX_10M ((uint16_t)0x0000) /*!< Set the half-duplex mode at 10 Mb/s */
|
||||
#define PHY_AUTONEGOTIATION ((uint16_t)0x1000) /*!< Enable auto-negotiation function */
|
||||
#define PHY_RESTART_AUTONEGOTIATION ((uint16_t)0x0200) /*!< Restart auto-negotiation function */
|
||||
#define PHY_POWERDOWN ((uint16_t)0x0800) /*!< Select the power down mode */
|
||||
#define PHY_ISOLATE ((uint16_t)0x0400) /*!< Isolate PHY from MII */
|
||||
|
||||
#define PHY_AUTONEGO_COMPLETE ((uint16_t)0x0020) /*!< Auto-Negotiation process completed */
|
||||
#define PHY_LINKED_STATUS ((uint16_t)0x0004) /*!< Valid link established */
|
||||
#define PHY_JABBER_DETECTION ((uint16_t)0x0002) /*!< Jabber condition detected */
|
||||
|
||||
/* Section 4: Extended PHY Registers */
|
||||
|
||||
#define PHY_SR ((uint16_t)0x10) /*!< PHY status register Offset */
|
||||
#define PHY_MICR ((uint16_t)0x11) /*!< MII Interrupt Control Register */
|
||||
#define PHY_MISR ((uint16_t)0x12) /*!< MII Interrupt Status and Misc. Control Register */
|
||||
|
||||
#define PHY_LINK_STATUS ((uint16_t)0x0001) /*!< PHY Link mask */
|
||||
#define PHY_SPEED_STATUS ((uint16_t)0x0002) /*!< PHY Speed mask */
|
||||
#define PHY_DUPLEX_STATUS ((uint16_t)0x0004) /*!< PHY Duplex mask */
|
||||
|
||||
#define PHY_MICR_INT_EN ((uint16_t)0x0002) /*!< PHY Enable interrupts */
|
||||
#define PHY_MICR_INT_OE ((uint16_t)0x0001) /*!< PHY Enable output interrupt events */
|
||||
|
||||
#define PHY_MISR_LINK_INT_EN ((uint16_t)0x0020) /*!< Enable Interrupt on change of link status */
|
||||
#define PHY_LINK_INTERRUPT ((uint16_t)0x2000) /*!< PHY link status interrupt mask */
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
/**
|
||||
* @brief Include module's header file
|
||||
*/
|
||||
|
||||
#ifdef HAL_RCC_MODULE_ENABLED
|
||||
#include "stm32f4xx_hal_rcc.h"
|
||||
#endif /* HAL_RCC_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_GPIO_MODULE_ENABLED
|
||||
#include "stm32f4xx_hal_gpio.h"
|
||||
#endif /* HAL_GPIO_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_DMA_MODULE_ENABLED
|
||||
#include "stm32f4xx_hal_dma.h"
|
||||
#endif /* HAL_DMA_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_CORTEX_MODULE_ENABLED
|
||||
#include "stm32f4xx_hal_cortex.h"
|
||||
#endif /* HAL_CORTEX_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_ADC_MODULE_ENABLED
|
||||
#include "stm32f4xx_hal_adc.h"
|
||||
#endif /* HAL_ADC_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_CAN_MODULE_ENABLED
|
||||
#include "stm32f4xx_hal_can.h"
|
||||
#endif /* HAL_CAN_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_CRC_MODULE_ENABLED
|
||||
#include "stm32f4xx_hal_crc.h"
|
||||
#endif /* HAL_CRC_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_CRYP_MODULE_ENABLED
|
||||
#include "stm32f4xx_hal_cryp.h"
|
||||
#endif /* HAL_CRYP_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_DMA2D_MODULE_ENABLED
|
||||
#include "stm32f4xx_hal_dma2d.h"
|
||||
#endif /* HAL_DMA2D_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_DAC_MODULE_ENABLED
|
||||
#include "stm32f4xx_hal_dac.h"
|
||||
#endif /* HAL_DAC_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_DCMI_MODULE_ENABLED
|
||||
#include "stm32f4xx_hal_dcmi.h"
|
||||
#endif /* HAL_DCMI_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_ETH_MODULE_ENABLED
|
||||
#include "stm32f4xx_hal_eth.h"
|
||||
#endif /* HAL_ETH_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_FLASH_MODULE_ENABLED
|
||||
#include "stm32f4xx_hal_flash.h"
|
||||
#endif /* HAL_FLASH_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_SRAM_MODULE_ENABLED
|
||||
#include "stm32f4xx_hal_sram.h"
|
||||
#endif /* HAL_SRAM_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_NOR_MODULE_ENABLED
|
||||
#include "stm32f4xx_hal_nor.h"
|
||||
#endif /* HAL_NOR_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_NAND_MODULE_ENABLED
|
||||
#include "stm32f4xx_hal_nand.h"
|
||||
#endif /* HAL_NAND_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_PCCARD_MODULE_ENABLED
|
||||
#include "stm32f4xx_hal_pccard.h"
|
||||
#endif /* HAL_PCCARD_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_SDRAM_MODULE_ENABLED
|
||||
#include "stm32f4xx_hal_sdram.h"
|
||||
#endif /* HAL_SDRAM_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_HASH_MODULE_ENABLED
|
||||
#include "stm32f4xx_hal_hash.h"
|
||||
#endif /* HAL_HASH_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_I2C_MODULE_ENABLED
|
||||
#include "stm32f4xx_hal_i2c.h"
|
||||
#endif /* HAL_I2C_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_I2S_MODULE_ENABLED
|
||||
#include "stm32f4xx_hal_i2s.h"
|
||||
#endif /* HAL_I2S_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_IWDG_MODULE_ENABLED
|
||||
#include "stm32f4xx_hal_iwdg.h"
|
||||
#endif /* HAL_IWDG_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_LTDC_MODULE_ENABLED
|
||||
#include "stm32f4xx_hal_ltdc.h"
|
||||
#endif /* HAL_LTDC_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_PWR_MODULE_ENABLED
|
||||
#include "stm32f4xx_hal_pwr.h"
|
||||
#endif /* HAL_PWR_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_RNG_MODULE_ENABLED
|
||||
#include "stm32f4xx_hal_rng.h"
|
||||
#endif /* HAL_RNG_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_RTC_MODULE_ENABLED
|
||||
#include "stm32f4xx_hal_rtc.h"
|
||||
#endif /* HAL_RTC_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_SAI_MODULE_ENABLED
|
||||
#include "stm32f4xx_hal_sai.h"
|
||||
#endif /* HAL_SAI_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_SD_MODULE_ENABLED
|
||||
#include "stm32f4xx_hal_sd.h"
|
||||
#endif /* HAL_SD_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_SPI_MODULE_ENABLED
|
||||
#include "stm32f4xx_hal_spi.h"
|
||||
#endif /* HAL_SPI_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_TIM_MODULE_ENABLED
|
||||
#include "stm32f4xx_hal_tim.h"
|
||||
#endif /* HAL_TIM_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_UART_MODULE_ENABLED
|
||||
#include "stm32f4xx_hal_uart.h"
|
||||
#endif /* HAL_UART_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_USART_MODULE_ENABLED
|
||||
#include "stm32f4xx_hal_usart.h"
|
||||
#endif /* HAL_USART_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_IRDA_MODULE_ENABLED
|
||||
#include "stm32f4xx_hal_irda.h"
|
||||
#endif /* HAL_IRDA_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_SMARTCARD_MODULE_ENABLED
|
||||
#include "stm32f4xx_hal_smartcard.h"
|
||||
#endif /* HAL_SMARTCARD_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_WWDG_MODULE_ENABLED
|
||||
#include "stm32f4xx_hal_wwdg.h"
|
||||
#endif /* HAL_WWDG_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_PCD_MODULE_ENABLED
|
||||
#include "stm32f4xx_hal_pcd.h"
|
||||
#endif /* HAL_PCD_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_HCD_MODULE_ENABLED
|
||||
#include "stm32f4xx_hal_hcd.h"
|
||||
#endif /* HAL_HCD_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_QSPI_MODULE_ENABLED
|
||||
#include "stm32f4xx_hal_qspi.h"
|
||||
#endif /* HAL_QSPI_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_CEC_MODULE_ENABLED
|
||||
#include "stm32f4xx_hal_cec.h"
|
||||
#endif /* HAL_CEC_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_FMPI2C_MODULE_ENABLED
|
||||
#include "stm32f4xx_hal_fmpi2c.h"
|
||||
#endif /* HAL_FMPI2C_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_SPDIFRX_MODULE_ENABLED
|
||||
#include "stm32f4xx_hal_spdifrx.h"
|
||||
#endif /* HAL_SPDIFRX_MODULE_ENABLED */
|
||||
|
||||
/* Exported macro ------------------------------------------------------------*/
|
||||
#ifdef USE_FULL_ASSERT
|
||||
/**
|
||||
* @brief The assert_param macro is used for function's parameters check.
|
||||
* @param expr: If expr is false, it calls assert_failed function
|
||||
* which reports the name of the source file and the source
|
||||
* line number of the call that failed.
|
||||
* If expr is true, it returns no value.
|
||||
* @retval None
|
||||
*/
|
||||
#define assert_param(expr) ((expr) ? (void)0 : assert_failed((uint8_t *)__FILE__, __LINE__))
|
||||
/* Exported functions ------------------------------------------------------- */
|
||||
void assert_failed(uint8_t* file, uint32_t line);
|
||||
#else
|
||||
#define assert_param(expr) ((void)0)
|
||||
#endif /* USE_FULL_ASSERT */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __STM32F4xx_HAL_CONF_H */
|
||||
|
||||
|
||||
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
|
@ -0,0 +1,72 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file stm32f4xx_it.h
|
||||
* @brief This file contains the headers of the interrupt handlers.
|
||||
******************************************************************************
|
||||
*
|
||||
* COPYRIGHT(c) 2015 STMicroelectronics
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* 2. 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.
|
||||
* 3. Neither the name of STMicroelectronics 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.
|
||||
*
|
||||
******************************************************************************
|
||||
*
|
||||
* Modifications by Robert Fisk
|
||||
*/
|
||||
|
||||
/* Define to prevent recursive inclusion -------------------------------------*/
|
||||
#ifndef __STM32F4xx_IT_H
|
||||
#define __STM32F4xx_IT_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
/* Exported types ------------------------------------------------------------*/
|
||||
/* Exported constants --------------------------------------------------------*/
|
||||
|
||||
#define INT_PRIORITY_SYSTICK 2
|
||||
#define INT_PRIORITY_SPI_DMA 10
|
||||
//#define INT_PRIORITY_SPI 8 //Interrupt-based SPI must be highest priority!
|
||||
#define INT_PRIORITY_USB 10
|
||||
|
||||
|
||||
/* Exported macro ------------------------------------------------------------*/
|
||||
/* Exported functions ------------------------------------------------------- */
|
||||
|
||||
void SysTick_Handler(void);
|
||||
void DMA2_Stream2_IRQHandler(void);
|
||||
void DMA2_Stream3_IRQHandler(void);
|
||||
void OTG_FS_IRQHandler(void);
|
||||
void BusFault_Handler(void);
|
||||
|
||||
void EnableOneBusFault(void);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __STM32F4xx_IT_H */
|
||||
|
||||
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
|
@ -0,0 +1,47 @@
|
||||
/*
|
||||
* led.h
|
||||
*
|
||||
* Created on: 19/08/2015
|
||||
* Author: Robert Fisk
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
#ifndef INC_LED_H_
|
||||
#define INC_LED_H_
|
||||
|
||||
|
||||
#include "stm32f4xx_hal.h"
|
||||
|
||||
|
||||
typedef enum
|
||||
{
|
||||
LED_STATUS_STARTUP,
|
||||
LED_STATUS_OFF,
|
||||
LED_STATUS_FLASH_ERROR,
|
||||
LED_STATUS_FLASH_UNSUPPORTED,
|
||||
LED_STATUS_FLASH_BOTDETECT,
|
||||
LED_STATUS_FLASH_READWRITE
|
||||
}
|
||||
LedStatusTypeDef;
|
||||
|
||||
|
||||
void LED_Init(void);
|
||||
void LED_SetState(LedStatusTypeDef newState);
|
||||
void LED_Tick(void);
|
||||
|
||||
|
||||
#define STARTUP_FLASH_DELAY_MS 500
|
||||
|
||||
#define LED_ERROR_BLINK_MS 100
|
||||
#define LED_UNSUPPORTED_BLINK_MS 500
|
||||
#define LED_BOTDETECT_ON_MS 100
|
||||
#define LED_BOTDETECT_OFF_MS (1000 - (LED_BOTDETECT_ON_MS * 3)) //Two flashes, total period = 1 sec
|
||||
#define LED_READWRITE_ON_MS 10
|
||||
#define LED_READWRITE_OFF_MS 30
|
||||
|
||||
|
||||
|
||||
#endif /* INC_LED_H_ */
|
@ -0,0 +1,66 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file : USB_HOST
|
||||
* @version : v1.0_Cube
|
||||
* @brief : Header for usb_host file.
|
||||
******************************************************************************
|
||||
* COPYRIGHT(c) 2015 STMicroelectronics
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* 2. 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.
|
||||
* 3. Neither the name of STMicroelectronics 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.
|
||||
*
|
||||
******************************************************************************
|
||||
*
|
||||
* Modifications by Robert Fisk
|
||||
*/
|
||||
|
||||
/* Define to prevent recursive inclusion -------------------------------------*/
|
||||
#ifndef __usb_host_H
|
||||
#define __usb_host_H
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include "stm32f4xx.h"
|
||||
#include "stm32f4xx_hal.h"
|
||||
|
||||
|
||||
void USB_Host_Init(void);
|
||||
void USB_Host_Process(void);
|
||||
void USB_Host_Disconnect(void);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif /*__usb_host_H */
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
|
@ -0,0 +1,179 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file : usbh_conf.h
|
||||
* @version : v1.0_Cube
|
||||
* @brief : Header for usbh_conf file.
|
||||
******************************************************************************
|
||||
* COPYRIGHT(c) 2015 STMicroelectronics
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* 2. 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.
|
||||
* 3. Neither the name of STMicroelectronics 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.
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
/* Define to prevent recursive inclusion -------------------------------------*/
|
||||
#ifndef __USBH_CONF__H__
|
||||
#define __USBH_CONF__H__
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include "stm32f4xx.h"
|
||||
#include "stm32f4xx_hal.h"
|
||||
|
||||
/**
|
||||
MiddleWare name : USB_HOST
|
||||
MiddleWare fileName : usbh_conf.h
|
||||
MiddleWare version :
|
||||
*/
|
||||
/*---------- -----------*/
|
||||
#define USBH_MAX_NUM_ENDPOINTS 2
|
||||
|
||||
/*---------- -----------*/
|
||||
#define USBH_MAX_NUM_INTERFACES 3
|
||||
|
||||
/*---------- -----------*/
|
||||
#define USBH_MAX_NUM_CONFIGURATION 1
|
||||
|
||||
/*---------- -----------*/
|
||||
#define USBH_KEEP_CFG_DESCRIPTOR 0
|
||||
|
||||
/*---------- -----------*/
|
||||
#define USBH_MAX_NUM_SUPPORTED_CLASS 2
|
||||
|
||||
/*---------- -----------*/
|
||||
#define USBH_MAX_SIZE_CONFIGURATION 256
|
||||
|
||||
/*---------- -----------*/
|
||||
#define USBH_MAX_DATA_BUFFER 256 //was 512, string descriptors are max 255 bytes
|
||||
|
||||
/*---------- -----------*/
|
||||
#define USBH_DEBUG_LEVEL 0
|
||||
|
||||
/*---------- -----------*/
|
||||
#define USBH_USE_OS 0
|
||||
|
||||
|
||||
#define BOT_PAGE_LENGTH 512 //Moved here from usbh_msc_bot.h to avoid a circular include loop :(
|
||||
|
||||
|
||||
/****************************************/
|
||||
/* #define for FS and HS identification */
|
||||
#define HOST_HS 0
|
||||
#define HOST_FS 1
|
||||
|
||||
/** @defgroup USBH_Exported_Macros
|
||||
* @{
|
||||
*/
|
||||
#if (USBH_USE_OS == 1)
|
||||
#include "cmsis_os.h"
|
||||
#define USBH_PROCESS_PRIO osPriorityNormal
|
||||
#define USBH_PROCESS_STACK_SIZE ((uint16_t)0)
|
||||
#endif
|
||||
|
||||
/* Memory management macros */
|
||||
#define USBH_malloc malloc
|
||||
#define USBH_free free
|
||||
#define USBH_memset memset
|
||||
#define USBH_memcpy memcpy
|
||||
|
||||
/* DEBUG macros */
|
||||
|
||||
#if (USBH_DEBUG_LEVEL > 0)
|
||||
#define USBH_UsrLog(...) printf(__VA_ARGS__);\
|
||||
printf("\n");
|
||||
#else
|
||||
#define USBH_UsrLog(...)
|
||||
#endif
|
||||
|
||||
|
||||
#if (USBH_DEBUG_LEVEL > 1)
|
||||
|
||||
#define USBH_ErrLog(...) printf("ERROR: ") ;\
|
||||
printf(__VA_ARGS__);\
|
||||
printf("\n");
|
||||
#else
|
||||
#define USBH_ErrLog(...)
|
||||
#endif
|
||||
|
||||
|
||||
#if (USBH_DEBUG_LEVEL > 2)
|
||||
#define USBH_DbgLog(...) printf("DEBUG : ") ;\
|
||||
printf(__VA_ARGS__);\
|
||||
printf("\n");
|
||||
#else
|
||||
#define USBH_DbgLog(...)
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @defgroup USBH_CONF_Exported_Types
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @defgroup USBH_CONF_Exported_Macros
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @defgroup USBH_CONF_Exported_Variables
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @defgroup USBH_CONF_Exported_FunctionsPrototype
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
#endif //__USBH_CONF__H__
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
|
||||
|
@ -0,0 +1,362 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file usbh_hid.h
|
||||
* @author MCD Application Team
|
||||
* @version V3.2.2
|
||||
* @date 07-July-2015
|
||||
* @brief This file contains all the prototypes for the usbh_hid.c
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* <h2><center>© COPYRIGHT 2015 STMicroelectronics</center></h2>
|
||||
*
|
||||
* Licensed under MCD-ST Liberty SW License Agreement V2, (the "License");
|
||||
* You may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at:
|
||||
*
|
||||
* http://www.st.com/software_license_agreement_liberty_v2
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
******************************************************************************
|
||||
*
|
||||
* Modifications by Robert Fisk
|
||||
*
|
||||
*/
|
||||
|
||||
/* Define to prevent recursive ----------------------------------------------*/
|
||||
#ifndef __USBH_HID_H
|
||||
#define __USBH_HID_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include "usbh_core.h"
|
||||
#include "downstream_hid.h"
|
||||
|
||||
|
||||
/** @addtogroup USBH_LIB
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @addtogroup USBH_CLASS
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @addtogroup USBH_HID_CLASS
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @defgroup USBH_HID_CORE
|
||||
* @brief This file is the Header file for usbh_hid.c
|
||||
* @{
|
||||
*/
|
||||
|
||||
|
||||
/** @defgroup USBH_HID_CORE_Exported_Types
|
||||
* @{
|
||||
*/
|
||||
|
||||
#define HID_MIN_POLL 10
|
||||
#define HID_MAX_REPORT_SIZE 8
|
||||
#define HID_REPORT_BUFFER_SIZE 64
|
||||
#define HID_MAX_USAGE 10
|
||||
#define HID_MAX_NBR_REPORT_FMT 10
|
||||
//#define HID_QUEUE_SIZE 10
|
||||
//
|
||||
//#define HID_ITEM_LONG 0xFE
|
||||
//
|
||||
//#define HID_ITEM_TYPE_MAIN 0x00
|
||||
//#define HID_ITEM_TYPE_GLOBAL 0x01
|
||||
//#define HID_ITEM_TYPE_LOCAL 0x02
|
||||
//#define HID_ITEM_TYPE_RESERVED 0x03
|
||||
//
|
||||
//
|
||||
//#define HID_MAIN_ITEM_TAG_INPUT 0x08
|
||||
//#define HID_MAIN_ITEM_TAG_OUTPUT 0x09
|
||||
//#define HID_MAIN_ITEM_TAG_COLLECTION 0x0A
|
||||
//#define HID_MAIN_ITEM_TAG_FEATURE 0x0B
|
||||
//#define HID_MAIN_ITEM_TAG_ENDCOLLECTION 0x0C
|
||||
//
|
||||
//
|
||||
//#define HID_GLOBAL_ITEM_TAG_USAGE_PAGE 0x00
|
||||
//#define HID_GLOBAL_ITEM_TAG_LOG_MIN 0x01
|
||||
//#define HID_GLOBAL_ITEM_TAG_LOG_MAX 0x02
|
||||
//#define HID_GLOBAL_ITEM_TAG_PHY_MIN 0x03
|
||||
//#define HID_GLOBAL_ITEM_TAG_PHY_MAX 0x04
|
||||
//#define HID_GLOBAL_ITEM_TAG_UNIT_EXPONENT 0x05
|
||||
//#define HID_GLOBAL_ITEM_TAG_UNIT 0x06
|
||||
//#define HID_GLOBAL_ITEM_TAG_REPORT_SIZE 0x07
|
||||
//#define HID_GLOBAL_ITEM_TAG_REPORT_ID 0x08
|
||||
//#define HID_GLOBAL_ITEM_TAG_REPORT_COUNT 0x09
|
||||
//#define HID_GLOBAL_ITEM_TAG_PUSH 0x0A
|
||||
//#define HID_GLOBAL_ITEM_TAG_POP 0x0B
|
||||
//
|
||||
//
|
||||
//#define HID_LOCAL_ITEM_TAG_USAGE 0x00
|
||||
//#define HID_LOCAL_ITEM_TAG_USAGE_MIN 0x01
|
||||
//#define HID_LOCAL_ITEM_TAG_USAGE_MAX 0x02
|
||||
//#define HID_LOCAL_ITEM_TAG_DESIGNATOR_INDEX 0x03
|
||||
//#define HID_LOCAL_ITEM_TAG_DESIGNATOR_MIN 0x04
|
||||
//#define HID_LOCAL_ITEM_TAG_DESIGNATOR_MAX 0x05
|
||||
//#define HID_LOCAL_ITEM_TAG_STRING_INDEX 0x07
|
||||
//#define HID_LOCAL_ITEM_TAG_STRING_MIN 0x08
|
||||
//#define HID_LOCAL_ITEM_TAG_STRING_MAX 0x09
|
||||
//#define HID_LOCAL_ITEM_TAG_DELIMITER 0x0A
|
||||
|
||||
|
||||
#define HID_REPORT_DIRECTION_IN 0x01
|
||||
#define HID_REPORT_DIRECTION_OUT 0x02
|
||||
|
||||
|
||||
/* States for HID State Machine */
|
||||
typedef enum
|
||||
{
|
||||
HID_INIT= 0,
|
||||
HID_IDLE,
|
||||
HID_GET_DATA,
|
||||
HID_GET_POLL,
|
||||
HID_SET_DATA_POLL,
|
||||
HID_ERROR,
|
||||
}
|
||||
HID_StateTypeDef;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
HID_REQ_INIT = 0,
|
||||
HID_REQ_IDLE,
|
||||
HID_REQ_GET_REPORT_DESC,
|
||||
HID_REQ_GET_HID_DESC,
|
||||
HID_REQ_SET_IDLE,
|
||||
HID_REQ_SET_PROTOCOL,
|
||||
HID_REQ_SET_REPORT,
|
||||
|
||||
}
|
||||
HID_CtlStateTypeDef;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
HID_MOUSE = 0x01,
|
||||
HID_KEYBOARD = 0x02,
|
||||
HID_UNKNOWN = 0xFF,
|
||||
}
|
||||
HID_TypeTypeDef;
|
||||
|
||||
|
||||
typedef struct _HID_ReportData
|
||||
{
|
||||
uint8_t ReportID;
|
||||
uint8_t ReportType;
|
||||
uint16_t UsagePage;
|
||||
uint32_t Usage[HID_MAX_USAGE];
|
||||
uint32_t NbrUsage;
|
||||
uint32_t UsageMin;
|
||||
uint32_t UsageMax;
|
||||
int32_t LogMin;
|
||||
int32_t LogMax;
|
||||
int32_t PhyMin;
|
||||
int32_t PhyMax;
|
||||
int32_t UnitExp;
|
||||
uint32_t Unit;
|
||||
uint32_t ReportSize;
|
||||
uint32_t ReportCnt;
|
||||
uint32_t Flag;
|
||||
uint32_t PhyUsage;
|
||||
uint32_t AppUsage;
|
||||
uint32_t LogUsage;
|
||||
}
|
||||
HID_ReportDataTypeDef;
|
||||
|
||||
typedef struct _HID_ReportIDTypeDef {
|
||||
uint8_t Size; /* Report size return by the device id */
|
||||
uint8_t ReportID; /* Report Id */
|
||||
uint8_t Type; /* Report Type (INPUT/OUTPUT/FEATURE) */
|
||||
} HID_ReportIDTypeDef;
|
||||
|
||||
typedef struct _HID_CollectionTypeDef
|
||||
{
|
||||
uint32_t Usage;
|
||||
uint8_t Type;
|
||||
struct _HID_CollectionTypeDef *NextPtr;
|
||||
} HID_CollectionTypeDef;
|
||||
|
||||
|
||||
typedef struct _HID_AppCollectionTypeDef {
|
||||
uint32_t Usage;
|
||||
uint8_t Type;
|
||||
uint8_t NbrReportFmt;
|
||||
HID_ReportDataTypeDef ReportData[HID_MAX_NBR_REPORT_FMT];
|
||||
} HID_AppCollectionTypeDef;
|
||||
|
||||
|
||||
typedef struct _HIDDescriptor
|
||||
{
|
||||
uint8_t bLength;
|
||||
uint8_t bDescriptorType;
|
||||
uint16_t bcdHID; /* indicates what endpoint this descriptor is describing */
|
||||
uint8_t bCountryCode; /* specifies the transfer type. */
|
||||
uint8_t bNumDescriptors; /* specifies the transfer type. */
|
||||
uint8_t bReportDescriptorType; /* Maximum Packet Size this endpoint is capable of sending or receiving */
|
||||
uint16_t wItemLength; /* is used to specify the polling interval of certain transfers. */
|
||||
}
|
||||
HID_DescTypeDef;
|
||||
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint8_t *buf;
|
||||
uint16_t head;
|
||||
uint16_t tail;
|
||||
uint16_t size;
|
||||
uint8_t lock;
|
||||
} FIFO_TypeDef;
|
||||
|
||||
|
||||
|
||||
/* Structure for HID process */
|
||||
typedef struct _HID_Process
|
||||
{
|
||||
uint8_t OutPipe;
|
||||
uint8_t InPipe;
|
||||
uint8_t OutEp;
|
||||
uint8_t InEp;
|
||||
HID_StateTypeDef state;
|
||||
HID_CtlStateTypeDef ctl_state;
|
||||
uint16_t length;
|
||||
uint16_t poll;
|
||||
uint32_t timer;
|
||||
uint8_t ep_addr;
|
||||
uint8_t Protocol;
|
||||
HID_DescTypeDef HID_Desc;
|
||||
TransactionCompleteCallbackTypeDef ReportCallback;
|
||||
uint8_t Data[HID_REPORT_BUFFER_SIZE];
|
||||
}
|
||||
HID_HandleTypeDef;
|
||||
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @defgroup USBH_HID_CORE_Exported_Defines
|
||||
* @{
|
||||
*/
|
||||
|
||||
#define USB_HID_GET_REPORT 0x01
|
||||
#define USB_HID_GET_IDLE 0x02
|
||||
#define USB_HID_GET_PROTOCOL 0x03
|
||||
#define USB_HID_SET_REPORT 0x09
|
||||
#define USB_HID_SET_IDLE 0x0A
|
||||
#define USB_HID_SET_PROTOCOL 0x0B
|
||||
|
||||
|
||||
|
||||
|
||||
/* HID Class Codes */
|
||||
#define USB_HID_CLASS 0x03
|
||||
|
||||
/* Interface Descriptor field values for HID Boot Protocol */
|
||||
#define HID_BOOT_CODE 0x01
|
||||
#define HID_KEYBRD_PROTOCOL 0x01
|
||||
#define HID_MOUSE_PROTOCOL 0x02
|
||||
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @defgroup USBH_HID_CORE_Exported_Macros
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @defgroup USBH_HID_CORE_Exported_Variables
|
||||
* @{
|
||||
*/
|
||||
extern USBH_ClassTypeDef HID_Class;
|
||||
#define USBH_HID_CLASS &HID_Class
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @defgroup USBH_HID_CORE_Exported_FunctionsPrototype
|
||||
* @{
|
||||
*/
|
||||
|
||||
USBH_StatusTypeDef USBH_HID_SetReport (USBH_HandleTypeDef *phost,
|
||||
uint8_t reportType,
|
||||
uint8_t reportId,
|
||||
uint8_t* reportBuff,
|
||||
uint8_t reportLen,
|
||||
TransactionCompleteCallbackTypeDef callback);
|
||||
|
||||
USBH_StatusTypeDef USBH_HID_GetReport (USBH_HandleTypeDef *phost,
|
||||
uint8_t reportType,
|
||||
uint8_t reportId,
|
||||
uint8_t* reportBuff,
|
||||
uint8_t reportLen);
|
||||
|
||||
USBH_StatusTypeDef USBH_HID_GetHIDReportDescriptor (USBH_HandleTypeDef *phost,
|
||||
uint16_t length);
|
||||
|
||||
USBH_StatusTypeDef USBH_HID_GetHIDDescriptor (USBH_HandleTypeDef *phost,
|
||||
uint16_t length);
|
||||
|
||||
USBH_StatusTypeDef USBH_HID_SetIdle (USBH_HandleTypeDef *phost,
|
||||
uint8_t duration,
|
||||
uint8_t reportId);
|
||||
|
||||
USBH_StatusTypeDef USBH_HID_SetProtocol (USBH_HandleTypeDef *phost,
|
||||
uint8_t protocol);
|
||||
|
||||
void USBH_HID_EventCallback(USBH_HandleTypeDef *phost);
|
||||
|
||||
HID_TypeTypeDef USBH_HID_GetDeviceType(USBH_HandleTypeDef *phost);
|
||||
|
||||
uint8_t USBH_HID_GetPollInterval(USBH_HandleTypeDef *phost);
|
||||
|
||||
void fifo_init(FIFO_TypeDef * f, uint8_t * buf, uint16_t size);
|
||||
|
||||
uint16_t fifo_read(FIFO_TypeDef * f, void * buf, uint16_t nbytes);
|
||||
|
||||
uint16_t fifo_write(FIFO_TypeDef * f, const void * buf, uint16_t nbytes);
|
||||
|
||||
HAL_StatusTypeDef USBH_HID_GetInterruptReport(USBH_HandleTypeDef *phost,
|
||||
TransactionCompleteCallbackTypeDef callback);
|
||||
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __USBH_HID_H */
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
|
||||
|
@ -0,0 +1,326 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file usbh_hid_keybd.h
|
||||
* @author MCD Application Team
|
||||
* @version V3.2.2
|
||||
* @date 07-July-2015
|
||||
* @brief This file contains all the prototypes for the usbh_hid_keybd.c
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* <h2><center>© COPYRIGHT 2015 STMicroelectronics</center></h2>
|
||||
*
|
||||
* Licensed under MCD-ST Liberty SW License Agreement V2, (the "License");
|
||||
* You may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at:
|
||||
*
|
||||
* http://www.st.com/software_license_agreement_liberty_v2
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
/* Define to prevent recursive -----------------------------------------------*/
|
||||
#ifndef __USBH_HID_KEYBD_H
|
||||
#define __USBH_HID_KEYBD_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include "usbh_hid.h"
|
||||
#include "usbh_hid_keybd.h"
|
||||
|
||||
/** @addtogroup USBH_LIB
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @addtogroup USBH_CLASS
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @addtogroup USBH_HID_CLASS
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @defgroup USBH_HID_KEYBD
|
||||
* @brief This file is the Header file for usbh_hid_keybd.c
|
||||
* @{
|
||||
*/
|
||||
|
||||
|
||||
/** @defgroup USBH_HID_KEYBD_Exported_Types
|
||||
* @{
|
||||
*/
|
||||
#define KEY_NONE 0x00
|
||||
#define KEY_ERRORROLLOVER 0x01
|
||||
#define KEY_POSTFAIL 0x02
|
||||
#define KEY_ERRORUNDEFINED 0x03
|
||||
#define KEY_A 0x04
|
||||
#define KEY_B 0x05
|
||||
#define KEY_C 0x06
|
||||
#define KEY_D 0x07
|
||||
#define KEY_E 0x08
|
||||
#define KEY_F 0x09
|
||||
#define KEY_G 0x0A
|
||||
#define KEY_H 0x0B
|
||||
#define KEY_I 0x0C
|
||||
#define KEY_J 0x0D
|
||||
#define KEY_K 0x0E
|
||||
#define KEY_L 0x0F
|
||||
#define KEY_M 0x10
|
||||
#define KEY_N 0x11
|
||||
#define KEY_O 0x12
|
||||
#define KEY_P 0x13
|
||||
#define KEY_Q 0x14
|
||||
#define KEY_R 0x15
|
||||
#define KEY_S 0x16
|
||||
#define KEY_T 0x17
|
||||
#define KEY_U 0x18
|
||||
#define KEY_V 0x19
|
||||
#define KEY_W 0x1A
|
||||
#define KEY_X 0x1B
|
||||
#define KEY_Y 0x1C
|
||||
#define KEY_Z 0x1D
|
||||
#define KEY_1_EXCLAMATION_MARK 0x1E
|
||||
#define KEY_2_AT 0x1F
|
||||
#define KEY_3_NUMBER_SIGN 0x20
|
||||
#define KEY_4_DOLLAR 0x21
|
||||
#define KEY_5_PERCENT 0x22
|
||||
#define KEY_6_CARET 0x23
|
||||
#define KEY_7_AMPERSAND 0x24
|
||||
#define KEY_8_ASTERISK 0x25
|
||||
#define KEY_9_OPARENTHESIS 0x26
|
||||
#define KEY_0_CPARENTHESIS 0x27
|
||||
#define KEY_ENTER 0x28
|
||||
#define KEY_ESCAPE 0x29
|
||||
#define KEY_BACKSPACE 0x2A
|
||||
#define KEY_TAB 0x2B
|
||||
#define KEY_SPACEBAR 0x2C
|
||||
#define KEY_MINUS_UNDERSCORE 0x2D
|
||||
#define KEY_EQUAL_PLUS 0x2E
|
||||
#define KEY_OBRACKET_AND_OBRACE 0x2F
|
||||
#define KEY_CBRACKET_AND_CBRACE 0x30
|
||||
#define KEY_BACKSLASH_VERTICAL_BAR 0x31
|
||||
#define KEY_NONUS_NUMBER_SIGN_TILDE 0x32
|
||||
#define KEY_SEMICOLON_COLON 0x33
|
||||
#define KEY_SINGLE_AND_DOUBLE_QUOTE 0x34
|
||||
#define KEY_GRAVE ACCENT AND TILDE 0x35
|
||||
#define KEY_COMMA_AND_LESS 0x36
|
||||
#define KEY_DOT_GREATER 0x37
|
||||
#define KEY_SLASH_QUESTION 0x38
|
||||
#define KEY_CAPS LOCK 0x39
|
||||
#define KEY_F1 0x3A
|
||||
#define KEY_F2 0x3B
|
||||
#define KEY_F3 0x3C
|
||||
#define KEY_F4 0x3D
|
||||
#define KEY_F5 0x3E
|
||||
#define KEY_F6 0x3F
|
||||
#define KEY_F7 0x40
|
||||
#define KEY_F8 0x41
|
||||
#define KEY_F9 0x42
|
||||
#define KEY_F10 0x43
|
||||
#define KEY_F11 0x44
|
||||
#define KEY_F12 0x45
|
||||
#define KEY_PRINTSCREEN 0x46
|
||||
#define KEY_SCROLL LOCK 0x47
|
||||
#define KEY_PAUSE 0x48
|
||||
#define KEY_INSERT 0x49
|
||||
#define KEY_HOME 0x4A
|
||||
#define KEY_PAGEUP 0x4B
|
||||
#define KEY_DELETE 0x4C
|
||||
#define KEY_END1 0x4D
|
||||
#define KEY_PAGEDOWN 0x4E
|
||||
#define KEY_RIGHTARROW 0x4F
|
||||
#define KEY_LEFTARROW 0x50
|
||||
#define KEY_DOWNARROW 0x51
|
||||
#define KEY_UPARROW 0x52
|
||||
#define KEY_KEYPAD_NUM_LOCK_AND_CLEAR 0x53
|
||||
#define KEY_KEYPAD_SLASH 0x54
|
||||
#define KEY_KEYPAD_ASTERIKS 0x55
|
||||
#define KEY_KEYPAD_MINUS 0x56
|
||||
#define KEY_KEYPAD_PLUS 0x57
|
||||
#define KEY_KEYPAD_ENTER 0x58
|
||||
#define KEY_KEYPAD_1_END 0x59
|
||||
#define KEY_KEYPAD_2_DOWN_ARROW 0x5A
|
||||
#define KEY_KEYPAD_3_PAGEDN 0x5B
|
||||
#define KEY_KEYPAD_4_LEFT_ARROW 0x5C
|
||||
#define KEY_KEYPAD_5 0x5D
|
||||
#define KEY_KEYPAD_6_RIGHT_ARROW 0x5E
|
||||
#define KEY_KEYPAD_7_HOME 0x5F
|
||||
#define KEY_KEYPAD_8_UP_ARROW 0x60
|
||||
#define KEY_KEYPAD_9_PAGEUP 0x61
|
||||
#define KEY_KEYPAD_0_INSERT 0x62
|
||||
#define KEY_KEYPAD_DECIMAL_SEPARATOR_DELETE 0x63
|
||||
#define KEY_NONUS_BACK_SLASH_VERTICAL_BAR 0x64
|
||||
#define KEY_APPLICATION 0x65
|
||||
#define KEY_POWER 0x66
|
||||
#define KEY_KEYPAD_EQUAL 0x67
|
||||
#define KEY_F13 0x68
|
||||
#define KEY_F14 0x69
|
||||
#define KEY_F15 0x6A
|
||||
#define KEY_F16 0x6B
|
||||
#define KEY_F17 0x6C
|
||||
#define KEY_F18 0x6D
|
||||
#define KEY_F19 0x6E
|
||||
#define KEY_F20 0x6F
|
||||
#define KEY_F21 0x70
|
||||
#define KEY_F22 0x71
|
||||
#define KEY_F23 0x72
|
||||
#define KEY_F24 0x73
|
||||
#define KEY_EXECUTE 0x74
|
||||
#define KEY_HELP 0x75
|
||||
#define KEY_MENU 0x76
|
||||
#define KEY_SELECT 0x77
|
||||
#define KEY_STOP 0x78
|
||||
#define KEY_AGAIN 0x79
|
||||
#define KEY_UNDO 0x7A
|
||||
#define KEY_CUT 0x7B
|
||||
#define KEY_COPY 0x7C
|
||||
#define KEY_PASTE 0x7D
|
||||
#define KEY_FIND 0x7E
|
||||
#define KEY_MUTE 0x7F
|
||||
#define KEY_VOLUME_UP 0x80
|
||||
#define KEY_VOLUME_DOWN 0x81
|
||||
#define KEY_LOCKING_CAPS_LOCK 0x82
|
||||
#define KEY_LOCKING_NUM_LOCK 0x83
|
||||
#define KEY_LOCKING_SCROLL_LOCK 0x84
|
||||
#define KEY_KEYPAD_COMMA 0x85
|
||||
#define KEY_KEYPAD_EQUAL_SIGN 0x86
|
||||
#define KEY_INTERNATIONAL1 0x87
|
||||
#define KEY_INTERNATIONAL2 0x88
|
||||
#define KEY_INTERNATIONAL3 0x89
|
||||
#define KEY_INTERNATIONAL4 0x8A
|
||||
#define KEY_INTERNATIONAL5 0x8B
|
||||
#define KEY_INTERNATIONAL6 0x8C
|
||||
#define KEY_INTERNATIONAL7 0x8D
|
||||
#define KEY_INTERNATIONAL8 0x8E
|
||||
#define KEY_INTERNATIONAL9 0x8F
|
||||
#define KEY_LANG1 0x90
|
||||
#define KEY_LANG2 0x91
|
||||
#define KEY_LANG3 0x92
|
||||
#define KEY_LANG4 0x93
|
||||
#define KEY_LANG5 0x94
|
||||
#define KEY_LANG6 0x95
|
||||
#define KEY_LANG7 0x96
|
||||
#define KEY_LANG8 0x97
|
||||
#define KEY_LANG9 0x98
|
||||
#define KEY_ALTERNATE_ERASE 0x99
|
||||
#define KEY_SYSREQ 0x9A
|
||||
#define KEY_CANCEL 0x9B
|
||||
#define KEY_CLEAR 0x9C
|
||||
#define KEY_PRIOR 0x9D
|
||||
#define KEY_RETURN 0x9E
|
||||
#define KEY_SEPARATOR 0x9F
|
||||
#define KEY_OUT 0xA0
|
||||
#define KEY_OPER 0xA1
|
||||
#define KEY_CLEAR_AGAIN 0xA2
|
||||
#define KEY_CRSEL 0xA3
|
||||
#define KEY_EXSEL 0xA4
|
||||
#define KEY_KEYPAD_00 0xB0
|
||||
#define KEY_KEYPAD_000 0xB1
|
||||
#define KEY_THOUSANDS_SEPARATOR 0xB2
|
||||
#define KEY_DECIMAL_SEPARATOR 0xB3
|
||||
#define KEY_CURRENCY_UNIT 0xB4
|
||||
#define KEY_CURRENCY_SUB_UNIT 0xB5
|
||||
#define KEY_KEYPAD_OPARENTHESIS 0xB6
|
||||
#define KEY_KEYPAD_CPARENTHESIS 0xB7
|
||||
#define KEY_KEYPAD_OBRACE 0xB8
|
||||
#define KEY_KEYPAD_CBRACE 0xB9
|
||||
#define KEY_KEYPAD_TAB 0xBA
|
||||
#define KEY_KEYPAD_BACKSPACE 0xBB
|
||||
#define KEY_KEYPAD_A 0xBC
|
||||
#define KEY_KEYPAD_B 0xBD
|
||||
#define KEY_KEYPAD_C 0xBE
|
||||
#define KEY_KEYPAD_D 0xBF
|
||||
#define KEY_KEYPAD_E 0xC0
|
||||
#define KEY_KEYPAD_F 0xC1
|
||||
#define KEY_KEYPAD_XOR 0xC2
|
||||
#define KEY_KEYPAD_CARET 0xC3
|
||||
#define KEY_KEYPAD_PERCENT 0xC4
|
||||
#define KEY_KEYPAD_LESS 0xC5
|
||||
#define KEY_KEYPAD_GREATER 0xC6
|
||||
#define KEY_KEYPAD_AMPERSAND 0xC7
|
||||
#define KEY_KEYPAD_LOGICAL_AND 0xC8
|
||||
#define KEY_KEYPAD_VERTICAL_BAR 0xC9
|
||||
#define KEY_KEYPAD_LOGIACL_OR 0xCA
|
||||
#define KEY_KEYPAD_COLON 0xCB
|
||||
#define KEY_KEYPAD_NUMBER_SIGN 0xCC
|
||||
#define KEY_KEYPAD_SPACE 0xCD
|
||||
#define KEY_KEYPAD_AT 0xCE
|
||||
#define KEY_KEYPAD_EXCLAMATION_MARK 0xCF
|
||||
#define KEY_KEYPAD_MEMORY_STORE 0xD0
|
||||
#define KEY_KEYPAD_MEMORY_RECALL 0xD1
|
||||
#define KEY_KEYPAD_MEMORY_CLEAR 0xD2
|
||||
#define KEY_KEYPAD_MEMORY_ADD 0xD3
|
||||
#define KEY_KEYPAD_MEMORY_SUBTRACT 0xD4
|
||||
#define KEY_KEYPAD_MEMORY_MULTIPLY 0xD5
|
||||
#define KEY_KEYPAD_MEMORY_DIVIDE 0xD6
|
||||
#define KEY_KEYPAD_PLUSMINUS 0xD7
|
||||
#define KEY_KEYPAD_CLEAR 0xD8
|
||||
#define KEY_KEYPAD_CLEAR_ENTRY 0xD9
|
||||
#define KEY_KEYPAD_BINARY 0xDA
|
||||
#define KEY_KEYPAD_OCTAL 0xDB
|
||||
#define KEY_KEYPAD_DECIMAL 0xDC
|
||||
#define KEY_KEYPAD_HEXADECIMAL 0xDD
|
||||
#define KEY_LEFTCONTROL 0xE0
|
||||
#define KEY_LEFTSHIFT 0xE1
|
||||
#define KEY_LEFTALT 0xE2
|
||||
#define KEY_LEFT_GUI 0xE3
|
||||
#define KEY_RIGHTCONTROL 0xE4
|
||||
#define KEY_RIGHTSHIFT 0xE5
|
||||
#define KEY_RIGHTALT 0xE6
|
||||
#define KEY_RIGHT_GUI 0xE7
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint8_t state;
|
||||
uint8_t lctrl;
|
||||
uint8_t lshift;
|
||||
uint8_t lalt;
|
||||
uint8_t lgui;
|
||||
uint8_t rctrl;
|
||||
uint8_t rshift;
|
||||
uint8_t ralt;
|
||||
uint8_t rgui;
|
||||
uint8_t keys[6];
|
||||
}
|
||||
HID_KEYBD_Info_TypeDef;
|
||||
|
||||
USBH_StatusTypeDef USBH_HID_KeybdInit(USBH_HandleTypeDef *phost);
|
||||
HID_KEYBD_Info_TypeDef *USBH_HID_GetKeybdInfo(USBH_HandleTypeDef *phost);
|
||||
uint8_t USBH_HID_GetASCIICode(HID_KEYBD_Info_TypeDef *info);
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __USBH_HID_KEYBD_H */
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
|
||||
|
@ -0,0 +1,125 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file usbh_hid_mouse.h
|
||||
* @author MCD Application Team
|
||||
* @version V3.2.2
|
||||
* @date 07-July-2015
|
||||
* @brief This file contains all the prototypes for the usbh_hid_mouse.c
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* <h2><center>© COPYRIGHT 2015 STMicroelectronics</center></h2>
|
||||
*
|
||||
* Licensed under MCD-ST Liberty SW License Agreement V2, (the "License");
|
||||
* You may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at:
|
||||
*
|
||||
* http://www.st.com/software_license_agreement_liberty_v2
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
/* Define to prevent recursive ----------------------------------------------*/
|
||||
#ifndef __USBH_HID_MOUSE_H
|
||||
#define __USBH_HID_MOUSE_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include "usbh_hid.h"
|
||||
|
||||
/** @addtogroup USBH_LIB
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @addtogroup USBH_CLASS
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @addtogroup USBH_HID_CLASS
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @defgroup USBH_HID_MOUSE
|
||||
* @brief This file is the Header file for usbh_hid_mouse.c
|
||||
* @{
|
||||
*/
|
||||
|
||||
|
||||
/** @defgroup USBH_HID_MOUSE_Exported_Types
|
||||
* @{
|
||||
*/
|
||||
|
||||
typedef struct _HID_MOUSE_Info
|
||||
{
|
||||
uint8_t x;
|
||||
uint8_t y;
|
||||
uint8_t buttons[3];
|
||||
}
|
||||
HID_MOUSE_Info_TypeDef;
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @defgroup USBH_HID_MOUSE_Exported_Defines
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @defgroup USBH_HID_MOUSE_Exported_Macros
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @defgroup USBH_HID_MOUSE_Exported_Variables
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @defgroup USBH_HID_MOUSE_Exported_FunctionsPrototype
|
||||
* @{
|
||||
*/
|
||||
USBH_StatusTypeDef USBH_HID_MouseInit(USBH_HandleTypeDef *phost);
|
||||
HID_MOUSE_Info_TypeDef *USBH_HID_GetMouseInfo(USBH_HandleTypeDef *phost);
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __USBH_HID_MOUSE_H */
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
|
@ -0,0 +1,106 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file usbh_hid_parser.c
|
||||
* @author MCD Application Team
|
||||
* @version V3.2.2
|
||||
* @date 07-July-2015
|
||||
* @brief This file is the header file of the usbh_hid_parser.c
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* <h2><center>© COPYRIGHT 2015 STMicroelectronics</center></h2>
|
||||
*
|
||||
* Licensed under MCD-ST Liberty SW License Agreement V2, (the "License");
|
||||
* You may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at:
|
||||
*
|
||||
* http://www.st.com/software_license_agreement_liberty_v2
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
/* Define to prevent recursive -----------------------------------------------*/
|
||||
#ifndef __USBH_HID_PARSER_H
|
||||
#define __USBH_HID_PARSER_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include "usbh_hid.h"
|
||||
#include "usbh_hid_usage.h"
|
||||
|
||||
/** @addtogroup USBH_LIB
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @addtogroup USBH_CLASS
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @addtogroup USBH_HID_CLASS
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @defgroup USBH_HID_PARSER
|
||||
* @brief This file is the Header file for usbh_hid_parser.c
|
||||
* @{
|
||||
*/
|
||||
|
||||
|
||||
/** @defgroup USBH_HID_PARSER_Exported_Types
|
||||
* @{
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
uint8_t *data;
|
||||
uint32_t size;
|
||||
uint8_t shift;
|
||||
uint8_t count;
|
||||
uint8_t sign;
|
||||
uint32_t logical_min; /*min value device can return*/
|
||||
uint32_t logical_max; /*max value device can return*/
|
||||
uint32_t physical_min; /*min vale read can report*/
|
||||
uint32_t physical_max; /*max value read can report*/
|
||||
uint32_t resolution;
|
||||
}
|
||||
HID_Report_ItemTypedef;
|
||||
|
||||
|
||||
uint32_t HID_ReadItem (HID_Report_ItemTypedef *ri, uint8_t ndx);
|
||||
uint32_t HID_WriteItem(HID_Report_ItemTypedef *ri, uint32_t value, uint8_t ndx);
|
||||
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __USBH_HID_PARSER_H */
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
|
@ -0,0 +1,200 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file usbh_hid_usage.c
|
||||
* @author MCD Application Team
|
||||
* @version V3.2.2
|
||||
* @date 07-July-2015
|
||||
* @brief This file contain the USAGE page codes
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* <h2><center>© COPYRIGHT 2015 STMicroelectronics</center></h2>
|
||||
*
|
||||
* Licensed under MCD-ST Liberty SW License Agreement V2, (the "License");
|
||||
* You may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at:
|
||||
*
|
||||
* http://www.st.com/software_license_agreement_liberty_v2
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
/* Define to prevent recursive ----------------------------------------------*/
|
||||
#ifndef __USDH_HID_USAGE_H
|
||||
#define __USDH_HID_USAGE_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/** @addtogroup USBH_LIB
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @addtogroup USBH_CLASS
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @addtogroup USBH_HID_CLASS
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @defgroup USBH_HID_USAGE
|
||||
* @brief This file is the Header file for usbh_hid_usage.c
|
||||
* @{
|
||||
*/
|
||||
|
||||
|
||||
/** @defgroup USBH_HID_USAGE_Exported_Types
|
||||
* @{
|
||||
*/
|
||||
|
||||
/****************************************************/
|
||||
/* HID 1.11 usage pages */
|
||||
/****************************************************/
|
||||
|
||||
#define HID_USAGE_PAGE_UNDEFINED uint16_t (0x00) /* Undefined */
|
||||
/**** Top level pages */
|
||||
#define HID_USAGE_PAGE_GEN_DES uint16_t (0x01) /* Generic Desktop Controls*/
|
||||
#define HID_USAGE_PAGE_SIM_CTR uint16_t (0x02) /* Simulation Controls */
|
||||
#define HID_USAGE_PAGE_VR_CTR uint16_t (0x03) /* VR Controls */
|
||||
#define HID_USAGE_PAGE_SPORT_CTR uint16_t (0x04) /* Sport Controls */
|
||||
#define HID_USAGE_PAGE_GAME_CTR uint16_t (0x05) /* Game Controls */
|
||||
#define HID_USAGE_PAGE_GEN_DEV uint16_t (0x06) /* Generic Device Controls */
|
||||
#define HID_USAGE_PAGE_KEYB uint16_t (0x07) /* Keyboard/Keypad */
|
||||
#define HID_USAGE_PAGE_LED uint16_t (0x08) /* LEDs */
|
||||
#define HID_USAGE_PAGE_BUTTON uint16_t (0x09) /* Button */
|
||||
#define HID_USAGE_PAGE_ORDINAL uint16_t (0x0A) /* Ordinal */
|
||||
#define HID_USAGE_PAGE_PHONE uint16_t (0x0B) /* Telephony */
|
||||
#define HID_USAGE_PAGE_CONSUMER uint16_t (0x0C) /* Consumer */
|
||||
#define HID_USAGE_PAGE_DIGITIZER uint16_t (0x0D) /* Digitizer*/
|
||||
/* 0E Reserved */
|
||||
#define HID_USAGE_PAGE_PID uint16_t (0x0F) /* PID Page (force feedback and related devices) */
|
||||
#define HID_USAGE_PAGE_UNICODE uint16_t (0x10) /* Unicode */
|
||||
/* 11-13 Reserved */
|
||||
#define HID_USAGE_PAGE_ALNUM_DISP uint16_t (0x14) /* Alphanumeric Display */
|
||||
/* 15-1f Reserved */
|
||||
/**** END of top level pages */
|
||||
/* 25-3f Reserved */
|
||||
#define HID_USAGE_PAGE_MEDICAL uint16_t (0x40) /* Medical Instruments */
|
||||
/* 41-7F Reserved */
|
||||
/*80-83 Monitor pages USB Device Class Definition for Monitor Devices
|
||||
84-87 Power pages USB Device Class Definition for Power Devices */
|
||||
/* 88-8B Reserved */
|
||||
#define HID_USAGE_PAGE_BARCODE uint16_t (0x8C) /* Bar Code Scanner page */
|
||||
#define HID_USAGE_PAGE_SCALE uint16_t (0x8D) /* Scale page */
|
||||
#define HID_USAGE_PAGE_MSR uint16_t (0x8E) /* Magnetic Stripe Reading (MSR) Devices */
|
||||
#define HID_USAGE_PAGE_POS uint16_t (0x8F) /* Reserved Point of Sale pages */
|
||||
#define HID_USAGE_PAGE_CAMERA_CTR uint16_t (0x90) /* Camera Control Page */
|
||||
#define HID_USAGE_PAGE_ARCADE uint16_t (0x91) /* Arcade Page */
|
||||
|
||||
/****************************************************/
|
||||
/* Usage definitions for the "Generic Desktop" page */
|
||||
/****************************************************/
|
||||
#define HID_USAGE_UNDEFINED uint16_t (0x00) /* Undefined */
|
||||
#define HID_USAGE_POINTER uint16_t (0x01) /* Pointer (Physical Collection) */
|
||||
#define HID_USAGE_MOUSE uint16_t (0x02) /* Mouse (Application Collection) */
|
||||
/* 03 Reserved */
|
||||
#define HID_USAGE_JOYSTICK uint16_t (0x04) /* Joystick (Application Collection) */
|
||||
#define HID_USAGE_GAMEPAD uint16_t (0x05) /* Game Pad (Application Collection) */
|
||||
#define HID_USAGE_KBD uint16_t (0x06) /* Keyboard (Application Collection) */
|
||||
#define HID_USAGE_KEYPAD uint16_t (0x07) /* Keypad (Application Collection) */
|
||||
#define HID_USAGE_MAX_CTR uint16_t (0x08) /* Multi-axis Controller (Application Collection) */
|
||||
/* 09-2F Reserved */
|
||||
#define HID_USAGE_X uint16_t (0x30) /* X (Dynamic Value) */
|
||||
#define HID_USAGE_Y uint16_t (0x31) /* Y (Dynamic Value) */
|
||||
#define HID_USAGE_Z uint16_t (0x32) /* Z (Dynamic Value) */
|
||||
#define HID_USAGE_RX uint16_t (0x33) /* Rx (Dynamic Value) */
|
||||
#define HID_USAGE_RY uint16_t (0x34) /* Ry (Dynamic Value) */
|
||||
#define HID_USAGE_RZ uint16_t (0x35) /* Rz (Dynamic Value) */
|
||||
#define HID_USAGE_SLIDER uint16_t (0x36) /* Slider (Dynamic Value) */
|
||||
#define HID_USAGE_DIAL uint16_t (0x37) /* Dial (Dynamic Value) */
|
||||
#define HID_USAGE_WHEEL uint16_t (0x38) /* Wheel (Dynamic Value) */
|
||||
#define HID_USAGE_HATSW uint16_t (0x39) /* Hat switch (Dynamic Value) */
|
||||
#define HID_USAGE_COUNTEDBUF uint16_t (0x3A) /* Counted Buffer (Logical Collection) */
|
||||
#define HID_USAGE_BYTECOUNT uint16_t (0x3B) /* Byte Count (Dynamic Value) */
|
||||
#define HID_USAGE_MOTIONWAKE uint16_t (0x3C) /* Motion Wakeup (One Shot Control) */
|
||||
#define HID_USAGE_START uint16_t (0x3D) /* Start (On/Off Control) */
|
||||
#define HID_USAGE_SELECT uint16_t (0x3E) /* Select (On/Off Control) */
|
||||
/* 3F Reserved */
|
||||
#define HID_USAGE_VX uint16_t (0x40) /* Vx (Dynamic Value) */
|
||||
#define HID_USAGE_VY uint16_t (0x41) /* Vy (Dynamic Value) */
|
||||
#define HID_USAGE_VZ uint16_t (0x42) /* Vz (Dynamic Value) */
|
||||
#define HID_USAGE_VBRX uint16_t (0x43) /* Vbrx (Dynamic Value) */
|
||||
#define HID_USAGE_VBRY uint16_t (0x44) /* Vbry (Dynamic Value) */
|
||||
#define HID_USAGE_VBRZ uint16_t (0x45) /* Vbrz (Dynamic Value) */
|
||||
#define HID_USAGE_VNO uint16_t (0x46) /* Vno (Dynamic Value) */
|
||||
#define HID_USAGE_FEATNOTIF uint16_t (0x47) /* Feature Notification (Dynamic Value),(Dynamic Flag) */
|
||||
/* 48-7F Reserved */
|
||||
#define HID_USAGE_SYSCTL uint16_t (0x80) /* System Control (Application Collection) */
|
||||
#define HID_USAGE_PWDOWN uint16_t (0x81) /* System Power Down (One Shot Control) */
|
||||
#define HID_USAGE_SLEEP uint16_t (0x82) /* System Sleep (One Shot Control) */
|
||||
#define HID_USAGE_WAKEUP uint16_t (0x83) /* System Wake Up (One Shot Control) */
|
||||
#define HID_USAGE_CONTEXTM uint16_t (0x84) /* System Context Menu (One Shot Control) */
|
||||
#define HID_USAGE_MAINM uint16_t (0x85) /* System Main Menu (One Shot Control) */
|
||||
#define HID_USAGE_APPM uint16_t (0x86) /* System App Menu (One Shot Control) */
|
||||
#define HID_USAGE_MENUHELP uint16_t (0x87) /* System Menu Help (One Shot Control) */
|
||||
#define HID_USAGE_MENUEXIT uint16_t (0x88) /* System Menu Exit (One Shot Control) */
|
||||
#define HID_USAGE_MENUSELECT uint16_t (0x89) /* System Menu Select (One Shot Control) */
|
||||
#define HID_USAGE_SYSM_RIGHT uint16_t (0x8A) /* System Menu Right (Re-Trigger Control) */
|
||||
#define HID_USAGE_SYSM_LEFT uint16_t (0x8B) /* System Menu Left (Re-Trigger Control) */
|
||||
#define HID_USAGE_SYSM_UP uint16_t (0x8C) /* System Menu Up (Re-Trigger Control) */
|
||||
#define HID_USAGE_SYSM_DOWN uint16_t (0x8D) /* System Menu Down (Re-Trigger Control) */
|
||||
#define HID_USAGE_COLDRESET uint16_t (0x8E) /* System Cold Restart (One Shot Control) */
|
||||
#define HID_USAGE_WARMRESET uint16_t (0x8F) /* System Warm Restart (One Shot Control) */
|
||||
#define HID_USAGE_DUP uint16_t (0x90) /* D-pad Up (On/Off Control) */
|
||||
#define HID_USAGE_DDOWN uint16_t (0x91) /* D-pad Down (On/Off Control) */
|
||||
#define HID_USAGE_DRIGHT uint16_t (0x92) /* D-pad Right (On/Off Control) */
|
||||
#define HID_USAGE_DLEFT uint16_t (0x93) /* D-pad Left (On/Off Control) */
|
||||
/* 94-9F Reserved */
|
||||
#define HID_USAGE_SYS_DOCK uint16_t (0xA0) /* System Dock (One Shot Control) */
|
||||
#define HID_USAGE_SYS_UNDOCK uint16_t (0xA1) /* System Undock (One Shot Control) */
|
||||
#define HID_USAGE_SYS_SETUP uint16_t (0xA2) /* System Setup (One Shot Control) */
|
||||
#define HID_USAGE_SYS_BREAK uint16_t (0xA3) /* System Break (One Shot Control) */
|
||||
#define HID_USAGE_SYS_DBGBRK uint16_t (0xA4) /* System Debugger Break (One Shot Control) */
|
||||
#define HID_USAGE_APP_BRK uint16_t (0xA5) /* Application Break (One Shot Control) */
|
||||
#define HID_USAGE_APP_DBGBRK uint16_t (0xA6) /* Application Debugger Break (One Shot Control) */
|
||||
#define HID_USAGE_SYS_SPKMUTE uint16_t (0xA7) /* System Speaker Mute (One Shot Control) */
|
||||
#define HID_USAGE_SYS_HIBERN uint16_t (0xA8) /* System Hibernate (One Shot Control) */
|
||||
/* A9-AF Reserved */
|
||||
#define HID_USAGE_SYS_SIDPINV uint16_t (0xB0) /* System Display Invert (One Shot Control) */
|
||||
#define HID_USAGE_SYS_DISPINT uint16_t (0xB1) /* System Display Internal (One Shot Control) */
|
||||
#define HID_USAGE_SYS_DISPEXT uint16_t (0xB2) /* System Display External (One Shot Control) */
|
||||
#define HID_USAGE_SYS_DISPBOTH uint16_t (0xB3) /* System Display Both (One Shot Control) */
|
||||
#define HID_USAGE_SYS_DISPDUAL uint16_t (0xB4) /* System Display Dual (One Shot Control) */
|
||||
#define HID_USAGE_SYS_DISPTGLIE uint16_t (0xB5) /* System Display Toggle Int/Ext (One Shot Control) */
|
||||
#define HID_USAGE_SYS_DISP_SWAP uint16_t (0xB6) /* System Display Swap Primary/Secondary (One Shot Control) */
|
||||
#define HID_USAGE_SYS_DIPS_LCDA uint16_t (0xB7) /* System Display LCD Autoscale (One Shot Control) */
|
||||
/* B8-FFFF Reserved */
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __USDH_HID_USAGE_H */
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
|
@ -0,0 +1,850 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file usbh_hid.c
|
||||
* @author MCD Application Team
|
||||
* @version V3.2.2
|
||||
* @date 07-July-2015
|
||||
* @brief This file is the HID Layer Handlers for USB Host HID class.
|
||||
*
|
||||
* @verbatim
|
||||
*
|
||||
* ===================================================================
|
||||
* HID Class Description
|
||||
* ===================================================================
|
||||
* This module manages the HID class V1.11 following the "Device Class Definition
|
||||
* for Human Interface Devices (HID) Version 1.11 Jun 27, 2001".
|
||||
* This driver implements the following aspects of the specification:
|
||||
* - The Boot Interface Subclass
|
||||
* - The Mouse and Keyboard protocols
|
||||
*
|
||||
* @endverbatim
|
||||
*
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* <h2><center>© COPYRIGHT 2015 STMicroelectronics</center></h2>
|
||||
*
|
||||
* Licensed under MCD-ST Liberty SW License Agreement V2, (the "License");
|
||||
* You may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at:
|
||||
*
|
||||
* http://www.st.com/software_license_agreement_liberty_v2
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
******************************************************************************
|
||||
*
|
||||
* Modifications by Robert Fisk
|
||||
*/
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include "usbh_hid.h"
|
||||
#include "build_config.h"
|
||||
|
||||
|
||||
#if defined (CONFIG_KEYBOARD_ENABLED) || defined (CONFIG_MOUSE_ENABLED)
|
||||
|
||||
/** @addtogroup USBH_LIB
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @addtogroup USBH_CLASS
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @addtogroup USBH_HID_CLASS
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @defgroup USBH_HID_CORE
|
||||
* @brief This file includes HID Layer Handlers for USB Host HID class.
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @defgroup USBH_HID_CORE_Private_TypesDefinitions
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
|
||||
/** @defgroup USBH_HID_CORE_Private_Defines
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
|
||||
/** @defgroup USBH_HID_CORE_Private_Macros
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
|
||||
/** @defgroup USBH_HID_CORE_Private_Variables
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
|
||||
/** @defgroup USBH_HID_CORE_Private_FunctionPrototypes
|
||||
* @{
|
||||
*/
|
||||
|
||||
static USBH_StatusTypeDef USBH_HID_InterfaceInit (USBH_HandleTypeDef *phost);
|
||||
static USBH_StatusTypeDef USBH_HID_InterfaceDeInit (USBH_HandleTypeDef *phost);
|
||||
static USBH_StatusTypeDef USBH_HID_ClassRequest(USBH_HandleTypeDef *phost);
|
||||
static USBH_StatusTypeDef USBH_HID_Process(USBH_HandleTypeDef *phost);
|
||||
static USBH_StatusTypeDef USBH_HID_SOFProcess(USBH_HandleTypeDef *phost);
|
||||
static void USBH_HID_ParseHIDDesc (HID_DescTypeDef *desc, uint8_t *buf);
|
||||
|
||||
|
||||
USBH_ClassTypeDef HID_Class =
|
||||
{
|
||||
"HID",
|
||||
USB_HID_CLASS,
|
||||
USBH_HID_InterfaceInit,
|
||||
USBH_HID_InterfaceDeInit,
|
||||
USBH_HID_ClassRequest,
|
||||
USBH_HID_Process,
|
||||
USBH_HID_SOFProcess,
|
||||
NULL,
|
||||
};
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
|
||||
/** @defgroup USBH_HID_CORE_Private_Functions
|
||||
* @{
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* @brief USBH_HID_InterfaceInit
|
||||
* The function init the HID class.
|
||||
* @param phost: Host handle
|
||||
* @retval USBH Status
|
||||
*/
|
||||
static USBH_StatusTypeDef USBH_HID_InterfaceInit (USBH_HandleTypeDef *phost)
|
||||
{
|
||||
uint8_t max_ep;
|
||||
uint8_t num = 0;
|
||||
uint8_t interface = 0xFF;
|
||||
|
||||
HID_HandleTypeDef *HID_Handle;
|
||||
|
||||
|
||||
#ifdef CONFIG_MOUSE_ENABLED
|
||||
interface = USBH_FindInterface(phost, phost->pActiveClass->ClassCode, HID_BOOT_CODE, HID_MOUSE_PROTOCOL); //Search for mouse interfaces first
|
||||
#endif
|
||||
#ifdef CONFIG_KEYBOARD_ENABLED
|
||||
if (interface == 0xFF)
|
||||
{
|
||||
interface = USBH_FindInterface(phost, phost->pActiveClass->ClassCode, HID_BOOT_CODE, HID_KEYBRD_PROTOCOL);
|
||||
}
|
||||
#endif
|
||||
|
||||
if(interface == 0xFF) /* No Valid Interface */
|
||||
{
|
||||
USBH_DbgLog ("Cannot Find the interface for %s class.", phost->pActiveClass->Name);
|
||||
return USBH_FAIL;
|
||||
}
|
||||
|
||||
USBH_SelectInterface (phost, interface);
|
||||
phost->pActiveClass->pData = (HID_HandleTypeDef *)USBH_malloc (sizeof(HID_HandleTypeDef));
|
||||
HID_Handle = (HID_HandleTypeDef *) phost->pActiveClass->pData;
|
||||
|
||||
HID_Handle->state = HID_INIT;
|
||||
HID_Handle->ctl_state = HID_REQ_INIT;
|
||||
HID_Handle->ep_addr = phost->device.CfgDesc.Itf_Desc[phost->device.current_interface].Ep_Desc[0].bEndpointAddress;
|
||||
HID_Handle->length = phost->device.CfgDesc.Itf_Desc[phost->device.current_interface].Ep_Desc[0].wMaxPacketSize;
|
||||
HID_Handle->poll = phost->device.CfgDesc.Itf_Desc[phost->device.current_interface].Ep_Desc[0].bInterval;
|
||||
HID_Handle->Protocol = phost->device.CfgDesc.Itf_Desc[phost->device.current_interface].bInterfaceProtocol;
|
||||
|
||||
if (HID_Handle->poll < HID_MIN_POLL) HID_Handle->poll = HID_MIN_POLL;
|
||||
if (HID_Handle->length > HID_REPORT_BUFFER_SIZE) return USBH_FAIL; //Some mechanical keyboards need to send > 8 byte packets
|
||||
|
||||
/* Check fo available number of endpoints */
|
||||
/* Find the number of EPs in the Interface Descriptor */
|
||||
/* Choose the lower number in order not to overrun the buffer allocated */
|
||||
max_ep = ( (phost->device.CfgDesc.Itf_Desc[phost->device.current_interface].bNumEndpoints <= USBH_MAX_NUM_ENDPOINTS) ?
|
||||
phost->device.CfgDesc.Itf_Desc[phost->device.current_interface].bNumEndpoints :
|
||||
USBH_MAX_NUM_ENDPOINTS);
|
||||
|
||||
|
||||
/* Decode endpoint IN and OUT address from interface descriptor */
|
||||
for ( ;num < max_ep; num++)
|
||||
{
|
||||
if(phost->device.CfgDesc.Itf_Desc[phost->device.current_interface].Ep_Desc[num].bEndpointAddress & 0x80)
|
||||
{
|
||||
HID_Handle->InEp = (phost->device.CfgDesc.Itf_Desc[phost->device.current_interface].Ep_Desc[num].bEndpointAddress);
|
||||
HID_Handle->InPipe =\
|
||||
USBH_AllocPipe(phost, HID_Handle->InEp);
|
||||
|
||||
/* Open pipe for IN endpoint */
|
||||
USBH_OpenPipe (phost,
|
||||
HID_Handle->InPipe,
|
||||
HID_Handle->InEp,
|
||||
phost->device.address,
|
||||
phost->device.speed,
|
||||
USB_EP_TYPE_INTR,
|
||||
HID_Handle->length);
|
||||
|
||||
USBH_LL_SetToggle (phost, HID_Handle->InPipe, 0);
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
HID_Handle->OutEp = (phost->device.CfgDesc.Itf_Desc[phost->device.current_interface].Ep_Desc[num].bEndpointAddress);
|
||||
HID_Handle->OutPipe =\
|
||||
USBH_AllocPipe(phost, HID_Handle->OutEp);
|
||||
|
||||
/* Open pipe for OUT endpoint */
|
||||
USBH_OpenPipe (phost,
|
||||
HID_Handle->OutPipe,
|
||||
HID_Handle->OutEp,
|
||||
phost->device.address,
|
||||
phost->device.speed,
|
||||
USB_EP_TYPE_INTR,
|
||||
HID_Handle->length);
|
||||
|
||||
USBH_LL_SetToggle (phost, HID_Handle->OutPipe, 0);
|
||||
}
|
||||
|
||||
}
|
||||
return USBH_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief USBH_HID_InterfaceDeInit
|
||||
* The function DeInit the Pipes used for the HID class.
|
||||
* @param phost: Host handle
|
||||
* @retval USBH Status
|
||||
*/
|
||||
USBH_StatusTypeDef USBH_HID_InterfaceDeInit (USBH_HandleTypeDef *phost )
|
||||
{
|
||||
HID_HandleTypeDef *HID_Handle = (HID_HandleTypeDef *) phost->pActiveClass->pData;
|
||||
|
||||
if(HID_Handle->InPipe != 0x00)
|
||||
{
|
||||
USBH_ClosePipe (phost, HID_Handle->InPipe);
|
||||
USBH_FreePipe (phost, HID_Handle->InPipe);
|
||||
HID_Handle->InPipe = 0; /* Reset the pipe as Free */
|
||||
}
|
||||
|
||||
if(HID_Handle->OutPipe != 0x00)
|
||||
{
|
||||
USBH_ClosePipe(phost, HID_Handle->OutPipe);
|
||||
USBH_FreePipe (phost, HID_Handle->OutPipe);
|
||||
HID_Handle->OutPipe = 0; /* Reset the pipe as Free */
|
||||
}
|
||||
|
||||
if(phost->pActiveClass->pData)
|
||||
{
|
||||
USBH_free (phost->pActiveClass->pData);
|
||||
}
|
||||
|
||||
return USBH_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief USBH_HID_ClassRequest
|
||||
* The function is responsible for handling Standard requests
|
||||
* for HID class.
|
||||
* @param phost: Host handle
|
||||
* @retval USBH Status
|
||||
*/
|
||||
static USBH_StatusTypeDef USBH_HID_ClassRequest(USBH_HandleTypeDef *phost)
|
||||
{
|
||||
|
||||
USBH_StatusTypeDef status = USBH_BUSY;
|
||||
USBH_StatusTypeDef classReqStatus = USBH_BUSY;
|
||||
HID_HandleTypeDef *HID_Handle = (HID_HandleTypeDef *) phost->pActiveClass->pData;
|
||||
|
||||
/* Switch HID state machine */
|
||||
switch (HID_Handle->ctl_state)
|
||||
{
|
||||
case HID_REQ_INIT:
|
||||
case HID_REQ_GET_HID_DESC:
|
||||
|
||||
/* Get HID Desc */
|
||||
if (USBH_HID_GetHIDDescriptor (phost, USB_HID_DESC_SIZE)== USBH_OK)
|
||||
{
|
||||
|
||||
USBH_HID_ParseHIDDesc(&HID_Handle->HID_Desc, phost->device.Data);
|
||||
HID_Handle->ctl_state = HID_REQ_GET_REPORT_DESC;
|
||||
}
|
||||
|
||||
break;
|
||||
case HID_REQ_GET_REPORT_DESC:
|
||||
/* Get Report Desc */
|
||||
if (USBH_HID_GetHIDReportDescriptor(phost, HID_Handle->HID_Desc.wItemLength) == USBH_OK)
|
||||
{
|
||||
/* The descriptor is available in phost->device.Data */
|
||||
HID_Handle->ctl_state = HID_REQ_SET_IDLE;
|
||||
}
|
||||
break;
|
||||
|
||||
case HID_REQ_SET_IDLE:
|
||||
classReqStatus = USBH_HID_SetIdle (phost, 0, 0);
|
||||
|
||||
/* set Idle */
|
||||
if (classReqStatus == USBH_OK)
|
||||
{
|
||||
HID_Handle->ctl_state = HID_REQ_SET_PROTOCOL;
|
||||
}
|
||||
else if(classReqStatus == USBH_NOT_SUPPORTED)
|
||||
{
|
||||
HID_Handle->ctl_state = HID_REQ_SET_PROTOCOL;
|
||||
}
|
||||
break;
|
||||
|
||||
case HID_REQ_SET_PROTOCOL:
|
||||
//Mouse in 'report' mode,
|
||||
//Keyboard in 'boot' mode
|
||||
if (USBH_HID_SetProtocol(phost,
|
||||
(HID_Handle->Protocol == HID_MOUSE_PROTOCOL ? 1 : 0)) == USBH_OK)
|
||||
{
|
||||
HID_Handle->ctl_state = HID_REQ_IDLE;
|
||||
|
||||
/* all requests performed*/
|
||||
phost->pUser(phost, HOST_USER_CLASS_ACTIVE);
|
||||
status = USBH_OK;
|
||||
}
|
||||
break;
|
||||
|
||||
case HID_REQ_IDLE:
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief USBH_HID_Process
|
||||
* The function is for managing state machine for HID data transfers
|
||||
* @param phost: Host handle
|
||||
* @retval USBH Status
|
||||
*/
|
||||
static USBH_StatusTypeDef USBH_HID_Process(USBH_HandleTypeDef *phost)
|
||||
{
|
||||
USBH_URBStateTypeDef urbStatus;
|
||||
HID_HandleTypeDef *HID_Handle = (HID_HandleTypeDef *) phost->pActiveClass->pData;
|
||||
|
||||
switch (HID_Handle->state)
|
||||
{
|
||||
case HID_INIT:
|
||||
HID_Handle->timer = phost->Timer;
|
||||
HID_Handle->state = HID_IDLE;
|
||||
break;
|
||||
|
||||
case HID_IDLE:
|
||||
break;
|
||||
|
||||
case HID_GET_DATA:
|
||||
if ((int32_t)(phost->Timer - HID_Handle->timer) >= HID_Handle->poll)
|
||||
{
|
||||
USBH_InterruptReceiveData(phost,
|
||||
HID_Handle->Data,
|
||||
HID_Handle->length,
|
||||
HID_Handle->InPipe);
|
||||
HID_Handle->state = HID_GET_POLL;
|
||||
HID_Handle->timer = phost->Timer;
|
||||
}
|
||||
break;
|
||||
|
||||
case HID_GET_POLL:
|
||||
urbStatus = USBH_LL_GetURBState(phost, HID_Handle->InPipe);
|
||||
|
||||
if (urbStatus == USBH_URB_DONE)
|
||||
{
|
||||
HID_Handle->ReportCallback(USBH_OK);
|
||||
HID_Handle->state = HID_IDLE;
|
||||
break;
|
||||
}
|
||||
|
||||
if (urbStatus == USBH_URB_NOTREADY)
|
||||
{
|
||||
HID_Handle->ReportCallback(USBH_BUSY);
|
||||
HID_Handle->state = HID_IDLE;
|
||||
break;
|
||||
}
|
||||
|
||||
if (urbStatus == USBH_URB_STALL)
|
||||
{
|
||||
/* Issue Clear Feature on interrupt IN endpoint */
|
||||
if(USBH_ClrFeature(phost,
|
||||
HID_Handle->ep_addr) == USBH_OK)
|
||||
{
|
||||
HID_Handle->ReportCallback(USBH_BUSY);
|
||||
HID_Handle->state = HID_IDLE;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case HID_SET_DATA_POLL:
|
||||
if (USBH_CtlReq(phost, HID_Handle->Data, phost->Control.setup.b.wLength.w) == USBH_OK)
|
||||
{
|
||||
HID_Handle->ReportCallback(USBH_OK);
|
||||
HID_Handle->state = HID_IDLE;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return USBH_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief USBH_HID_SOFProcess
|
||||
* The function is for managing the SOF Process
|
||||
* @param phost: Host handle
|
||||
* @retval USBH Status
|
||||
*/
|
||||
static USBH_StatusTypeDef USBH_HID_SOFProcess(USBH_HandleTypeDef *phost)
|
||||
{
|
||||
|
||||
return USBH_OK;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//Downstream_HID calls into here at main() priority,
|
||||
//to request a new report for Upstream.
|
||||
HAL_StatusTypeDef USBH_HID_GetInterruptReport(USBH_HandleTypeDef *phost,
|
||||
TransactionCompleteCallbackTypeDef callback)
|
||||
{
|
||||
HID_HandleTypeDef *HID_Handle = (HID_HandleTypeDef *) phost->pActiveClass->pData;
|
||||
|
||||
if (HID_Handle->state == HID_IDLE)
|
||||
{
|
||||
HID_Handle->ReportCallback = callback;
|
||||
HID_Handle->state = HID_GET_DATA;
|
||||
return HAL_OK;
|
||||
}
|
||||
|
||||
//return HAL_ERROR;
|
||||
while (1);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @brief USBH_Get_HID_ReportDescriptor
|
||||
* Issue report Descriptor command to the device. Once the response
|
||||
* received, parse the report descriptor and update the status.
|
||||
* @param phost: Host handle
|
||||
* @param Length : HID Report Descriptor Length
|
||||
* @retval USBH Status
|
||||
*/
|
||||
USBH_StatusTypeDef USBH_HID_GetHIDReportDescriptor (USBH_HandleTypeDef *phost,
|
||||
uint16_t length)
|
||||
{
|
||||
|
||||
USBH_StatusTypeDef status;
|
||||
|
||||
if (length > USBH_MAX_DATA_BUFFER)
|
||||
{
|
||||
length = USBH_MAX_DATA_BUFFER;
|
||||
}
|
||||
|
||||
status = USBH_GetDescriptor(phost,
|
||||
USB_REQ_RECIPIENT_INTERFACE | USB_REQ_TYPE_STANDARD,
|
||||
USB_DESC_HID_REPORT,
|
||||
phost->device.current_interface,
|
||||
phost->device.Data,
|
||||
length);
|
||||
|
||||
/* HID report descriptor is available in phost->device.Data.
|
||||
In case of USB Boot Mode devices for In report handling ,
|
||||
HID report descriptor parsing is not required.
|
||||
In case, for supporting Non-Boot Protocol devices and output reports,
|
||||
user may parse the report descriptor*/
|
||||
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief USBH_Get_HID_Descriptor
|
||||
* Issue HID Descriptor command to the device. Once the response
|
||||
* received, parse the report descriptor and update the status.
|
||||
* @param phost: Host handle
|
||||
* @param Length : HID Descriptor Length
|
||||
* @retval USBH Status
|
||||
*/
|
||||
USBH_StatusTypeDef USBH_HID_GetHIDDescriptor (USBH_HandleTypeDef *phost,
|
||||
uint16_t length)
|
||||
{
|
||||
|
||||
USBH_StatusTypeDef status;
|
||||
|
||||
if (length > USBH_MAX_DATA_BUFFER)
|
||||
{
|
||||
length = USBH_MAX_DATA_BUFFER;
|
||||
}
|
||||
|
||||
status = USBH_GetDescriptor( phost,
|
||||
USB_REQ_RECIPIENT_INTERFACE | USB_REQ_TYPE_STANDARD,
|
||||
USB_DESC_HID,
|
||||
phost->device.current_interface,
|
||||
phost->device.Data,
|
||||
length);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief USBH_Set_Idle
|
||||
* Set Idle State.
|
||||
* @param phost: Host handle
|
||||
* @param duration: Duration for HID Idle request
|
||||
* @param reportId : Targeted report ID for Set Idle request
|
||||
* @retval USBH Status
|
||||
*/
|
||||
USBH_StatusTypeDef USBH_HID_SetIdle (USBH_HandleTypeDef *phost,
|
||||
uint8_t duration,
|
||||
uint8_t reportId)
|
||||
{
|
||||
if (phost->RequestState == CMD_SEND)
|
||||
{
|
||||
phost->Control.setup.b.bmRequestType = USB_H2D |
|
||||
USB_REQ_RECIPIENT_INTERFACE |
|
||||
USB_REQ_TYPE_CLASS;
|
||||
|
||||
phost->Control.setup.b.bRequest = USB_HID_SET_IDLE;
|
||||
phost->Control.setup.b.wValue.w = (duration << 8 ) | reportId;
|
||||
|
||||
phost->Control.setup.b.wIndex.w = 0;
|
||||
phost->Control.setup.b.wLength.w = 0;
|
||||
}
|
||||
|
||||
return USBH_CtlReq(phost, 0 , 0 );
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief USBH_HID_Set_Report
|
||||
* Issues Set Report
|
||||
* @param phost: Host handle
|
||||
* @param reportType : Report type to be sent
|
||||
* @param reportId : Targeted report ID for Set Report request
|
||||
* @param reportBuff : Report Buffer
|
||||
* @param reportLen : Length of data report to be send
|
||||
* @retval USBH Status
|
||||
*/
|
||||
USBH_StatusTypeDef USBH_HID_SetReport (USBH_HandleTypeDef *phost,
|
||||
uint8_t reportType,
|
||||
uint8_t reportId,
|
||||
uint8_t* reportBuff,
|
||||
uint8_t reportLen,
|
||||
TransactionCompleteCallbackTypeDef callback)
|
||||
{
|
||||
HID_HandleTypeDef *HID_Handle = (HID_HandleTypeDef *) phost->pActiveClass->pData;
|
||||
uint32_t i;
|
||||
|
||||
if (phost->RequestState == CMD_SEND)
|
||||
{
|
||||
if ((HID_Handle->state != HID_IDLE) ||
|
||||
(reportLen > HID_MAX_REPORT_SIZE))
|
||||
{
|
||||
while (1);
|
||||
}
|
||||
|
||||
HID_Handle->ReportCallback = callback;
|
||||
HID_Handle->state = HID_SET_DATA_POLL;
|
||||
for (i = 0; i < reportLen; i++)
|
||||
{
|
||||
HID_Handle->Data[i] = *reportBuff;
|
||||
reportBuff++;
|
||||
}
|
||||
|
||||
phost->Control.setup.b.bmRequestType = USB_H2D |
|
||||
USB_REQ_RECIPIENT_INTERFACE |
|
||||
USB_REQ_TYPE_CLASS;
|
||||
|
||||
phost->Control.setup.b.bRequest = USB_HID_SET_REPORT;
|
||||
phost->Control.setup.b.wValue.w = (reportType << 8 ) | reportId;
|
||||
|
||||
phost->Control.setup.b.wIndex.w = 0;
|
||||
phost->Control.setup.b.wLength.w = reportLen;
|
||||
}
|
||||
|
||||
//return USBH_CtlReq(phost, reportBuff, reportLen);
|
||||
return USBH_OK;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief USBH_HID_GetReport
|
||||
* retreive Set Report
|
||||
* @param phost: Host handle
|
||||
* @param reportType : Report type to be sent
|
||||
* @param reportId : Targeted report ID for Set Report request
|
||||
* @param reportBuff : Report Buffer
|
||||
* @param reportLen : Length of data report to be send
|
||||
* @retval USBH Status
|
||||
*/
|
||||
USBH_StatusTypeDef USBH_HID_GetReport (USBH_HandleTypeDef *phost,
|
||||
uint8_t reportType,
|
||||
uint8_t reportId,
|
||||
uint8_t* reportBuff,
|
||||
uint8_t reportLen)
|
||||
{
|
||||
if (phost->RequestState == CMD_SEND)
|
||||
{
|
||||
phost->Control.setup.b.bmRequestType = USB_D2H |
|
||||
USB_REQ_RECIPIENT_INTERFACE |
|
||||
USB_REQ_TYPE_CLASS;
|
||||
|
||||
phost->Control.setup.b.bRequest = USB_HID_GET_REPORT;
|
||||
phost->Control.setup.b.wValue.w = (reportType << 8 ) | reportId;
|
||||
|
||||
phost->Control.setup.b.wIndex.w = 0;
|
||||
phost->Control.setup.b.wLength.w = reportLen;
|
||||
}
|
||||
|
||||
return USBH_CtlReq(phost, reportBuff , reportLen );
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief USBH_Set_Protocol
|
||||
* Set protocol State.
|
||||
* @param phost: Host handle
|
||||
* @param protocol : Set Protocol for HID : boot/report protocol
|
||||
* @retval USBH Status
|
||||
*/
|
||||
USBH_StatusTypeDef USBH_HID_SetProtocol(USBH_HandleTypeDef *phost,
|
||||
uint8_t protocol)
|
||||
{
|
||||
if (phost->RequestState == CMD_SEND)
|
||||
{
|
||||
phost->Control.setup.b.bmRequestType = USB_H2D |
|
||||
USB_REQ_RECIPIENT_INTERFACE |\
|
||||
USB_REQ_TYPE_CLASS;
|
||||
|
||||
phost->Control.setup.b.bRequest = USB_HID_SET_PROTOCOL;
|
||||
phost->Control.setup.b.wValue.w = protocol == 0 ? 0 : 1;
|
||||
phost->Control.setup.b.wIndex.w = 0;
|
||||
phost->Control.setup.b.wLength.w = 0;
|
||||
}
|
||||
|
||||
return USBH_CtlReq(phost, 0 , 0 );
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief USBH_ParseHIDDesc
|
||||
* This function Parse the HID descriptor
|
||||
* @param desc: HID Descriptor
|
||||
* @param buf: Buffer where the source descriptor is available
|
||||
* @retval None
|
||||
*/
|
||||
static void USBH_HID_ParseHIDDesc (HID_DescTypeDef *desc, uint8_t *buf)
|
||||
{
|
||||
|
||||
desc->bLength = *(uint8_t *) (buf + 0);
|
||||
desc->bDescriptorType = *(uint8_t *) (buf + 1);
|
||||
desc->bcdHID = LE16 (buf + 2);
|
||||
desc->bCountryCode = *(uint8_t *) (buf + 4);
|
||||
desc->bNumDescriptors = *(uint8_t *) (buf + 5);
|
||||
desc->bReportDescriptorType = *(uint8_t *) (buf + 6);
|
||||
desc->wItemLength = LE16 (buf + 7);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief USBH_HID_GetDeviceType
|
||||
* Return Device function.
|
||||
* @param phost: Host handle
|
||||
* @retval HID function: HID_MOUSE / HID_KEYBOARD
|
||||
*/
|
||||
HID_TypeTypeDef USBH_HID_GetDeviceType(USBH_HandleTypeDef *phost)
|
||||
{
|
||||
HID_TypeTypeDef type = HID_UNKNOWN;
|
||||
|
||||
if(phost->gState == HOST_CLASS)
|
||||
{
|
||||
|
||||
if(phost->device.CfgDesc.Itf_Desc[phost->device.current_interface].bInterfaceProtocol \
|
||||
== HID_KEYBRD_PROTOCOL)
|
||||
{
|
||||
type = HID_KEYBOARD;
|
||||
}
|
||||
else if(phost->device.CfgDesc.Itf_Desc[phost->device.current_interface].bInterfaceProtocol \
|
||||
== HID_MOUSE_PROTOCOL)
|
||||
{
|
||||
type= HID_MOUSE;
|
||||
}
|
||||
}
|
||||
return type;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief USBH_HID_GetPollInterval
|
||||
* Return HID device poll time
|
||||
* @param phost: Host handle
|
||||
* @retval poll time (ms)
|
||||
*/
|
||||
uint8_t USBH_HID_GetPollInterval(USBH_HandleTypeDef *phost)
|
||||
{
|
||||
HID_HandleTypeDef *HID_Handle = (HID_HandleTypeDef *) phost->pActiveClass->pData;
|
||||
|
||||
if((phost->gState == HOST_CLASS_REQUEST) ||
|
||||
(phost->gState == HOST_INPUT) ||
|
||||
(phost->gState == HOST_SET_CONFIGURATION) ||
|
||||
(phost->gState == HOST_CHECK_CLASS) ||
|
||||
((phost->gState == HOST_CLASS)))
|
||||
{
|
||||
return (HID_Handle->poll);
|
||||
}
|
||||
else
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* @brief fifo_init
|
||||
* Initialize FIFO.
|
||||
* @param f: Fifo address
|
||||
* @param buf: Fifo buffer
|
||||
* @param size: Fifo Size
|
||||
* @retval none
|
||||
*/
|
||||
void fifo_init(FIFO_TypeDef * f, uint8_t * buf, uint16_t size)
|
||||
{
|
||||
f->head = 0;
|
||||
f->tail = 0;
|
||||
f->lock = 0;
|
||||
f->size = size;
|
||||
f->buf = buf;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief fifo_read
|
||||
* Read from FIFO.
|
||||
* @param f: Fifo address
|
||||
* @param buf: read buffer
|
||||
* @param nbytes: number of item to read
|
||||
* @retval number of read items
|
||||
*/
|
||||
uint16_t fifo_read(FIFO_TypeDef * f, void * buf, uint16_t nbytes)
|
||||
{
|
||||
uint16_t i;
|
||||
uint8_t * p;
|
||||
p = (uint8_t*) buf;
|
||||
|
||||
if(f->lock == 0)
|
||||
{
|
||||
f->lock = 1;
|
||||
for(i=0; i < nbytes; i++)
|
||||
{
|
||||
if( f->tail != f->head )
|
||||
{
|
||||
*p++ = f->buf[f->tail];
|
||||
f->tail++;
|
||||
if( f->tail == f->size )
|
||||
{
|
||||
f->tail = 0;
|
||||
}
|
||||
} else
|
||||
{
|
||||
f->lock = 0;
|
||||
return i;
|
||||
}
|
||||
}
|
||||
}
|
||||
f->lock = 0;
|
||||
return nbytes;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief fifo_write
|
||||
* Read from FIFO.
|
||||
* @param f: Fifo address
|
||||
* @param buf: read buffer
|
||||
* @param nbytes: number of item to write
|
||||
* @retval number of written items
|
||||
*/
|
||||
uint16_t fifo_write(FIFO_TypeDef * f, const void * buf, uint16_t nbytes)
|
||||
{
|
||||
uint16_t i;
|
||||
const uint8_t * p;
|
||||
p = (const uint8_t*) buf;
|
||||
if(f->lock == 0)
|
||||
{
|
||||
f->lock = 1;
|
||||
for(i=0; i < nbytes; i++)
|
||||
{
|
||||
if( (f->head + 1 == f->tail) ||
|
||||
( (f->head + 1 == f->size) && (f->tail == 0)) )
|
||||
{
|
||||
f->lock = 0;
|
||||
return i;
|
||||
}
|
||||
else
|
||||
{
|
||||
f->buf[f->head] = *p++;
|
||||
f->head++;
|
||||
if( f->head == f->size )
|
||||
{
|
||||
f->head = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
f->lock = 0;
|
||||
return nbytes;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief The function is a callback about HID Data events
|
||||
* @param phost: Selected device
|
||||
* @retval None
|
||||
*/
|
||||
__weak void USBH_HID_EventCallback(USBH_HandleTypeDef *phost)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
#endif //#if defined (CONFIG_KEYBOARD_ENABLED) || defined (CONFIG_MOUSE_ENABLED)
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
|
@ -0,0 +1,241 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file usbh_msc.h
|
||||
* @author MCD Application Team
|
||||
* @version V3.2.1
|
||||
* @date 26-June-2015
|
||||
* @brief This file contains all the prototypes for the usbh_msc.c
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* <h2><center>© COPYRIGHT 2015 STMicroelectronics</center></h2>
|
||||
*
|
||||
* Licensed under MCD-ST Liberty SW License Agreement V2, (the "License");
|
||||
* You may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at:
|
||||
*
|
||||
* http://www.st.com/software_license_agreement_liberty_v2
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
******************************************************************************
|
||||
*
|
||||
* Modifications by Robert Fisk
|
||||
*/
|
||||
|
||||
|
||||
/* Define to prevent recursive ----------------------------------------------*/
|
||||
#ifndef __USBH_MSC_H
|
||||
#define __USBH_MSC_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include "usbh_core.h"
|
||||
#include "usbh_msc_bot.h"
|
||||
#include "usbh_msc_scsi.h"
|
||||
|
||||
|
||||
|
||||
|
||||
typedef enum
|
||||
{
|
||||
MSC_INIT = 0,
|
||||
MSC_IDLE,
|
||||
MSC_TEST_UNIT_READY,
|
||||
MSC_READ_CAPACITY10,
|
||||
MSC_READ_INQUIRY,
|
||||
MSC_REQUEST_SENSE,
|
||||
MSC_REQUEST_SENSE_WAIT_RETRY,
|
||||
MSC_READ,
|
||||
MSC_WRITE,
|
||||
MSC_UNRECOVERED_ERROR,
|
||||
MSC_START_STOP,
|
||||
}
|
||||
MSC_StateTypeDef;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
MSC_OK,
|
||||
MSC_NOT_READY,
|
||||
MSC_ERROR,
|
||||
|
||||
}
|
||||
MSC_ErrorTypeDef;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
MSC_REQ_IDLE = 0,
|
||||
MSC_REQ_STARTUP_DELAY,
|
||||
MSC_REQ_GET_MAX_LUN,
|
||||
MSC_REQ_RESET,
|
||||
MSC_REQ_ERROR,
|
||||
}
|
||||
MSC_ReqStateTypeDef;
|
||||
|
||||
#ifndef MAX_SUPPORTED_LUN
|
||||
#define MAX_SUPPORTED_LUN 2
|
||||
#endif
|
||||
|
||||
|
||||
/* Structure for LUN */
|
||||
typedef struct
|
||||
{
|
||||
MSC_StateTypeDef state;
|
||||
MSC_ErrorTypeDef error;
|
||||
USBH_StatusTypeDef prev_ready_state;
|
||||
SCSI_CapacityTypeDef capacity;
|
||||
SCSI_SenseTypeDef sense;
|
||||
SCSI_StdInquiryDataTypeDef inquiry;
|
||||
uint8_t state_changed;
|
||||
|
||||
}
|
||||
MSC_LUNTypeDef;
|
||||
|
||||
|
||||
typedef void (*MSC_CmdCompleteCallback)(USBH_StatusTypeDef result);
|
||||
|
||||
/* Structure for MSC process */
|
||||
typedef struct _MSC_Process
|
||||
{
|
||||
uint32_t max_lun;
|
||||
uint8_t InPipe;
|
||||
uint8_t OutPipe;
|
||||
uint8_t OutEp;
|
||||
uint8_t InEp;
|
||||
uint16_t OutEpSize;
|
||||
uint16_t InEpSize;
|
||||
MSC_StateTypeDef state;
|
||||
MSC_ErrorTypeDef error;
|
||||
MSC_ReqStateTypeDef req_state;
|
||||
MSC_ReqStateTypeDef prev_req_state;
|
||||
BOT_HandleTypeDef hbot;
|
||||
MSC_LUNTypeDef unit[MAX_SUPPORTED_LUN];
|
||||
uint16_t current_lun;
|
||||
uint16_t rw_lun;
|
||||
uint32_t timeout;
|
||||
uint32_t retry_timeout;
|
||||
MSC_CmdCompleteCallback CmdCompleteCallback;
|
||||
}
|
||||
MSC_HandleTypeDef;
|
||||
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
|
||||
|
||||
/** @defgroup USBH_MSC_CORE_Exported_Defines
|
||||
* @{
|
||||
*/
|
||||
|
||||
#define USB_REQ_BOT_RESET 0xFF
|
||||
#define USB_REQ_GET_MAX_LUN 0xFE
|
||||
|
||||
#define MSC_TIMEOUT_FIXED_MS 10000 //Some flash drives take 2 seconds to write a single block!
|
||||
#define MSC_SAMSUNG_STARTUP_DELAY_MS 100 //Samsung FIT Plus 32GB USB 3.1 flash drive was here
|
||||
|
||||
/* MSC Class Codes */
|
||||
#define USB_MSC_CLASS 0x08
|
||||
|
||||
/* Interface Descriptor field values for MSC Protocol */
|
||||
#define MSC_BOT 0x50
|
||||
#define MSC_TRANSPARENT 0x06
|
||||
|
||||
#define MSC_STARTUP_TIMEOUT_MS 15000
|
||||
#define MSC_STARTUP_RETRY_TIME_MS 100
|
||||
|
||||
#define MSC_START_STOP_EJECT_FLAG 0
|
||||
#define MSC_START_STOP_LOAD_FLAG 1
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @defgroup USBH_MSC_CORE_Exported_Macros
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @defgroup USBH_MSC_CORE_Exported_Variables
|
||||
* @{
|
||||
*/
|
||||
extern USBH_ClassTypeDef USBH_msc;
|
||||
#define USBH_MSC_CLASS &USBH_msc
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @defgroup USBH_MSC_CORE_Exported_FunctionsPrototype
|
||||
* @{
|
||||
*/
|
||||
|
||||
/* Common APIs */
|
||||
uint8_t USBH_MSC_IsReady (USBH_HandleTypeDef *phost);
|
||||
|
||||
/* APIs for LUN */
|
||||
int8_t USBH_MSC_GetMaxLUN (USBH_HandleTypeDef *phost);
|
||||
|
||||
uint8_t USBH_MSC_UnitIsReady (USBH_HandleTypeDef *phost,
|
||||
uint8_t lun,
|
||||
MSC_CmdCompleteCallback callback);
|
||||
|
||||
USBH_StatusTypeDef USBH_MSC_GetLUNInfo(USBH_HandleTypeDef *phost, uint8_t lun, MSC_LUNTypeDef *info);
|
||||
|
||||
USBH_StatusTypeDef USBH_MSC_Read(USBH_HandleTypeDef *phost,
|
||||
uint8_t lun,
|
||||
uint32_t address,
|
||||
uint32_t length,
|
||||
MSC_CmdCompleteCallback callback);
|
||||
|
||||
USBH_StatusTypeDef USBH_MSC_Write(USBH_HandleTypeDef *phost,
|
||||
uint8_t lun,
|
||||
uint32_t address,
|
||||
uint32_t length,
|
||||
MSC_CmdCompleteCallback callback);
|
||||
|
||||
USBH_StatusTypeDef USBH_MSC_StartStopUnit(USBH_HandleTypeDef *phost,
|
||||
uint8_t lun,
|
||||
uint8_t startStop,
|
||||
MSC_CmdCompleteCallback callback);
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __USBH_MSC_H */
|
||||
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
|
||||
|
||||
|
||||
|
@ -0,0 +1,249 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file usbh_msc_bot.h
|
||||
* @author MCD Application Team
|
||||
* @version V3.2.1
|
||||
* @date 26-June-2015
|
||||
* @brief Header file for usbh_msc_bot.c
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* <h2><center>© COPYRIGHT 2015 STMicroelectronics</center></h2>
|
||||
*
|
||||
* Licensed under MCD-ST Liberty SW License Agreement V2, (the "License");
|
||||
* You may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at:
|
||||
*
|
||||
* http://www.st.com/software_license_agreement_liberty_v2
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
******************************************************************************
|
||||
*
|
||||
* Modifications by Robert Fisk
|
||||
*/
|
||||
|
||||
|
||||
/* Define to prevent recursive ----------------------------------------------*/
|
||||
#ifndef __USBH_MSC_BOT_H
|
||||
#define __USBH_MSC_BOT_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include "usbh_core.h"
|
||||
#include "downstream_spi.h"
|
||||
|
||||
|
||||
/** @addtogroup USBH_LIB
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @addtogroup USBH_CLASS
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @addtogroup USBH_MSC_CLASS
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @defgroup USBH_MSC_BOT
|
||||
* @brief This file is the Header file for usbh_msc_bot.c
|
||||
* @{
|
||||
*/
|
||||
|
||||
|
||||
/** @defgroup USBH_MSC_BOT_Exported_Types
|
||||
* @{
|
||||
*/
|
||||
|
||||
typedef enum {
|
||||
BOT_OK = 0,
|
||||
BOT_FAIL = 1,
|
||||
BOT_PHASE_ERROR = 2,
|
||||
BOT_BUSY = 3
|
||||
}
|
||||
BOT_StatusTypeDef;
|
||||
|
||||
typedef enum {
|
||||
BOT_CMD_IDLE = 0,
|
||||
BOT_CMD_SEND,
|
||||
BOT_CMD_WAIT,
|
||||
}
|
||||
BOT_CMDStateTypeDef;
|
||||
|
||||
/* CSW Status Definitions */
|
||||
typedef enum
|
||||
{
|
||||
|
||||
BOT_CSW_CMD_PASSED = 0x00,
|
||||
BOT_CSW_CMD_FAILED = 0x01,
|
||||
BOT_CSW_PHASE_ERROR = 0x02,
|
||||
}
|
||||
BOT_CSWStatusTypeDef;
|
||||
|
||||
typedef enum {
|
||||
BOT_SEND_CBW = 1,
|
||||
BOT_SEND_CBW_WAIT,
|
||||
BOT_DATA_IN,
|
||||
BOT_DATA_IN_WAIT_FREE_PACKET,
|
||||
BOT_DATA_IN_WAIT,
|
||||
BOT_DATA_OUT,
|
||||
BOT_DATA_OUT_WAIT_RECEIVE_PACKET,
|
||||
BOT_DATA_OUT_WAIT,
|
||||
BOT_RECEIVE_CSW,
|
||||
BOT_RECEIVE_CSW_WAIT,
|
||||
BOT_ERROR_IN,
|
||||
BOT_ERROR_OUT,
|
||||
BOT_UNRECOVERED_ERROR
|
||||
}
|
||||
BOT_StateTypeDef;
|
||||
|
||||
typedef union
|
||||
{
|
||||
struct __CBW
|
||||
{
|
||||
uint32_t Signature;
|
||||
uint32_t Tag;
|
||||
uint32_t DataTransferLength;
|
||||
uint8_t Flags;
|
||||
uint8_t LUN;
|
||||
uint8_t CBLength;
|
||||
uint8_t CB[16];
|
||||
}field;
|
||||
uint8_t data[31];
|
||||
}
|
||||
BOT_CBWTypeDef;
|
||||
|
||||
typedef union
|
||||
{
|
||||
struct __CSW
|
||||
{
|
||||
uint32_t Signature;
|
||||
uint32_t Tag;
|
||||
uint32_t DataResidue;
|
||||
uint8_t Status;
|
||||
}field;
|
||||
uint8_t data[13];
|
||||
}
|
||||
BOT_CSWTypeDef;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint32_t data[16];
|
||||
BOT_StateTypeDef state;
|
||||
BOT_StateTypeDef prev_state;
|
||||
BOT_CMDStateTypeDef cmd_state;
|
||||
BOT_CBWTypeDef cbw;
|
||||
uint8_t Reserved1;
|
||||
BOT_CSWTypeDef csw;
|
||||
uint8_t Reserved2[3];
|
||||
uint8_t* pbuf;
|
||||
DownstreamPacketTypeDef* bot_packet;
|
||||
uint8_t* bot_packet_pbuf;
|
||||
uint16_t bot_packet_bytes_remaining;
|
||||
uint16_t this_URB_size;
|
||||
}
|
||||
BOT_HandleTypeDef;
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
|
||||
|
||||
/** @defgroup USBH_MSC_BOT_Exported_Defines
|
||||
* @{
|
||||
*/
|
||||
#define BOT_CBW_SIGNATURE 0x43425355
|
||||
#define BOT_CBW_TAG 0x20304050
|
||||
#define BOT_CSW_SIGNATURE 0x53425355
|
||||
#define BOT_CBW_LENGTH 31
|
||||
#define BOT_CSW_LENGTH 13
|
||||
|
||||
|
||||
|
||||
#define BOT_SEND_CSW_DISABLE 0
|
||||
#define BOT_SEND_CSW_ENABLE 1
|
||||
|
||||
#define BOT_DIR_IN 0
|
||||
#define BOT_DIR_OUT 1
|
||||
#define BOT_DIR_BOTH 2
|
||||
|
||||
|
||||
#define BOT_CBW_CB_LENGTH 16
|
||||
|
||||
|
||||
#define USB_REQ_BOT_RESET 0xFF
|
||||
#define USB_REQ_GET_MAX_LUN 0xFE
|
||||
|
||||
#define MAX_BULK_STALL_COUNT_LIMIT 0x04 /* If STALL is seen on Bulk
|
||||
Endpoint continuously, this means
|
||||
that device and Host has phase error
|
||||
Hence a Reset is needed */
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @defgroup USBH_MSC_BOT_Exported_Macros
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @defgroup USBH_MSC_BOT_Exported_Variables
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @defgroup USBH_MSC_BOT_Exported_FunctionsPrototype
|
||||
* @{
|
||||
*/
|
||||
USBH_StatusTypeDef USBH_MSC_BOT_REQ_Reset(USBH_HandleTypeDef *phost);
|
||||
USBH_StatusTypeDef USBH_MSC_BOT_REQ_GetMaxLUN(USBH_HandleTypeDef *phost, uint8_t *Maxlun);
|
||||
|
||||
USBH_StatusTypeDef USBH_MSC_BOT_Init(USBH_HandleTypeDef *phost);
|
||||
USBH_StatusTypeDef USBH_MSC_BOT_Process (USBH_HandleTypeDef *phost, uint8_t lun);
|
||||
USBH_StatusTypeDef USBH_MSC_BOT_Error(USBH_HandleTypeDef *phost, uint8_t lun);
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __USBH_MSC_BOT_H__ */
|
||||
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
|
||||
|
@ -0,0 +1,232 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file usbh_msc_scsi.h
|
||||
* @author MCD Application Team
|
||||
* @version V3.2.1
|
||||
* @date 26-June-2015
|
||||
* @brief Header file for usbh_msc_scsi.c
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* <h2><center>© COPYRIGHT 2015 STMicroelectronics</center></h2>
|
||||
*
|
||||
* Licensed under MCD-ST Liberty SW License Agreement V2, (the "License");
|
||||
* You may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at:
|
||||
*
|
||||
* http://www.st.com/software_license_agreement_liberty_v2
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
******************************************************************************
|
||||
*
|
||||
* Modifications by Robert Fisk
|
||||
*/
|
||||
|
||||
|
||||
/* Define to prevent recursive ----------------------------------------------*/
|
||||
#ifndef __USBH_MSC_SCSI_H
|
||||
#define __USBH_MSC_SCSI_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include "usbh_core.h"
|
||||
|
||||
|
||||
/** @addtogroup USBH_LIB
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @addtogroup USBH_CLASS
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @addtogroup USBH_MSC_CLASS
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @defgroup USBH_MSC_SCSI
|
||||
* @brief This file is the Header file for usbh_msc_scsi.c
|
||||
* @{
|
||||
*/
|
||||
|
||||
|
||||
// Capacity data.
|
||||
typedef struct
|
||||
{
|
||||
uint32_t block_nbr;
|
||||
uint16_t block_size;
|
||||
} SCSI_CapacityTypeDef;
|
||||
|
||||
|
||||
// Sense data.
|
||||
typedef struct
|
||||
{
|
||||
uint8_t key;
|
||||
uint8_t asc;
|
||||
uint8_t ascq;
|
||||
} SCSI_SenseTypeDef;
|
||||
|
||||
// INQUIRY data.
|
||||
typedef struct
|
||||
{
|
||||
uint8_t PeripheralQualifier;
|
||||
uint8_t DeviceType;
|
||||
uint8_t RemovableMedia;
|
||||
uint8_t vendor_id[9];
|
||||
uint8_t product_id[17];
|
||||
uint8_t revision_id[5];
|
||||
}SCSI_StdInquiryDataTypeDef;
|
||||
|
||||
/** @defgroup USBH_MSC_SCSI_Exported_Defines
|
||||
* @{
|
||||
*/
|
||||
#define OPCODE_TEST_UNIT_READY 0x00
|
||||
#define OPCODE_READ_CAPACITY10 0x25
|
||||
#define OPCODE_READ10 0x28
|
||||
#define OPCODE_WRITE10 0x2A
|
||||
#define OPCODE_REQUEST_SENSE 0x03
|
||||
#define OPCODE_INQUIRY 0x12
|
||||
#define OPCODE_START_STOP_UNIT 0x1B
|
||||
|
||||
#define DATA_LEN_MODE_TEST_UNIT_READY 0
|
||||
#define DATA_LEN_READ_CAPACITY10 8
|
||||
#define DATA_LEN_INQUIRY 36
|
||||
#define DATA_LEN_REQUEST_SENSE 14
|
||||
#define DATA_LEN_START_STOP_UNIT 0
|
||||
|
||||
#define CBW_CB_LENGTH 16
|
||||
#define CBW_LENGTH 10
|
||||
|
||||
/** @defgroup USBH_MSC_SCSI_Exported_Defines
|
||||
* @{
|
||||
*/
|
||||
#define SCSI_SENSE_KEY_NO_SENSE 0x00
|
||||
#define SCSI_SENSE_KEY_RECOVERED_ERROR 0x01
|
||||
#define SCSI_SENSE_KEY_NOT_READY 0x02
|
||||
#define SCSI_SENSE_KEY_MEDIUM_ERROR 0x03
|
||||
#define SCSI_SENSE_KEY_HARDWARE_ERROR 0x04
|
||||
#define SCSI_SENSE_KEY_ILLEGAL_REQUEST 0x05
|
||||
#define SCSI_SENSE_KEY_UNIT_ATTENTION 0x06
|
||||
#define SCSI_SENSE_KEY_DATA_PROTECT 0x07
|
||||
#define SCSI_SENSE_KEY_BLANK_CHECK 0x08
|
||||
#define SCSI_SENSE_KEY_VENDOR_SPECIFIC 0x09
|
||||
#define SCSI_SENSE_KEY_COPY_ABORTED 0x0A
|
||||
#define SCSI_SENSE_KEY_ABORTED_COMMAND 0x0B
|
||||
#define SCSI_SENSE_KEY_VOLUME_OVERFLOW 0x0D
|
||||
#define SCSI_SENSE_KEY_MISCOMPARE 0x0E
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
|
||||
/** @defgroup USBH_MSC_SCSI_Exported_Defines
|
||||
* @{
|
||||
*/
|
||||
#define SCSI_ASC_NO_ADDITIONAL_SENSE_INFORMATION 0x00
|
||||
#define SCSI_ASC_LOGICAL_UNIT_NOT_READY 0x04
|
||||
#define SCSI_ASC_INVALID_FIELD_IN_CDB 0x24
|
||||
#define SCSI_ASC_WRITE_PROTECTED 0x27
|
||||
#define SCSI_ASC_FORMAT_ERROR 0x31
|
||||
#define SCSI_ASC_INVALID_COMMAND_OPERATION_CODE 0x20
|
||||
#define SCSI_ASC_NOT_READY_TO_READY_CHANGE 0x28
|
||||
#define SCSI_ASC_MEDIUM_NOT_PRESENT 0x3A
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
|
||||
/** @defgroup USBH_MSC_SCSI_Exported_Defines
|
||||
* @{
|
||||
*/
|
||||
#define SCSI_ASCQ_FORMAT_COMMAND_FAILED 0x01
|
||||
#define SCSI_ASCQ_INITIALIZING_COMMAND_REQUIRED 0x02
|
||||
#define SCSI_ASCQ_OPERATION_IN_PROGRESS 0x07
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @defgroup USBH_MSC_SCSI_Exported_Macros
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @defgroup _Exported_Variables
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @defgroup USBH_MSC_SCSI_Exported_FunctionsPrototype
|
||||
* @{
|
||||
*/
|
||||
USBH_StatusTypeDef USBH_MSC_SCSI_TestUnitReady (USBH_HandleTypeDef *phost,
|
||||
uint8_t lun);
|
||||
|
||||
USBH_StatusTypeDef USBH_MSC_SCSI_ReadCapacity (USBH_HandleTypeDef *phost,
|
||||
uint8_t lun,
|
||||
SCSI_CapacityTypeDef *capacity);
|
||||
|
||||
USBH_StatusTypeDef USBH_MSC_SCSI_Inquiry (USBH_HandleTypeDef *phost,
|
||||
uint8_t lun,
|
||||
SCSI_StdInquiryDataTypeDef *inquiry);
|
||||
|
||||
USBH_StatusTypeDef USBH_MSC_SCSI_RequestSense (USBH_HandleTypeDef *phost,
|
||||
uint8_t lun,
|
||||
SCSI_SenseTypeDef *sense_data);
|
||||
|
||||
USBH_StatusTypeDef USBH_MSC_SCSI_Write(USBH_HandleTypeDef *phost,
|
||||
uint8_t lun,
|
||||
uint32_t address,
|
||||
uint32_t length);
|
||||
|
||||
USBH_StatusTypeDef USBH_MSC_SCSI_Read(USBH_HandleTypeDef *phost,
|
||||
uint8_t lun,
|
||||
uint32_t address,
|
||||
uint32_t length);
|
||||
|
||||
USBH_StatusTypeDef USBH_MSC_SCSI_StartStopUnit (USBH_HandleTypeDef *phost,
|
||||
uint8_t lun,
|
||||
uint8_t startStop);
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __USBH_MSC_SCSI_H */
|
||||
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
|
||||
|
@ -0,0 +1,892 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file usbh_msc.c
|
||||
* @author MCD Application Team
|
||||
* @version V3.2.1
|
||||
* @date 26-June-2015
|
||||
* @brief This file implements the MSC class driver functions
|
||||
* ===================================================================
|
||||
* MSC Class Description
|
||||
* ===================================================================
|
||||
* This module manages the MSC class V1.0 following the "Universal
|
||||
* Serial Bus Mass Storage Class (MSC) Bulk-Only Transport (BOT) Version 1.0
|
||||
* Sep. 31, 1999".
|
||||
* This driver implements the following aspects of the specification:
|
||||
* - Bulk-Only Transport protocol
|
||||
* - Subclass : SCSI transparent command set (ref. SCSI Primary Commands - 3 (SPC-3))
|
||||
*
|
||||
* @endverbatim
|
||||
*
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* <h2><center>© COPYRIGHT 2015 STMicroelectronics</center></h2>
|
||||
*
|
||||
* Licensed under MCD-ST Liberty SW License Agreement V2, (the "License");
|
||||
* You may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at:
|
||||
*
|
||||
* http://www.st.com/software_license_agreement_liberty_v2
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
******************************************************************************
|
||||
*
|
||||
* Modifications by Robert Fisk
|
||||
*/
|
||||
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
|
||||
#include "usbh_msc.h"
|
||||
#include "usbh_msc_bot.h"
|
||||
#include "usbh_msc_scsi.h"
|
||||
#include "interrupts.h"
|
||||
#include "build_config.h"
|
||||
|
||||
|
||||
#ifdef CONFIG_MASS_STORAGE_ENABLED
|
||||
/** @addtogroup USBH_LIB
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @addtogroup USBH_CLASS
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @addtogroup USBH_MSC_CLASS
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @defgroup USBH_MSC_CORE
|
||||
* @brief This file includes the mass storage related functions
|
||||
* @{
|
||||
*/
|
||||
|
||||
|
||||
/** @defgroup USBH_MSC_CORE_Private_TypesDefinitions
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @defgroup USBH_MSC_CORE_Private_Defines
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @defgroup USBH_MSC_CORE_Private_Macros
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
|
||||
/** @defgroup USBH_MSC_CORE_Private_Variables
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
|
||||
/** @defgroup USBH_MSC_CORE_Private_FunctionPrototypes
|
||||
* @{
|
||||
*/
|
||||
|
||||
static USBH_StatusTypeDef USBH_MSC_InterfaceInit (USBH_HandleTypeDef *phost);
|
||||
|
||||
static USBH_StatusTypeDef USBH_MSC_InterfaceDeInit (USBH_HandleTypeDef *phost);
|
||||
|
||||
static USBH_StatusTypeDef USBH_MSC_Process(USBH_HandleTypeDef *phost);
|
||||
|
||||
static USBH_StatusTypeDef USBH_MSC_ClassRequest(USBH_HandleTypeDef *phost);
|
||||
|
||||
static USBH_StatusTypeDef USBH_MSC_SOFProcess(USBH_HandleTypeDef *phost);
|
||||
|
||||
static USBH_StatusTypeDef USBH_MSC_RdWrProcess(USBH_HandleTypeDef *phost, uint8_t lun);
|
||||
|
||||
USBH_ClassTypeDef USBH_msc =
|
||||
{
|
||||
"MSC",
|
||||
USB_MSC_CLASS,
|
||||
USBH_MSC_InterfaceInit,
|
||||
USBH_MSC_InterfaceDeInit,
|
||||
USBH_MSC_ClassRequest,
|
||||
USBH_MSC_Process,
|
||||
USBH_MSC_SOFProcess,
|
||||
NULL,
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
|
||||
/** @defgroup USBH_MSC_CORE_Exported_Variables
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
|
||||
/** @defgroup USBH_MSC_CORE_Private_Functions
|
||||
* @{
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* @brief USBH_MSC_InterfaceInit
|
||||
* The function init the MSC class.
|
||||
* @param phost: Host handle
|
||||
* @retval USBH Status
|
||||
*/
|
||||
static USBH_StatusTypeDef USBH_MSC_InterfaceInit (USBH_HandleTypeDef *phost)
|
||||
{
|
||||
uint8_t interface = 0;
|
||||
USBH_StatusTypeDef status = USBH_FAIL ;
|
||||
MSC_HandleTypeDef *MSC_Handle;
|
||||
|
||||
interface = USBH_FindInterface(phost, phost->pActiveClass->ClassCode, 0xFF, MSC_BOT);//MSC_TRANSPARENT, MSC_BOT); //Ignore subclass?!!
|
||||
|
||||
if(interface == 0xFF) /* Not Valid Interface */
|
||||
{
|
||||
USBH_DbgLog ("Cannot Find the interface for %s class.", phost->pActiveClass->Name);
|
||||
status = USBH_FAIL;
|
||||
}
|
||||
else
|
||||
{
|
||||
USBH_SelectInterface (phost, interface);
|
||||
|
||||
phost->pActiveClass->pData = (MSC_HandleTypeDef *)USBH_malloc (sizeof(MSC_HandleTypeDef));
|
||||
MSC_Handle = (MSC_HandleTypeDef *) phost->pActiveClass->pData;
|
||||
|
||||
if(phost->device.CfgDesc.Itf_Desc[phost->device.current_interface].Ep_Desc[0].bEndpointAddress & 0x80)
|
||||
{
|
||||
MSC_Handle->InEp = (phost->device.CfgDesc.Itf_Desc[phost->device.current_interface].Ep_Desc[0].bEndpointAddress);
|
||||
MSC_Handle->InEpSize = phost->device.CfgDesc.Itf_Desc[phost->device.current_interface].Ep_Desc[0].wMaxPacketSize;
|
||||
}
|
||||
else
|
||||
{
|
||||
MSC_Handle->OutEp = (phost->device.CfgDesc.Itf_Desc[phost->device.current_interface].Ep_Desc[0].bEndpointAddress);
|
||||
MSC_Handle->OutEpSize = phost->device.CfgDesc.Itf_Desc[phost->device.current_interface].Ep_Desc[0].wMaxPacketSize;
|
||||
}
|
||||
|
||||
if(phost->device.CfgDesc.Itf_Desc[phost->device.current_interface].Ep_Desc[1].bEndpointAddress & 0x80)
|
||||
{
|
||||
MSC_Handle->InEp = (phost->device.CfgDesc.Itf_Desc[phost->device.current_interface].Ep_Desc[1].bEndpointAddress);
|
||||
MSC_Handle->InEpSize = phost->device.CfgDesc.Itf_Desc[phost->device.current_interface].Ep_Desc[1].wMaxPacketSize;
|
||||
}
|
||||
else
|
||||
{
|
||||
MSC_Handle->OutEp = (phost->device.CfgDesc.Itf_Desc[phost->device.current_interface].Ep_Desc[1].bEndpointAddress);
|
||||
MSC_Handle->OutEpSize = phost->device.CfgDesc.Itf_Desc[phost->device.current_interface].Ep_Desc[1].wMaxPacketSize;
|
||||
}
|
||||
|
||||
MSC_Handle->current_lun = 0;
|
||||
MSC_Handle->rw_lun = 0;
|
||||
MSC_Handle->state = MSC_INIT;
|
||||
MSC_Handle->error = MSC_OK;
|
||||
MSC_Handle->req_state = MSC_REQ_IDLE;
|
||||
MSC_Handle->OutPipe = USBH_AllocPipe(phost, MSC_Handle->OutEp);
|
||||
MSC_Handle->InPipe = USBH_AllocPipe(phost, MSC_Handle->InEp);
|
||||
MSC_Handle->CmdCompleteCallback = NULL;
|
||||
|
||||
USBH_MSC_BOT_Init(phost);
|
||||
|
||||
/* De-Initialize LUNs information */
|
||||
USBH_memset(MSC_Handle->unit, 0, sizeof(MSC_Handle->unit));
|
||||
|
||||
/* Open the new channels */
|
||||
USBH_OpenPipe (phost,
|
||||
MSC_Handle->OutPipe,
|
||||
MSC_Handle->OutEp,
|
||||
phost->device.address,
|
||||
phost->device.speed,
|
||||
USB_EP_TYPE_BULK,
|
||||
MSC_Handle->OutEpSize);
|
||||
|
||||
USBH_OpenPipe (phost,
|
||||
MSC_Handle->InPipe,
|
||||
MSC_Handle->InEp,
|
||||
phost->device.address,
|
||||
phost->device.speed,
|
||||
USB_EP_TYPE_BULK,
|
||||
MSC_Handle->InEpSize);
|
||||
|
||||
|
||||
USBH_LL_SetToggle (phost, MSC_Handle->InPipe,0);
|
||||
USBH_LL_SetToggle (phost, MSC_Handle->OutPipe,0);
|
||||
status = USBH_OK;
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief USBH_MSC_InterfaceDeInit
|
||||
* The function DeInit the Pipes used for the MSC class.
|
||||
* @param phost: Host handle
|
||||
* @retval USBH Status
|
||||
*/
|
||||
USBH_StatusTypeDef USBH_MSC_InterfaceDeInit (USBH_HandleTypeDef *phost)
|
||||
{
|
||||
MSC_HandleTypeDef *MSC_Handle = (MSC_HandleTypeDef *) phost->pActiveClass->pData;
|
||||
|
||||
if ( MSC_Handle->OutPipe)
|
||||
{
|
||||
USBH_ClosePipe(phost, MSC_Handle->OutPipe);
|
||||
USBH_FreePipe (phost, MSC_Handle->OutPipe);
|
||||
MSC_Handle->OutPipe = 0; /* Reset the Channel as Free */
|
||||
}
|
||||
|
||||
if ( MSC_Handle->InPipe)
|
||||
{
|
||||
USBH_ClosePipe(phost, MSC_Handle->InPipe);
|
||||
USBH_FreePipe (phost, MSC_Handle->InPipe);
|
||||
MSC_Handle->InPipe = 0; /* Reset the Channel as Free */
|
||||
}
|
||||
|
||||
if(phost->pActiveClass->pData)
|
||||
{
|
||||
USBH_free (phost->pActiveClass->pData);
|
||||
phost->pActiveClass->pData = 0;
|
||||
}
|
||||
|
||||
return USBH_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief USBH_MSC_ClassRequest
|
||||
* The function is responsible for handling Standard requests
|
||||
* for MSC class.
|
||||
* @param phost: Host handle
|
||||
* @retval USBH Status
|
||||
*/
|
||||
static USBH_StatusTypeDef USBH_MSC_ClassRequest(USBH_HandleTypeDef *phost)
|
||||
{
|
||||
MSC_HandleTypeDef *MSC_Handle = (MSC_HandleTypeDef *) phost->pActiveClass->pData;
|
||||
USBH_StatusTypeDef status = USBH_BUSY;
|
||||
|
||||
/* Switch MSC REQ state machine */
|
||||
switch (MSC_Handle->req_state)
|
||||
{
|
||||
case MSC_REQ_IDLE:
|
||||
MSC_Handle->timeout = HAL_GetTick();
|
||||
MSC_Handle->req_state = MSC_REQ_STARTUP_DELAY;
|
||||
break;
|
||||
|
||||
case MSC_REQ_STARTUP_DELAY:
|
||||
if ((HAL_GetTick() - MSC_Handle->timeout) > MSC_SAMSUNG_STARTUP_DELAY_MS)
|
||||
{
|
||||
MSC_Handle->req_state = MSC_REQ_GET_MAX_LUN;
|
||||
}
|
||||
break;
|
||||
|
||||
case MSC_REQ_GET_MAX_LUN:
|
||||
/* Issue GetMaxLUN request */
|
||||
status = USBH_MSC_BOT_REQ_GetMaxLUN(phost, (uint8_t *)&MSC_Handle->max_lun);
|
||||
|
||||
/* When devices do not support the GetMaxLun request, this should
|
||||
be considred as only one logical unit is supported */
|
||||
if(status == USBH_NOT_SUPPORTED)
|
||||
{
|
||||
MSC_Handle->max_lun = 0;
|
||||
status = USBH_OK;
|
||||
}
|
||||
|
||||
if(status == USBH_OK)
|
||||
{
|
||||
MSC_Handle->max_lun = (uint8_t )(MSC_Handle->max_lun) + 1;
|
||||
USBH_UsrLog ("Number of supported LUN: %lu", (int32_t)(MSC_Handle->max_lun));
|
||||
|
||||
if (MSC_Handle->max_lun > MAX_SUPPORTED_LUN)
|
||||
{
|
||||
MSC_Handle->max_lun = MAX_SUPPORTED_LUN;
|
||||
}
|
||||
MSC_Handle->req_state = MSC_REQ_IDLE;
|
||||
}
|
||||
break;
|
||||
|
||||
case MSC_REQ_ERROR :
|
||||
/* a Clear Feature should be issued here */
|
||||
if(USBH_ClrFeature(phost, 0x00) == USBH_OK)
|
||||
{
|
||||
MSC_Handle->req_state = MSC_Handle->prev_req_state;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief USBH_MSC_Process
|
||||
* The function is for managing state machine for MSC data transfers
|
||||
* @param phost: Host handle
|
||||
* @retval USBH Status
|
||||
*/
|
||||
static USBH_StatusTypeDef USBH_MSC_Process(USBH_HandleTypeDef *phost)
|
||||
{
|
||||
MSC_HandleTypeDef *MSC_Handle = (MSC_HandleTypeDef *) phost->pActiveClass->pData;
|
||||
USBH_StatusTypeDef error = USBH_BUSY ;
|
||||
USBH_StatusTypeDef scsi_status = USBH_BUSY ;
|
||||
USBH_StatusTypeDef ready_status = USBH_BUSY ;
|
||||
|
||||
|
||||
switch (MSC_Handle->state)
|
||||
{
|
||||
case MSC_INIT:
|
||||
|
||||
if(MSC_Handle->current_lun < MSC_Handle->max_lun)
|
||||
{
|
||||
|
||||
MSC_Handle->unit[MSC_Handle->current_lun].error = MSC_NOT_READY;
|
||||
/* Switch MSC REQ state machine */
|
||||
switch (MSC_Handle->unit[MSC_Handle->current_lun].state)
|
||||
{
|
||||
case MSC_INIT:
|
||||
USBH_UsrLog ("LUN #%d: ", MSC_Handle->current_lun);
|
||||
MSC_Handle->unit[MSC_Handle->current_lun].state = MSC_READ_INQUIRY;
|
||||
MSC_Handle->timeout = HAL_GetTick();
|
||||
//Fallthrough
|
||||
|
||||
case MSC_READ_INQUIRY:
|
||||
scsi_status = USBH_MSC_SCSI_Inquiry(phost, MSC_Handle->current_lun, &MSC_Handle->unit[MSC_Handle->current_lun].inquiry);
|
||||
|
||||
if( scsi_status == USBH_OK)
|
||||
{
|
||||
USBH_UsrLog ("Inquiry Vendor : %s", MSC_Handle->unit[MSC_Handle->current_lun].inquiry.vendor_id);
|
||||
USBH_UsrLog ("Inquiry Product : %s", MSC_Handle->unit[MSC_Handle->current_lun].inquiry.product_id);
|
||||
USBH_UsrLog ("Inquiry Version : %s", MSC_Handle->unit[MSC_Handle->current_lun].inquiry.revision_id);
|
||||
MSC_Handle->unit[MSC_Handle->current_lun].state = MSC_TEST_UNIT_READY;
|
||||
}
|
||||
if( scsi_status == USBH_FAIL)
|
||||
{
|
||||
MSC_Handle->unit[MSC_Handle->current_lun].state = MSC_REQUEST_SENSE;
|
||||
}
|
||||
else if(scsi_status == USBH_UNRECOVERED_ERROR)
|
||||
{
|
||||
MSC_Handle->unit[MSC_Handle->current_lun].state = MSC_IDLE;
|
||||
MSC_Handle->unit[MSC_Handle->current_lun].error = MSC_ERROR;
|
||||
}
|
||||
break;
|
||||
|
||||
case MSC_TEST_UNIT_READY:
|
||||
ready_status = USBH_MSC_SCSI_TestUnitReady(phost, MSC_Handle->current_lun);
|
||||
|
||||
if( ready_status == USBH_OK)
|
||||
{
|
||||
if( MSC_Handle->unit[MSC_Handle->current_lun].prev_ready_state != USBH_OK)
|
||||
{
|
||||
MSC_Handle->unit[MSC_Handle->current_lun].state_changed = 1;
|
||||
USBH_UsrLog ("MSC Device ready");
|
||||
}
|
||||
else
|
||||
{
|
||||
MSC_Handle->unit[MSC_Handle->current_lun].state_changed = 0;
|
||||
}
|
||||
MSC_Handle->unit[MSC_Handle->current_lun].state = MSC_READ_CAPACITY10;
|
||||
MSC_Handle->unit[MSC_Handle->current_lun].error = MSC_OK;
|
||||
MSC_Handle->unit[MSC_Handle->current_lun].prev_ready_state = USBH_OK;
|
||||
}
|
||||
if( ready_status == USBH_FAIL)
|
||||
{
|
||||
/* Media not ready, so try to check again during 10s */
|
||||
if( MSC_Handle->unit[MSC_Handle->current_lun].prev_ready_state != USBH_FAIL)
|
||||
{
|
||||
MSC_Handle->unit[MSC_Handle->current_lun].state_changed = 1;
|
||||
USBH_UsrLog ("MSC Device NOT ready");
|
||||
}
|
||||
else
|
||||
{
|
||||
MSC_Handle->unit[MSC_Handle->current_lun].state_changed = 0;
|
||||
}
|
||||
MSC_Handle->unit[MSC_Handle->current_lun].state = MSC_REQUEST_SENSE;
|
||||
MSC_Handle->unit[MSC_Handle->current_lun].error = MSC_NOT_READY;
|
||||
MSC_Handle->unit[MSC_Handle->current_lun].prev_ready_state = USBH_FAIL;
|
||||
}
|
||||
else if(ready_status == USBH_UNRECOVERED_ERROR)
|
||||
{
|
||||
MSC_Handle->unit[MSC_Handle->current_lun].state = MSC_IDLE;
|
||||
MSC_Handle->unit[MSC_Handle->current_lun].error = MSC_ERROR;
|
||||
}
|
||||
break;
|
||||
|
||||
case MSC_READ_CAPACITY10:
|
||||
scsi_status = USBH_MSC_SCSI_ReadCapacity(phost,MSC_Handle->current_lun, &MSC_Handle->unit[MSC_Handle->current_lun].capacity) ;
|
||||
|
||||
if(scsi_status == USBH_OK)
|
||||
{
|
||||
if(MSC_Handle->unit[MSC_Handle->current_lun].state_changed == 1)
|
||||
{
|
||||
USBH_UsrLog ("MSC Device capacity : %lu Bytes", \
|
||||
(int32_t)(MSC_Handle->unit[MSC_Handle->current_lun].capacity.block_nbr * MSC_Handle->unit[MSC_Handle->current_lun].capacity.block_size));
|
||||
USBH_UsrLog ("Block number : %lu", (int32_t)(MSC_Handle->unit[MSC_Handle->current_lun].capacity.block_nbr));
|
||||
USBH_UsrLog ("Block Size : %lu", (int32_t)(MSC_Handle->unit[MSC_Handle->current_lun].capacity.block_size));
|
||||
}
|
||||
MSC_Handle->unit[MSC_Handle->current_lun].state = MSC_IDLE;
|
||||
MSC_Handle->unit[MSC_Handle->current_lun].error = MSC_OK;
|
||||
MSC_Handle->current_lun++;
|
||||
}
|
||||
else if( scsi_status == USBH_FAIL)
|
||||
{
|
||||
MSC_Handle->unit[MSC_Handle->current_lun].state = MSC_REQUEST_SENSE;
|
||||
}
|
||||
else if(scsi_status == USBH_UNRECOVERED_ERROR)
|
||||
{
|
||||
MSC_Handle->unit[MSC_Handle->current_lun].state = MSC_IDLE;
|
||||
MSC_Handle->unit[MSC_Handle->current_lun].error = MSC_ERROR;
|
||||
}
|
||||
break;
|
||||
|
||||
case MSC_REQUEST_SENSE:
|
||||
scsi_status = USBH_MSC_SCSI_RequestSense(phost, MSC_Handle->current_lun, &MSC_Handle->unit[MSC_Handle->current_lun].sense);
|
||||
|
||||
if( scsi_status == USBH_OK)
|
||||
{
|
||||
if((MSC_Handle->unit[MSC_Handle->current_lun].sense.key == SCSI_SENSE_KEY_UNIT_ATTENTION) ||
|
||||
(MSC_Handle->unit[MSC_Handle->current_lun].sense.key == SCSI_SENSE_KEY_NOT_READY) )
|
||||
{
|
||||
if((HAL_GetTick() - MSC_Handle->timeout) < MSC_STARTUP_TIMEOUT_MS)
|
||||
{
|
||||
MSC_Handle->retry_timeout = HAL_GetTick();
|
||||
MSC_Handle->unit[MSC_Handle->current_lun].state = MSC_REQUEST_SENSE_WAIT_RETRY;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
USBH_UsrLog ("Sense Key : %x", MSC_Handle->unit[MSC_Handle->current_lun].sense.key);
|
||||
USBH_UsrLog ("Additional Sense Code : %x", MSC_Handle->unit[MSC_Handle->current_lun].sense.asc);
|
||||
USBH_UsrLog ("Additional Sense Code Qualifier: %x", MSC_Handle->unit[MSC_Handle->current_lun].sense.ascq);
|
||||
MSC_Handle->unit[MSC_Handle->current_lun].state = MSC_IDLE;
|
||||
MSC_Handle->current_lun++;
|
||||
}
|
||||
if( scsi_status == USBH_FAIL)
|
||||
{
|
||||
USBH_UsrLog ("MSC Device NOT ready");
|
||||
MSC_Handle->unit[MSC_Handle->current_lun].state = MSC_UNRECOVERED_ERROR;
|
||||
}
|
||||
else if(scsi_status == USBH_UNRECOVERED_ERROR)
|
||||
{
|
||||
MSC_Handle->unit[MSC_Handle->current_lun].state = MSC_IDLE;
|
||||
MSC_Handle->unit[MSC_Handle->current_lun].error = MSC_ERROR;
|
||||
}
|
||||
break;
|
||||
|
||||
case MSC_REQUEST_SENSE_WAIT_RETRY:
|
||||
if ((HAL_GetTick() - MSC_Handle->retry_timeout) > MSC_STARTUP_RETRY_TIME_MS)
|
||||
{
|
||||
MSC_Handle->unit[MSC_Handle->current_lun].state = MSC_TEST_UNIT_READY;
|
||||
}
|
||||
break;
|
||||
|
||||
case MSC_UNRECOVERED_ERROR:
|
||||
MSC_Handle->current_lun++;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
MSC_Handle->current_lun = 0;
|
||||
MSC_Handle->state = MSC_IDLE;
|
||||
|
||||
phost->pUser(phost, HOST_USER_CLASS_ACTIVE);
|
||||
}
|
||||
break;
|
||||
|
||||
case MSC_IDLE:
|
||||
error = USBH_OK;
|
||||
break;
|
||||
|
||||
#ifdef CONFIG_MASS_STORAGE_WRITES_PERMITTED
|
||||
case MSC_WRITE:
|
||||
#endif
|
||||
case MSC_READ:
|
||||
error = USBH_MSC_RdWrProcess(phost, MSC_Handle->rw_lun);
|
||||
if(((int32_t)(HAL_GetTick() - MSC_Handle->timeout) > 0) || (phost->device.is_connected == 0))
|
||||
{
|
||||
error = USBH_FAIL;
|
||||
}
|
||||
|
||||
if (error != USBH_BUSY)
|
||||
{
|
||||
MSC_Handle->state = MSC_IDLE;
|
||||
if (MSC_Handle->CmdCompleteCallback != NULL)
|
||||
{
|
||||
MSC_Handle->CmdCompleteCallback(error);
|
||||
MSC_Handle->CmdCompleteCallback = NULL;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case MSC_TEST_UNIT_READY:
|
||||
error = USBH_MSC_SCSI_TestUnitReady(phost, MSC_Handle->rw_lun);
|
||||
|
||||
if (((int32_t)(HAL_GetTick() - MSC_Handle->timeout) > 0) || (phost->device.is_connected == 0))
|
||||
{
|
||||
error = USBH_FAIL;
|
||||
}
|
||||
if (error != USBH_BUSY)
|
||||
{
|
||||
MSC_Handle->state = MSC_IDLE;
|
||||
if (error == USBH_OK)
|
||||
{
|
||||
MSC_Handle->unit[MSC_Handle->current_lun].error = MSC_OK;
|
||||
}
|
||||
else
|
||||
{
|
||||
MSC_Handle->unit[MSC_Handle->current_lun].error = MSC_NOT_READY;
|
||||
}
|
||||
if (MSC_Handle->CmdCompleteCallback != NULL)
|
||||
{
|
||||
MSC_Handle->CmdCompleteCallback(error);
|
||||
MSC_Handle->CmdCompleteCallback = NULL;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case MSC_START_STOP:
|
||||
error = USBH_MSC_SCSI_StartStopUnit(phost, MSC_Handle->rw_lun, 0);
|
||||
|
||||
if((error != USBH_BUSY) ||
|
||||
((int32_t)(HAL_GetTick() - MSC_Handle->timeout) > 0) || (phost->device.is_connected == 0))
|
||||
{
|
||||
MSC_Handle->state = MSC_IDLE;
|
||||
error = USBH_OK;
|
||||
|
||||
if (MSC_Handle->CmdCompleteCallback != NULL)
|
||||
{
|
||||
MSC_Handle->CmdCompleteCallback(USBH_OK);
|
||||
MSC_Handle->CmdCompleteCallback = NULL;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief USBH_MSC_SOFProcess
|
||||
* The function is for SOF state
|
||||
* @param phost: Host handle
|
||||
* @retval USBH Status
|
||||
*/
|
||||
static USBH_StatusTypeDef USBH_MSC_SOFProcess(USBH_HandleTypeDef *phost)
|
||||
{
|
||||
|
||||
return USBH_OK;
|
||||
}
|
||||
/**
|
||||
* @brief USBH_MSC_RdWrProcess
|
||||
* The function is for managing state machine for MSC I/O Process
|
||||
* @param phost: Host handle
|
||||
* @param lun: logical Unit Number
|
||||
* @retval USBH Status
|
||||
*/
|
||||
static USBH_StatusTypeDef USBH_MSC_RdWrProcess(USBH_HandleTypeDef *phost, uint8_t lun)
|
||||
{
|
||||
MSC_HandleTypeDef *MSC_Handle = (MSC_HandleTypeDef *) phost->pActiveClass->pData;
|
||||
USBH_StatusTypeDef error = USBH_BUSY ;
|
||||
USBH_StatusTypeDef scsi_status = USBH_BUSY ;
|
||||
|
||||
/* Switch MSC REQ state machine */
|
||||
switch (MSC_Handle->unit[lun].state)
|
||||
{
|
||||
|
||||
case MSC_READ:
|
||||
scsi_status = USBH_MSC_SCSI_Read(phost,lun, 0, 0) ;
|
||||
|
||||
if(scsi_status == USBH_OK)
|
||||
{
|
||||
MSC_Handle->unit[lun].state = MSC_IDLE;
|
||||
error = USBH_OK;
|
||||
}
|
||||
else if( scsi_status == USBH_FAIL)
|
||||
{
|
||||
MSC_Handle->unit[lun].state = MSC_REQUEST_SENSE;
|
||||
}
|
||||
else if(scsi_status == USBH_UNRECOVERED_ERROR)
|
||||
{
|
||||
MSC_Handle->unit[lun].state = MSC_UNRECOVERED_ERROR;
|
||||
error = USBH_FAIL;
|
||||
}
|
||||
#if (USBH_USE_OS == 1)
|
||||
osMessagePut ( phost->os_event, USBH_CLASS_EVENT, 0);
|
||||
#endif
|
||||
break;
|
||||
|
||||
#ifdef CONFIG_MASS_STORAGE_WRITES_PERMITTED
|
||||
case MSC_WRITE:
|
||||
scsi_status = USBH_MSC_SCSI_Write(phost,lun, 0, 0) ;
|
||||
|
||||
if(scsi_status == USBH_OK)
|
||||
{
|
||||
MSC_Handle->unit[lun].state = MSC_IDLE;
|
||||
error = USBH_OK;
|
||||
}
|
||||
else if( scsi_status == USBH_FAIL)
|
||||
{
|
||||
MSC_Handle->unit[lun].state = MSC_REQUEST_SENSE;
|
||||
}
|
||||
else if(scsi_status == USBH_UNRECOVERED_ERROR)
|
||||
{
|
||||
MSC_Handle->unit[lun].state = MSC_UNRECOVERED_ERROR;
|
||||
error = USBH_FAIL;
|
||||
}
|
||||
#if (USBH_USE_OS == 1)
|
||||
osMessagePut ( phost->os_event, USBH_CLASS_EVENT, 0);
|
||||
#endif
|
||||
break;
|
||||
#endif //#ifdef CONFIG_MASS_STORAGE_WRITES_PERMITTED
|
||||
|
||||
case MSC_REQUEST_SENSE:
|
||||
scsi_status = USBH_MSC_SCSI_RequestSense(phost, lun, &MSC_Handle->unit[lun].sense);
|
||||
|
||||
if( scsi_status == USBH_OK)
|
||||
{
|
||||
USBH_UsrLog ("Sense Key : %x", MSC_Handle->unit[lun].sense.key);
|
||||
USBH_UsrLog ("Additional Sense Code : %x", MSC_Handle->unit[lun].sense.asc);
|
||||
USBH_UsrLog ("Additional Sense Code Qualifier: %x", MSC_Handle->unit[lun].sense.ascq);
|
||||
MSC_Handle->unit[lun].state = MSC_IDLE;
|
||||
MSC_Handle->unit[lun].error = MSC_ERROR;
|
||||
error = USBH_FAIL;
|
||||
}
|
||||
if( scsi_status == USBH_FAIL)
|
||||
{
|
||||
USBH_UsrLog ("MSC Device NOT ready");
|
||||
}
|
||||
else if(scsi_status == USBH_UNRECOVERED_ERROR)
|
||||
{
|
||||
MSC_Handle->unit[lun].state = MSC_UNRECOVERED_ERROR;
|
||||
error = USBH_FAIL;
|
||||
}
|
||||
#if (USBH_USE_OS == 1)
|
||||
osMessagePut ( phost->os_event, USBH_CLASS_EVENT, 0);
|
||||
#endif
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
|
||||
}
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief USBH_MSC_GetMaxLUN
|
||||
* The function return the Max LUN supported
|
||||
* @param phost: Host handle
|
||||
* @retval logical Unit Number supported
|
||||
*/
|
||||
int8_t USBH_MSC_GetMaxLUN (USBH_HandleTypeDef *phost)
|
||||
{
|
||||
MSC_HandleTypeDef *MSC_Handle = (MSC_HandleTypeDef *) phost->pActiveClass->pData;
|
||||
|
||||
if ((phost->gState == HOST_CLASS) && (MSC_Handle->state == MSC_IDLE))
|
||||
{
|
||||
return MSC_Handle->max_lun;
|
||||
}
|
||||
return 0xFF;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief USBH_MSC_UnitIsReady
|
||||
* The function check whether a LUN is ready
|
||||
* @param phost: Host handle
|
||||
* @param lun: logical Unit Number
|
||||
* @retval Lun status (0: not ready / 1: ready)
|
||||
*/
|
||||
uint8_t USBH_MSC_UnitIsReady (USBH_HandleTypeDef *phost,
|
||||
uint8_t lun,
|
||||
MSC_CmdCompleteCallback callback)
|
||||
{
|
||||
MSC_HandleTypeDef *MSC_Handle = (MSC_HandleTypeDef *) phost->pActiveClass->pData;
|
||||
|
||||
if ((phost->device.is_connected == 0) ||
|
||||
(phost->gState != HOST_CLASS) ||
|
||||
(MSC_Handle->state != MSC_IDLE))
|
||||
{
|
||||
return USBH_FAIL;
|
||||
}
|
||||
|
||||
MSC_Handle->state = MSC_TEST_UNIT_READY;
|
||||
MSC_Handle->rw_lun = lun;
|
||||
MSC_Handle->CmdCompleteCallback = callback;
|
||||
MSC_Handle->timeout = HAL_GetTick() + MSC_TIMEOUT_FIXED_MS;
|
||||
|
||||
return USBH_MSC_SCSI_TestUnitReady(phost, lun);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief USBH_MSC_GetLUNInfo
|
||||
* The function return a LUN information
|
||||
* @param phost: Host handle
|
||||
* @param lun: logical Unit Number
|
||||
* @retval USBH Status
|
||||
*/
|
||||
USBH_StatusTypeDef USBH_MSC_GetLUNInfo(USBH_HandleTypeDef *phost, uint8_t lun, MSC_LUNTypeDef *info)
|
||||
{
|
||||
MSC_HandleTypeDef *MSC_Handle = (MSC_HandleTypeDef *) phost->pActiveClass->pData;
|
||||
if(phost->gState == HOST_CLASS)
|
||||
{
|
||||
USBH_memcpy(info,&MSC_Handle->unit[lun], sizeof(MSC_LUNTypeDef));
|
||||
return USBH_OK;
|
||||
}
|
||||
else
|
||||
{
|
||||
return USBH_FAIL;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief USBH_MSC_Read
|
||||
* The function performs a Read operation
|
||||
* @param phost: Host handle
|
||||
* @param lun: logical Unit Number
|
||||
* @param address: sector address
|
||||
* @param pbuf: pointer to data
|
||||
* @param length: number of sector to read
|
||||
* @retval USBH Status
|
||||
*/
|
||||
USBH_StatusTypeDef USBH_MSC_Read(USBH_HandleTypeDef *phost,
|
||||
uint8_t lun,
|
||||
uint32_t address,
|
||||
uint32_t length,
|
||||
MSC_CmdCompleteCallback callback)
|
||||
{
|
||||
MSC_HandleTypeDef *MSC_Handle = (MSC_HandleTypeDef *) phost->pActiveClass->pData;
|
||||
|
||||
if ((phost->device.is_connected == 0) ||
|
||||
(phost->gState != HOST_CLASS) ||
|
||||
(MSC_Handle->state != MSC_IDLE) ||
|
||||
(MSC_Handle->unit[lun].state != MSC_IDLE))
|
||||
{
|
||||
return USBH_FAIL;
|
||||
}
|
||||
|
||||
MSC_Handle->state = MSC_READ;
|
||||
MSC_Handle->unit[lun].state = MSC_READ;
|
||||
MSC_Handle->rw_lun = lun;
|
||||
MSC_Handle->CmdCompleteCallback = callback;
|
||||
MSC_Handle->timeout = HAL_GetTick() + MSC_TIMEOUT_FIXED_MS;
|
||||
|
||||
return USBH_MSC_SCSI_Read(phost,
|
||||
lun,
|
||||
address,
|
||||
length);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @brief USBH_MSC_Write
|
||||
* The function performs a Write operation
|
||||
* @param phost: Host handle
|
||||
* @param lun: logical Unit Number
|
||||
* @param address: sector address
|
||||
* @param pbuf: pointer to data
|
||||
* @param length: number of sector to write
|
||||
* @retval USBH Status
|
||||
*/
|
||||
#ifdef CONFIG_MASS_STORAGE_WRITES_PERMITTED
|
||||
USBH_StatusTypeDef USBH_MSC_Write(USBH_HandleTypeDef *phost,
|
||||
uint8_t lun,
|
||||
uint32_t address,
|
||||
uint32_t length,
|
||||
MSC_CmdCompleteCallback callback)
|
||||
{
|
||||
MSC_HandleTypeDef *MSC_Handle = (MSC_HandleTypeDef *) phost->pActiveClass->pData;
|
||||
|
||||
if ((phost->device.is_connected == 0) ||
|
||||
(phost->gState != HOST_CLASS) ||
|
||||
(MSC_Handle->state != MSC_IDLE) ||
|
||||
(MSC_Handle->unit[lun].state != MSC_IDLE))
|
||||
{
|
||||
return USBH_FAIL;
|
||||
}
|
||||
|
||||
MSC_Handle->state = MSC_WRITE;
|
||||
MSC_Handle->unit[lun].state = MSC_WRITE;
|
||||
MSC_Handle->rw_lun = lun;
|
||||
MSC_Handle->CmdCompleteCallback = callback;
|
||||
MSC_Handle->timeout = HAL_GetTick() + MSC_TIMEOUT_FIXED_MS;
|
||||
|
||||
return USBH_MSC_SCSI_Write(phost,
|
||||
lun,
|
||||
address,
|
||||
length);
|
||||
}
|
||||
#endif //#ifdef CONFIG_MASS_STORAGE_WRITES_PERMITTED
|
||||
|
||||
|
||||
|
||||
USBH_StatusTypeDef USBH_MSC_StartStopUnit(USBH_HandleTypeDef *phost,
|
||||
uint8_t lun,
|
||||
uint8_t startStop,
|
||||
MSC_CmdCompleteCallback callback)
|
||||
{
|
||||
MSC_HandleTypeDef *MSC_Handle = (MSC_HandleTypeDef *) phost->pActiveClass->pData;
|
||||
|
||||
if ((phost->device.is_connected == 0) ||
|
||||
(phost->gState != HOST_CLASS) ||
|
||||
(MSC_Handle->state != MSC_IDLE))
|
||||
{
|
||||
return USBH_FAIL;
|
||||
}
|
||||
|
||||
MSC_Handle->state = MSC_START_STOP;
|
||||
MSC_Handle->rw_lun = lun;
|
||||
MSC_Handle->timeout = HAL_GetTick() + MSC_TIMEOUT_FIXED_MS;
|
||||
MSC_Handle->CmdCompleteCallback = callback;
|
||||
|
||||
return USBH_MSC_SCSI_StartStopUnit(phost,
|
||||
lun,
|
||||
startStop);
|
||||
}
|
||||
|
||||
|
||||
#endif //#ifdef CONFIG_MASS_STORAGE_ENABLED
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
|
@ -0,0 +1,737 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file usbh_msc_bot.c
|
||||
* @author MCD Application Team
|
||||
* @version V3.2.1
|
||||
* @date 26-June-2015
|
||||
* @brief This file includes the BOT protocol related functions
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* <h2><center>© COPYRIGHT 2015 STMicroelectronics</center></h2>
|
||||
*
|
||||
* Licensed under MCD-ST Liberty SW License Agreement V2, (the "License");
|
||||
* You may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at:
|
||||
*
|
||||
* http://www.st.com/software_license_agreement_liberty_v2
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
******************************************************************************
|
||||
*
|
||||
* Modifications by Robert Fisk
|
||||
*/
|
||||
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include "usbh_msc_bot.h"
|
||||
#include "usbh_msc.h"
|
||||
#include "downstream_spi.h"
|
||||
#include "downstream_msc.h"
|
||||
#include "downstream_statemachine.h"
|
||||
#include "build_config.h"
|
||||
|
||||
|
||||
#ifdef CONFIG_MASS_STORAGE_ENABLED
|
||||
|
||||
static USBH_StatusTypeDef USBH_MSC_BOT_Abort(USBH_HandleTypeDef *phost, uint8_t lun, uint8_t dir);
|
||||
static BOT_CSWStatusTypeDef USBH_MSC_DecodeCSW(USBH_HandleTypeDef *phost);
|
||||
void USBH_MSC_BOT_Read_Multipacket_FreePacketCallback(DownstreamPacketTypeDef* freePacket);
|
||||
void USBH_MSC_BOT_Read_Multipacket_PrepareURB(USBH_HandleTypeDef *phost);
|
||||
void USBH_MSC_BOT_Write_Multipacket_ReceivePacketCallback(DownstreamPacketTypeDef* receivedPacket,
|
||||
uint16_t dataLength);
|
||||
void USBH_MSC_BOT_Write_Multipacket_PrepareURB(USBH_HandleTypeDef *phost);
|
||||
|
||||
|
||||
|
||||
USBH_HandleTypeDef *Callback_MSC_phost;
|
||||
|
||||
|
||||
/**
|
||||
* @brief USBH_MSC_BOT_REQ_Reset
|
||||
* The function the MSC BOT Reset request.
|
||||
* @param phost: Host handle
|
||||
* @retval USBH Status
|
||||
*/
|
||||
USBH_StatusTypeDef USBH_MSC_BOT_REQ_Reset(USBH_HandleTypeDef *phost)
|
||||
{
|
||||
if (phost->RequestState == CMD_SEND)
|
||||
{
|
||||
phost->Control.setup.b.bmRequestType = USB_H2D |
|
||||
USB_REQ_TYPE_CLASS |
|
||||
USB_REQ_RECIPIENT_INTERFACE;
|
||||
|
||||
phost->Control.setup.b.bRequest = USB_REQ_BOT_RESET;
|
||||
phost->Control.setup.b.wValue.w = 0;
|
||||
phost->Control.setup.b.wIndex.w = 0;
|
||||
phost->Control.setup.b.wLength.w = 0;
|
||||
}
|
||||
|
||||
return USBH_CtlReq(phost, 0 , 0 );
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief USBH_MSC_BOT_REQ_GetMaxLUN
|
||||
* The function the MSC BOT GetMaxLUN request.
|
||||
* @param phost: Host handle
|
||||
* @param Maxlun: pointer to Maxlun variable
|
||||
* @retval USBH Status
|
||||
*/
|
||||
USBH_StatusTypeDef USBH_MSC_BOT_REQ_GetMaxLUN(USBH_HandleTypeDef *phost, uint8_t *Maxlun)
|
||||
{
|
||||
if (phost->RequestState == CMD_SEND)
|
||||
{
|
||||
phost->Control.setup.b.bmRequestType = USB_D2H |
|
||||
USB_REQ_TYPE_CLASS |
|
||||
USB_REQ_RECIPIENT_INTERFACE;
|
||||
|
||||
phost->Control.setup.b.bRequest = USB_REQ_GET_MAX_LUN;
|
||||
phost->Control.setup.b.wValue.w = 0;
|
||||
phost->Control.setup.b.wIndex.w = 0;
|
||||
phost->Control.setup.b.wLength.w = 1;
|
||||
}
|
||||
|
||||
return USBH_CtlReq(phost, Maxlun , 1 );
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @brief USBH_MSC_BOT_Init
|
||||
* The function Initializes the BOT protocol.
|
||||
* @param phost: Host handle
|
||||
* @retval USBH Status
|
||||
*/
|
||||
USBH_StatusTypeDef USBH_MSC_BOT_Init(USBH_HandleTypeDef *phost)
|
||||
{
|
||||
|
||||
MSC_HandleTypeDef *MSC_Handle = (MSC_HandleTypeDef *) phost->pActiveClass->pData;
|
||||
|
||||
MSC_Handle->hbot.cbw.field.Signature = BOT_CBW_SIGNATURE;
|
||||
MSC_Handle->hbot.cbw.field.Tag = BOT_CBW_TAG;
|
||||
MSC_Handle->hbot.state = BOT_SEND_CBW;
|
||||
MSC_Handle->hbot.cmd_state = BOT_CMD_SEND;
|
||||
|
||||
return USBH_OK;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @brief USBH_MSC_BOT_Process
|
||||
* The function handle the BOT protocol.
|
||||
* @param phost: Host handle
|
||||
* @param lun: Logical Unit Number
|
||||
* @retval USBH Status
|
||||
*/
|
||||
USBH_StatusTypeDef USBH_MSC_BOT_Process (USBH_HandleTypeDef *phost, uint8_t lun)
|
||||
{
|
||||
USBH_StatusTypeDef status = USBH_BUSY;
|
||||
USBH_StatusTypeDef error = USBH_BUSY;
|
||||
BOT_CSWStatusTypeDef CSW_Status = BOT_CSW_CMD_FAILED;
|
||||
USBH_URBStateTypeDef URB_Status = USBH_URB_IDLE;
|
||||
MSC_HandleTypeDef *MSC_Handle = (MSC_HandleTypeDef *) phost->pActiveClass->pData;
|
||||
uint32_t partialTransferLength;
|
||||
uint8_t toggle = 0;
|
||||
|
||||
switch (MSC_Handle->hbot.state)
|
||||
{
|
||||
case BOT_SEND_CBW:
|
||||
MSC_Handle->hbot.cbw.field.LUN = lun;
|
||||
MSC_Handle->hbot.state = BOT_SEND_CBW_WAIT;
|
||||
USBH_BulkSendData (phost,
|
||||
MSC_Handle->hbot.cbw.data,
|
||||
BOT_CBW_LENGTH,
|
||||
MSC_Handle->OutPipe,
|
||||
1);
|
||||
break;
|
||||
|
||||
case BOT_SEND_CBW_WAIT:
|
||||
|
||||
URB_Status = USBH_LL_GetURBState(phost, MSC_Handle->OutPipe);
|
||||
|
||||
if(URB_Status == USBH_URB_DONE)
|
||||
{
|
||||
if ( MSC_Handle->hbot.cbw.field.DataTransferLength != 0 )
|
||||
{
|
||||
/* If there is Data Transfer Stage */
|
||||
if (((MSC_Handle->hbot.cbw.field.Flags) & USB_REQ_DIR_MASK) == USB_D2H)
|
||||
{
|
||||
/* Data Direction is IN */
|
||||
MSC_Handle->hbot.state = BOT_DATA_IN;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Data Direction is OUT */
|
||||
MSC_Handle->hbot.state = BOT_DATA_OUT;
|
||||
}
|
||||
}
|
||||
|
||||
else
|
||||
{/* If there is NO Data Transfer Stage */
|
||||
MSC_Handle->hbot.state = BOT_RECEIVE_CSW;
|
||||
}
|
||||
|
||||
}
|
||||
else if(URB_Status == USBH_URB_NOTREADY)
|
||||
{
|
||||
/* Re-send CBW */
|
||||
MSC_Handle->hbot.state = BOT_SEND_CBW;
|
||||
}
|
||||
else if(URB_Status == USBH_URB_STALL)
|
||||
{
|
||||
MSC_Handle->hbot.state = BOT_ERROR_OUT;
|
||||
}
|
||||
break;
|
||||
|
||||
case BOT_DATA_IN:
|
||||
if (MSC_Handle->hbot.pbuf != NULL)
|
||||
{
|
||||
//Simple single-buffer operation
|
||||
MSC_Handle->hbot.state = BOT_DATA_IN_WAIT;
|
||||
MSC_Handle->hbot.this_URB_size = MIN(MSC_Handle->hbot.cbw.field.DataTransferLength,
|
||||
MSC_Handle->InEpSize);
|
||||
USBH_BulkReceiveData (phost,
|
||||
MSC_Handle->hbot.pbuf,
|
||||
MSC_Handle->hbot.this_URB_size,
|
||||
MSC_Handle->InPipe);
|
||||
}
|
||||
else
|
||||
{
|
||||
//Asynchronous multi-packet operation: get first packet
|
||||
MSC_Handle->hbot.state = BOT_DATA_IN_WAIT_FREE_PACKET;
|
||||
Callback_MSC_phost = phost;
|
||||
if (Downstream_GetFreePacket(USBH_MSC_BOT_Read_Multipacket_FreePacketCallback) != HAL_OK)
|
||||
{
|
||||
MSC_Handle->hbot.state = BOT_ERROR_IN;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case BOT_DATA_IN_WAIT_FREE_PACKET:
|
||||
break;
|
||||
|
||||
case BOT_DATA_IN_WAIT:
|
||||
URB_Status = USBH_LL_GetURBState(phost, MSC_Handle->InPipe);
|
||||
|
||||
if (URB_Status == USBH_URB_DONE)
|
||||
{
|
||||
if (USBH_LL_GetLastXferSize(phost, MSC_Handle->InPipe) != MSC_Handle->hbot.this_URB_size)
|
||||
{
|
||||
while(1);
|
||||
}
|
||||
|
||||
MSC_Handle->hbot.cbw.field.DataTransferLength -= MSC_Handle->hbot.this_URB_size;
|
||||
|
||||
if (MSC_Handle->hbot.pbuf != NULL)
|
||||
{
|
||||
//Simple single-buffer operation: everything must fit in one URB
|
||||
MSC_Handle->hbot.state = BOT_RECEIVE_CSW;
|
||||
}
|
||||
else
|
||||
{
|
||||
//Asynchronous multi-packet operation
|
||||
MSC_Handle->hbot.bot_packet_bytes_remaining -= MSC_Handle->hbot.this_URB_size;
|
||||
MSC_Handle->hbot.bot_packet_pbuf += MSC_Handle->hbot.this_URB_size;
|
||||
|
||||
if (MSC_Handle->hbot.cbw.field.DataTransferLength == 0)
|
||||
{
|
||||
//End of reception: dispatch last packet
|
||||
MSC_Handle->hbot.state = BOT_RECEIVE_CSW;
|
||||
Downstream_MSC_PutStreamDataPacket(MSC_Handle->hbot.bot_packet,
|
||||
(BOT_PAGE_LENGTH - MSC_Handle->hbot.bot_packet_bytes_remaining));
|
||||
}
|
||||
else
|
||||
{
|
||||
//Still more data to receive
|
||||
// if (MSC_Handle->hbot.bot_packet_bytes_remaining == 0)
|
||||
// {
|
||||
//Dispatch current bot_packet, then get a new one
|
||||
if (Downstream_MSC_PutStreamDataPacket(MSC_Handle->hbot.bot_packet,
|
||||
BOT_PAGE_LENGTH) != HAL_OK)
|
||||
{
|
||||
MSC_Handle->hbot.state = BOT_ERROR_IN;
|
||||
break;
|
||||
}
|
||||
MSC_Handle->hbot.state = BOT_DATA_IN_WAIT_FREE_PACKET;
|
||||
if (Downstream_GetFreePacket(USBH_MSC_BOT_Read_Multipacket_FreePacketCallback) != HAL_OK)
|
||||
{
|
||||
MSC_Handle->hbot.state = BOT_ERROR_IN;
|
||||
break;
|
||||
}
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// //Continue filling the current bot_packet
|
||||
// USBH_MSC_BOT_Read_Multipacket_PrepareURB(phost);
|
||||
// }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
else if (URB_Status == USBH_URB_STALL)
|
||||
{
|
||||
/* This is Data IN Stage STALL Condition */
|
||||
MSC_Handle->hbot.state = BOT_ERROR_IN;
|
||||
|
||||
/* Refer to USB Mass-Storage Class : BOT (www.usb.org)
|
||||
6.7.2 Host expects to receive data from the device
|
||||
3. On a STALL condition receiving data, then:
|
||||
The host shall accept the data received.
|
||||
The host shall clear the Bulk-In pipe.
|
||||
4. The host shall attempt to receive a CSW.*/
|
||||
}
|
||||
break;
|
||||
|
||||
case BOT_DATA_OUT:
|
||||
if (MSC_Handle->hbot.pbuf != NULL)
|
||||
{
|
||||
//Simple single-buffer operation
|
||||
MSC_Handle->hbot.state = BOT_DATA_OUT_WAIT;
|
||||
MSC_Handle->hbot.this_URB_size = MIN(MSC_Handle->hbot.cbw.field.DataTransferLength,
|
||||
MSC_Handle->OutEpSize);
|
||||
USBH_BulkSendData (phost,
|
||||
MSC_Handle->hbot.pbuf,
|
||||
MSC_Handle->hbot.this_URB_size,
|
||||
MSC_Handle->OutPipe,
|
||||
1);
|
||||
}
|
||||
#ifdef CONFIG_MASS_STORAGE_WRITES_PERMITTED
|
||||
else
|
||||
{
|
||||
//Asynchronous multi-packet operation: get first packet
|
||||
MSC_Handle->hbot.state = BOT_DATA_OUT_WAIT_RECEIVE_PACKET;
|
||||
Callback_MSC_phost = phost;
|
||||
if (Downstream_MSC_GetStreamDataPacket(USBH_MSC_BOT_Write_Multipacket_ReceivePacketCallback) != HAL_OK)
|
||||
{
|
||||
MSC_Handle->hbot.state = BOT_ERROR_OUT;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
break;
|
||||
|
||||
case BOT_DATA_OUT_WAIT_RECEIVE_PACKET:
|
||||
break;
|
||||
|
||||
case BOT_DATA_OUT_WAIT:
|
||||
URB_Status = USBH_LL_GetURBState(phost, MSC_Handle->OutPipe);
|
||||
|
||||
if(URB_Status == USBH_URB_DONE)
|
||||
{
|
||||
MSC_Handle->hbot.cbw.field.DataTransferLength -= MSC_Handle->hbot.this_URB_size;
|
||||
|
||||
if (MSC_Handle->hbot.pbuf != NULL)
|
||||
{
|
||||
//Simple single-buffer operation: everything must fit in one URB
|
||||
MSC_Handle->hbot.state = BOT_RECEIVE_CSW;
|
||||
}
|
||||
#ifdef CONFIG_MASS_STORAGE_WRITES_PERMITTED
|
||||
else
|
||||
{
|
||||
//Asynchronous multi-packet operation
|
||||
MSC_Handle->hbot.bot_packet_bytes_remaining -= MSC_Handle->hbot.this_URB_size;
|
||||
MSC_Handle->hbot.bot_packet_pbuf += MSC_Handle->hbot.this_URB_size;
|
||||
if (MSC_Handle->hbot.cbw.field.DataTransferLength == 0)
|
||||
{
|
||||
//End of transmission
|
||||
Downstream_ReleasePacket(MSC_Handle->hbot.bot_packet);
|
||||
MSC_Handle->hbot.state = BOT_RECEIVE_CSW;
|
||||
}
|
||||
else
|
||||
{
|
||||
//Still more data to send
|
||||
if (MSC_Handle->hbot.bot_packet_bytes_remaining == 0)
|
||||
{
|
||||
//Get next bot_packet
|
||||
Downstream_ReleasePacket(MSC_Handle->hbot.bot_packet);
|
||||
MSC_Handle->hbot.state = BOT_DATA_OUT_WAIT_RECEIVE_PACKET;
|
||||
if (Downstream_MSC_GetStreamDataPacket(USBH_MSC_BOT_Write_Multipacket_ReceivePacketCallback) != HAL_OK)
|
||||
{
|
||||
MSC_Handle->hbot.state = BOT_ERROR_OUT;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
//Continue writing the current bot_packet
|
||||
USBH_MSC_BOT_Write_Multipacket_PrepareURB(phost);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
else if(URB_Status == USBH_URB_NOTREADY)
|
||||
{
|
||||
/* Resend same data */
|
||||
if (MSC_Handle->hbot.pbuf != NULL)
|
||||
{
|
||||
MSC_Handle->hbot.state = BOT_DATA_OUT;
|
||||
}
|
||||
#ifdef CONFIG_MASS_STORAGE_WRITES_PERMITTED
|
||||
else
|
||||
{
|
||||
//Increment counters by the amount of data actually transferred during the NAK'd URB
|
||||
partialTransferLength = USBH_LL_GetLastXferSize(phost, MSC_Handle->OutPipe);
|
||||
MSC_Handle->hbot.cbw.field.DataTransferLength -= partialTransferLength;
|
||||
MSC_Handle->hbot.bot_packet_bytes_remaining -= partialTransferLength;
|
||||
MSC_Handle->hbot.bot_packet_pbuf += partialTransferLength;
|
||||
|
||||
USBH_MSC_BOT_Write_Multipacket_PrepareURB(phost);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
else if(URB_Status == USBH_URB_STALL)
|
||||
{
|
||||
MSC_Handle->hbot.state = BOT_ERROR_OUT;
|
||||
|
||||
/* Refer to USB Mass-Storage Class : BOT (www.usb.org)
|
||||
6.7.3 Ho - Host expects to send data to the device
|
||||
3. On a STALL condition sending data, then:
|
||||
" The host shall clear the Bulk-Out pipe.
|
||||
4. The host shall attempt to receive a CSW.
|
||||
*/
|
||||
}
|
||||
break;
|
||||
|
||||
case BOT_RECEIVE_CSW:
|
||||
|
||||
USBH_BulkReceiveData (phost,
|
||||
MSC_Handle->hbot.csw.data,
|
||||
BOT_CSW_LENGTH ,
|
||||
MSC_Handle->InPipe);
|
||||
|
||||
MSC_Handle->hbot.state = BOT_RECEIVE_CSW_WAIT;
|
||||
break;
|
||||
|
||||
case BOT_RECEIVE_CSW_WAIT:
|
||||
|
||||
URB_Status = USBH_LL_GetURBState(phost, MSC_Handle->InPipe);
|
||||
|
||||
/* Decode CSW */
|
||||
if(URB_Status == USBH_URB_DONE)
|
||||
{
|
||||
MSC_Handle->hbot.state = BOT_SEND_CBW;
|
||||
MSC_Handle->hbot.cmd_state = BOT_CMD_SEND;
|
||||
CSW_Status = USBH_MSC_DecodeCSW(phost);
|
||||
|
||||
if(CSW_Status == BOT_CSW_CMD_PASSED)
|
||||
{
|
||||
status = USBH_OK;
|
||||
}
|
||||
else
|
||||
{
|
||||
status = USBH_FAIL;
|
||||
}
|
||||
}
|
||||
else if(URB_Status == USBH_URB_STALL)
|
||||
{
|
||||
MSC_Handle->hbot.state = BOT_ERROR_IN;
|
||||
}
|
||||
break;
|
||||
|
||||
case BOT_ERROR_IN:
|
||||
error = USBH_MSC_BOT_Abort(phost, lun, BOT_DIR_IN);
|
||||
|
||||
if (error == USBH_OK)
|
||||
{
|
||||
MSC_Handle->hbot.state = BOT_RECEIVE_CSW;
|
||||
}
|
||||
else if (error == USBH_UNRECOVERED_ERROR)
|
||||
{
|
||||
/* This means that there is a STALL Error limit, Do Reset Recovery */
|
||||
MSC_Handle->hbot.state = BOT_UNRECOVERED_ERROR;
|
||||
}
|
||||
break;
|
||||
|
||||
case BOT_ERROR_OUT:
|
||||
error = USBH_MSC_BOT_Abort(phost, lun, BOT_DIR_OUT);
|
||||
|
||||
if ( error == USBH_OK)
|
||||
{
|
||||
|
||||
toggle = USBH_LL_GetToggle(phost, MSC_Handle->OutPipe);
|
||||
USBH_LL_SetToggle(phost, MSC_Handle->OutPipe, 1- toggle);
|
||||
USBH_LL_SetToggle(phost, MSC_Handle->InPipe, 0);
|
||||
MSC_Handle->hbot.state = BOT_ERROR_IN;
|
||||
}
|
||||
else if (error == USBH_UNRECOVERED_ERROR)
|
||||
{
|
||||
MSC_Handle->hbot.state = BOT_UNRECOVERED_ERROR;
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
case BOT_UNRECOVERED_ERROR:
|
||||
status = USBH_MSC_BOT_REQ_Reset(phost);
|
||||
if ( status == USBH_OK)
|
||||
{
|
||||
MSC_Handle->hbot.state = BOT_SEND_CBW;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
void USBH_MSC_BOT_Read_Multipacket_FreePacketCallback(DownstreamPacketTypeDef* freePacket)
|
||||
{
|
||||
MSC_HandleTypeDef *MSC_Handle = (MSC_HandleTypeDef *) Callback_MSC_phost->pActiveClass->pData;
|
||||
|
||||
if (MSC_Handle->hbot.state != BOT_DATA_IN_WAIT_FREE_PACKET)
|
||||
{
|
||||
Downstream_PacketProcessor_FreakOut();
|
||||
return;
|
||||
}
|
||||
|
||||
MSC_Handle->hbot.state = BOT_DATA_IN_WAIT;
|
||||
MSC_Handle->hbot.bot_packet = freePacket;
|
||||
MSC_Handle->hbot.bot_packet_pbuf = freePacket->Data;
|
||||
MSC_Handle->hbot.bot_packet_bytes_remaining = BOT_PAGE_LENGTH;
|
||||
USBH_MSC_BOT_Read_Multipacket_PrepareURB(Callback_MSC_phost);
|
||||
}
|
||||
|
||||
|
||||
void USBH_MSC_BOT_Read_Multipacket_PrepareURB(USBH_HandleTypeDef *phost)
|
||||
{
|
||||
uint32_t temp_URB_size;
|
||||
MSC_HandleTypeDef *MSC_Handle = (MSC_HandleTypeDef *) phost->pActiveClass->pData;
|
||||
|
||||
temp_URB_size = MSC_Handle->hbot.cbw.field.DataTransferLength;
|
||||
if (temp_URB_size > MSC_Handle->hbot.bot_packet_bytes_remaining)
|
||||
{
|
||||
temp_URB_size = MSC_Handle->hbot.bot_packet_bytes_remaining;
|
||||
}
|
||||
// if (temp_URB_size > MSC_Handle->InEpSize)
|
||||
// {
|
||||
// temp_URB_size = MSC_Handle->InEpSize;
|
||||
// }
|
||||
MSC_Handle->hbot.this_URB_size = (uint16_t)temp_URB_size;
|
||||
|
||||
USBH_BulkReceiveData(phost,
|
||||
MSC_Handle->hbot.bot_packet_pbuf,
|
||||
MSC_Handle->hbot.this_URB_size,
|
||||
MSC_Handle->InPipe);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_MASS_STORAGE_WRITES_PERMITTED
|
||||
void USBH_MSC_BOT_Write_Multipacket_ReceivePacketCallback(DownstreamPacketTypeDef* receivedPacket,
|
||||
uint16_t dataLength)
|
||||
{
|
||||
MSC_HandleTypeDef *MSC_Handle = (MSC_HandleTypeDef *) Callback_MSC_phost->pActiveClass->pData;
|
||||
|
||||
if (MSC_Handle->hbot.state != BOT_DATA_OUT_WAIT_RECEIVE_PACKET)
|
||||
{
|
||||
Downstream_PacketProcessor_FreakOut();
|
||||
return;
|
||||
}
|
||||
|
||||
MSC_Handle->hbot.state = BOT_DATA_OUT_WAIT;
|
||||
MSC_Handle->hbot.bot_packet = receivedPacket;
|
||||
MSC_Handle->hbot.bot_packet_pbuf = receivedPacket->Data;
|
||||
MSC_Handle->hbot.bot_packet_bytes_remaining = dataLength;
|
||||
USBH_MSC_BOT_Write_Multipacket_PrepareURB(Callback_MSC_phost);
|
||||
}
|
||||
|
||||
|
||||
void USBH_MSC_BOT_Write_Multipacket_PrepareURB(USBH_HandleTypeDef *phost)
|
||||
{
|
||||
uint32_t temp_URB_size;
|
||||
MSC_HandleTypeDef *MSC_Handle = (MSC_HandleTypeDef *) phost->pActiveClass->pData;
|
||||
|
||||
temp_URB_size = MSC_Handle->hbot.cbw.field.DataTransferLength;
|
||||
if (temp_URB_size > MSC_Handle->hbot.bot_packet_bytes_remaining)
|
||||
{
|
||||
temp_URB_size = MSC_Handle->hbot.bot_packet_bytes_remaining;
|
||||
}
|
||||
if (temp_URB_size > MSC_Handle->OutEpSize)// * 4) //Some silicon has a buggy host fifo, so we write single packets only :(
|
||||
{
|
||||
temp_URB_size = MSC_Handle->OutEpSize;// * 4;
|
||||
}
|
||||
MSC_Handle->hbot.this_URB_size = (uint16_t)temp_URB_size;
|
||||
|
||||
USBH_BulkSendData (phost,
|
||||
MSC_Handle->hbot.bot_packet_pbuf,
|
||||
MSC_Handle->hbot.this_URB_size,
|
||||
MSC_Handle->OutPipe,
|
||||
1);
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief USBH_MSC_BOT_Abort
|
||||
* The function handle the BOT Abort process.
|
||||
* @param phost: Host handle
|
||||
* @param lun: Logical Unit Number
|
||||
* @param dir: direction (0: out / 1 : in)
|
||||
* @retval USBH Status
|
||||
*/
|
||||
static USBH_StatusTypeDef USBH_MSC_BOT_Abort(USBH_HandleTypeDef *phost, uint8_t lun, uint8_t dir)
|
||||
{
|
||||
UNUSED(lun);
|
||||
USBH_StatusTypeDef status = USBH_FAIL;
|
||||
MSC_HandleTypeDef *MSC_Handle = (MSC_HandleTypeDef *) phost->pActiveClass->pData;
|
||||
|
||||
switch (dir)
|
||||
{
|
||||
case BOT_DIR_IN :
|
||||
/* send ClrFeture on Bulk IN endpoint */
|
||||
status = USBH_ClrFeature(phost, MSC_Handle->InEp);
|
||||
|
||||
break;
|
||||
|
||||
case BOT_DIR_OUT :
|
||||
/*send ClrFeature on Bulk OUT endpoint */
|
||||
status = USBH_ClrFeature(phost, MSC_Handle->OutEp);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief USBH_MSC_BOT_DecodeCSW
|
||||
* This function decodes the CSW received by the device and updates the
|
||||
* same to upper layer.
|
||||
* @param phost: Host handle
|
||||
* @retval USBH Status
|
||||
* @notes
|
||||
* Refer to USB Mass-Storage Class : BOT (www.usb.org)
|
||||
* 6.3.1 Valid CSW Conditions :
|
||||
* The host shall consider the CSW valid when:
|
||||
* 1. dCSWSignature is equal to 53425355h
|
||||
* 2. the CSW is 13 (Dh) bytes in length,
|
||||
* 3. dCSWTag matches the dCBWTag from the corresponding CBW.
|
||||
*/
|
||||
|
||||
static BOT_CSWStatusTypeDef USBH_MSC_DecodeCSW(USBH_HandleTypeDef *phost)
|
||||
{
|
||||
MSC_HandleTypeDef *MSC_Handle = (MSC_HandleTypeDef *) phost->pActiveClass->pData;
|
||||
BOT_CSWStatusTypeDef status = BOT_CSW_CMD_FAILED;
|
||||
|
||||
/*Checking if the transfer length is different than 13*/
|
||||
if(USBH_LL_GetLastXferSize(phost, MSC_Handle->InPipe) != BOT_CSW_LENGTH)
|
||||
{
|
||||
/*(4) Hi > Dn (Host expects to receive data from the device,
|
||||
Device intends to transfer no data)
|
||||
(5) Hi > Di (Host expects to receive data from the device,
|
||||
Device intends to send data to the host)
|
||||
(9) Ho > Dn (Host expects to send data to the device,
|
||||
Device intends to transfer no data)
|
||||
(11) Ho > Do (Host expects to send data to the device,
|
||||
Device intends to receive data from the host)*/
|
||||
|
||||
|
||||
status = BOT_CSW_PHASE_ERROR;
|
||||
}
|
||||
else
|
||||
{ /* CSW length is Correct */
|
||||
|
||||
/* Check validity of the CSW Signature and CSWStatus */
|
||||
if(MSC_Handle->hbot.csw.field.Signature == BOT_CSW_SIGNATURE)
|
||||
{/* Check Condition 1. dCSWSignature is equal to 53425355h */
|
||||
|
||||
if(MSC_Handle->hbot.csw.field.Tag == MSC_Handle->hbot.cbw.field.Tag)
|
||||
{
|
||||
/* Check Condition 3. dCSWTag matches the dCBWTag from the
|
||||
corresponding CBW */
|
||||
|
||||
if(MSC_Handle->hbot.csw.field.Status == 0)
|
||||
{
|
||||
/* Refer to USB Mass-Storage Class : BOT (www.usb.org)
|
||||
|
||||
Hn Host expects no data transfers
|
||||
Hi Host expects to receive data from the device
|
||||
Ho Host expects to send data to the device
|
||||
|
||||
Dn Device intends to transfer no data
|
||||
Di Device intends to send data to the host
|
||||
Do Device intends to receive data from the host
|
||||
|
||||
Section 6.7
|
||||
(1) Hn = Dn (Host expects no data transfers,
|
||||
Device intends to transfer no data)
|
||||
(6) Hi = Di (Host expects to receive data from the device,
|
||||
Device intends to send data to the host)
|
||||
(12) Ho = Do (Host expects to send data to the device,
|
||||
Device intends to receive data from the host)
|
||||
|
||||
*/
|
||||
|
||||
status = BOT_CSW_CMD_PASSED;
|
||||
}
|
||||
else if(MSC_Handle->hbot.csw.field.Status == 1)
|
||||
{
|
||||
status = BOT_CSW_CMD_FAILED;
|
||||
}
|
||||
|
||||
else if(MSC_Handle->hbot.csw.field.Status == 2)
|
||||
{
|
||||
/* Refer to USB Mass-Storage Class : BOT (www.usb.org)
|
||||
Section 6.7
|
||||
(2) Hn < Di ( Host expects no data transfers,
|
||||
Device intends to send data to the host)
|
||||
(3) Hn < Do ( Host expects no data transfers,
|
||||
Device intends to receive data from the host)
|
||||
(7) Hi < Di ( Host expects to receive data from the device,
|
||||
Device intends to send data to the host)
|
||||
(8) Hi <> Do ( Host expects to receive data from the device,
|
||||
Device intends to receive data from the host)
|
||||
(10) Ho <> Di (Host expects to send data to the device,
|
||||
Di Device intends to send data to the host)
|
||||
(13) Ho < Do (Host expects to send data to the device,
|
||||
Device intends to receive data from the host)
|
||||
*/
|
||||
|
||||
status = BOT_CSW_PHASE_ERROR;
|
||||
}
|
||||
} /* CSW Tag Matching is Checked */
|
||||
} /* CSW Signature Correct Checking */
|
||||
else
|
||||
{
|
||||
/* If the CSW Signature is not valid, We sall return the Phase Error to
|
||||
Upper Layers for Reset Recovery */
|
||||
|
||||
status = BOT_CSW_PHASE_ERROR;
|
||||
}
|
||||
} /* CSW Length Check*/
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
#endif //#ifdef CONFIG_MASS_STORAGE_ENABLED
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
|
||||
|
||||
|
||||
|
@ -0,0 +1,473 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file usbh_msc_scsi.c
|
||||
* @author MCD Application Team
|
||||
* @version V3.2.1
|
||||
* @date 26-June-2015
|
||||
* @brief This file implements the SCSI commands
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* <h2><center>© COPYRIGHT 2015 STMicroelectronics</center></h2>
|
||||
*
|
||||
* Licensed under MCD-ST Liberty SW License Agreement V2, (the "License");
|
||||
* You may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at:
|
||||
*
|
||||
* http://www.st.com/software_license_agreement_liberty_v2
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
******************************************************************************
|
||||
*
|
||||
* Modifications by Robert Fisk
|
||||
*/
|
||||
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include "usbh_msc.h"
|
||||
#include "usbh_msc_scsi.h"
|
||||
#include "usbh_msc_bot.h"
|
||||
#include "build_config.h"
|
||||
|
||||
|
||||
#ifdef CONFIG_MASS_STORAGE_ENABLED
|
||||
|
||||
/** @addtogroup USBH_LIB
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @addtogroup USBH_CLASS
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @addtogroup USBH_MSC_CLASS
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @defgroup USBH_MSC_SCSI
|
||||
* @brief This file includes the mass storage related functions
|
||||
* @{
|
||||
*/
|
||||
|
||||
|
||||
/** @defgroup USBH_MSC_SCSI_Private_TypesDefinitions
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @defgroup USBH_MSC_SCSI_Private_Defines
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @defgroup USBH_MSC_SCSI_Private_Macros
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
|
||||
/** @defgroup USBH_MSC_SCSI_Private_FunctionPrototypes
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
|
||||
/** @defgroup USBH_MSC_SCSI_Exported_Variables
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
|
||||
/** @defgroup USBH_MSC_SCSI_Private_Functions
|
||||
* @{
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* @brief USBH_MSC_SCSI_TestUnitReady
|
||||
* Issue TestUnitReady command.
|
||||
* @param phost: Host handle
|
||||
* @param lun: Logical Unit Number
|
||||
* @retval USBH Status
|
||||
*/
|
||||
USBH_StatusTypeDef USBH_MSC_SCSI_TestUnitReady (USBH_HandleTypeDef *phost,
|
||||
uint8_t lun)
|
||||
{
|
||||
MSC_HandleTypeDef *MSC_Handle = (MSC_HandleTypeDef *) phost->pActiveClass->pData;
|
||||
|
||||
if (MSC_Handle->hbot.cmd_state == BOT_CMD_SEND)
|
||||
{
|
||||
/*Prepare the CBW and relevent field*/
|
||||
MSC_Handle->hbot.cbw.field.DataTransferLength = DATA_LEN_MODE_TEST_UNIT_READY;
|
||||
MSC_Handle->hbot.cbw.field.Flags = USB_EP_DIR_OUT;
|
||||
MSC_Handle->hbot.cbw.field.CBLength = CBW_LENGTH;
|
||||
|
||||
USBH_memset(MSC_Handle->hbot.cbw.field.CB, 0, CBW_CB_LENGTH);
|
||||
MSC_Handle->hbot.cbw.field.CB[0] = OPCODE_TEST_UNIT_READY;
|
||||
|
||||
MSC_Handle->hbot.state = BOT_SEND_CBW;
|
||||
MSC_Handle->hbot.cmd_state = BOT_CMD_WAIT;
|
||||
}
|
||||
|
||||
return USBH_MSC_BOT_Process(phost, lun);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief USBH_MSC_SCSI_ReadCapacity
|
||||
* Issue Read Capacity command.
|
||||
* @param phost: Host handle
|
||||
* @param lun: Logical Unit Number
|
||||
* @param capacity: pointer to the capacity structure
|
||||
* @retval USBH Status
|
||||
*/
|
||||
USBH_StatusTypeDef USBH_MSC_SCSI_ReadCapacity (USBH_HandleTypeDef *phost,
|
||||
uint8_t lun,
|
||||
SCSI_CapacityTypeDef *capacity)
|
||||
{
|
||||
USBH_StatusTypeDef error = USBH_BUSY ;
|
||||
MSC_HandleTypeDef *MSC_Handle = (MSC_HandleTypeDef *) phost->pActiveClass->pData;
|
||||
|
||||
switch(MSC_Handle->hbot.cmd_state)
|
||||
{
|
||||
case BOT_CMD_SEND:
|
||||
|
||||
/*Prepare the CBW and relevent field*/
|
||||
MSC_Handle->hbot.cbw.field.DataTransferLength = DATA_LEN_READ_CAPACITY10;
|
||||
MSC_Handle->hbot.cbw.field.Flags = USB_EP_DIR_IN;
|
||||
MSC_Handle->hbot.cbw.field.CBLength = CBW_LENGTH;
|
||||
|
||||
USBH_memset(MSC_Handle->hbot.cbw.field.CB, 0, CBW_CB_LENGTH);
|
||||
MSC_Handle->hbot.cbw.field.CB[0] = OPCODE_READ_CAPACITY10;
|
||||
|
||||
MSC_Handle->hbot.state = BOT_SEND_CBW;
|
||||
|
||||
MSC_Handle->hbot.cmd_state = BOT_CMD_WAIT;
|
||||
MSC_Handle->hbot.pbuf = (uint8_t *)MSC_Handle->hbot.data;
|
||||
error = USBH_BUSY;
|
||||
break;
|
||||
|
||||
case BOT_CMD_WAIT:
|
||||
|
||||
error = USBH_MSC_BOT_Process(phost, lun);
|
||||
|
||||
if(error == USBH_OK)
|
||||
{
|
||||
/*assign the capacity*/
|
||||
capacity->block_nbr = (MSC_Handle->hbot.pbuf[3] | (MSC_Handle->hbot.pbuf[2] << 8) |\
|
||||
(MSC_Handle->hbot.pbuf[1] << 16) | (MSC_Handle->hbot.pbuf[0] << 24)) + 1; //block_nbr = logical address of last block + 1
|
||||
|
||||
/*assign the page length*/
|
||||
capacity->block_size = MSC_Handle->hbot.pbuf[7] | (MSC_Handle->hbot.pbuf[6] << 8);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief USBH_MSC_SCSI_Inquiry
|
||||
* Issue Inquiry command.
|
||||
* @param phost: Host handle
|
||||
* @param lun: Logical Unit Number
|
||||
* @param capacity: pointer to the inquiry structure
|
||||
* @retval USBH Status
|
||||
*/
|
||||
USBH_StatusTypeDef USBH_MSC_SCSI_Inquiry (USBH_HandleTypeDef *phost,
|
||||
uint8_t lun,
|
||||
SCSI_StdInquiryDataTypeDef *inquiry)
|
||||
{
|
||||
USBH_StatusTypeDef error = USBH_FAIL ;
|
||||
MSC_HandleTypeDef *MSC_Handle = (MSC_HandleTypeDef *) phost->pActiveClass->pData;
|
||||
switch(MSC_Handle->hbot.cmd_state)
|
||||
{
|
||||
case BOT_CMD_SEND:
|
||||
|
||||
/*Prepare the CBW and relevent field*/
|
||||
MSC_Handle->hbot.cbw.field.DataTransferLength = DATA_LEN_INQUIRY;
|
||||
MSC_Handle->hbot.cbw.field.Flags = USB_EP_DIR_IN;
|
||||
MSC_Handle->hbot.cbw.field.CBLength = CBW_LENGTH;
|
||||
|
||||
USBH_memset(MSC_Handle->hbot.cbw.field.CB, 0, CBW_LENGTH);
|
||||
MSC_Handle->hbot.cbw.field.CB[0] = OPCODE_INQUIRY;
|
||||
MSC_Handle->hbot.cbw.field.CB[1] = (lun << 5);
|
||||
MSC_Handle->hbot.cbw.field.CB[2] = 0;
|
||||
MSC_Handle->hbot.cbw.field.CB[3] = 0;
|
||||
MSC_Handle->hbot.cbw.field.CB[4] = 0x24;
|
||||
MSC_Handle->hbot.cbw.field.CB[5] = 0;
|
||||
|
||||
MSC_Handle->hbot.state = BOT_SEND_CBW;
|
||||
|
||||
MSC_Handle->hbot.cmd_state = BOT_CMD_WAIT;
|
||||
MSC_Handle->hbot.pbuf = (uint8_t *)MSC_Handle->hbot.data;
|
||||
error = USBH_BUSY;
|
||||
break;
|
||||
|
||||
case BOT_CMD_WAIT:
|
||||
|
||||
error = USBH_MSC_BOT_Process(phost, lun);
|
||||
|
||||
if(error == USBH_OK)
|
||||
{
|
||||
USBH_memset(inquiry, 0, sizeof(SCSI_StdInquiryDataTypeDef));
|
||||
/*assign Inquiry Data */
|
||||
inquiry->DeviceType = MSC_Handle->hbot.pbuf[0] & 0x1F;
|
||||
inquiry->PeripheralQualifier = MSC_Handle->hbot.pbuf[0] >> 5;
|
||||
inquiry->RemovableMedia = (MSC_Handle->hbot.pbuf[1] & 0x80)== 0x80;
|
||||
USBH_memcpy (inquiry->vendor_id, &MSC_Handle->hbot.pbuf[8], 8);
|
||||
USBH_memcpy (inquiry->product_id, &MSC_Handle->hbot.pbuf[16], 16);
|
||||
USBH_memcpy (inquiry->revision_id, &MSC_Handle->hbot.pbuf[32], 4);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief USBH_MSC_SCSI_RequestSense
|
||||
* Issue RequestSense command.
|
||||
* @param phost: Host handle
|
||||
* @param lun: Logical Unit Number
|
||||
* @param capacity: pointer to the sense data structure
|
||||
* @retval USBH Status
|
||||
*/
|
||||
USBH_StatusTypeDef USBH_MSC_SCSI_RequestSense (USBH_HandleTypeDef *phost,
|
||||
uint8_t lun,
|
||||
SCSI_SenseTypeDef *sense_data)
|
||||
{
|
||||
USBH_StatusTypeDef error = USBH_FAIL ;
|
||||
MSC_HandleTypeDef *MSC_Handle = (MSC_HandleTypeDef *) phost->pActiveClass->pData;
|
||||
|
||||
switch(MSC_Handle->hbot.cmd_state)
|
||||
{
|
||||
case BOT_CMD_SEND:
|
||||
|
||||
/*Prepare the CBW and relevent field*/
|
||||
MSC_Handle->hbot.cbw.field.DataTransferLength = DATA_LEN_REQUEST_SENSE;
|
||||
MSC_Handle->hbot.cbw.field.Flags = USB_EP_DIR_IN;
|
||||
MSC_Handle->hbot.cbw.field.CBLength = CBW_LENGTH;
|
||||
|
||||
USBH_memset(MSC_Handle->hbot.cbw.field.CB, 0, CBW_CB_LENGTH);
|
||||
MSC_Handle->hbot.cbw.field.CB[0] = OPCODE_REQUEST_SENSE;
|
||||
MSC_Handle->hbot.cbw.field.CB[1] = (lun << 5);
|
||||
MSC_Handle->hbot.cbw.field.CB[2] = 0;
|
||||
MSC_Handle->hbot.cbw.field.CB[3] = 0;
|
||||
MSC_Handle->hbot.cbw.field.CB[4] = DATA_LEN_REQUEST_SENSE;
|
||||
MSC_Handle->hbot.cbw.field.CB[5] = 0;
|
||||
|
||||
MSC_Handle->hbot.state = BOT_SEND_CBW;
|
||||
MSC_Handle->hbot.cmd_state = BOT_CMD_WAIT;
|
||||
MSC_Handle->hbot.pbuf = (uint8_t *)MSC_Handle->hbot.data;
|
||||
error = USBH_BUSY;
|
||||
break;
|
||||
|
||||
case BOT_CMD_WAIT:
|
||||
|
||||
error = USBH_MSC_BOT_Process(phost, lun);
|
||||
if (error == USBH_OK)
|
||||
{
|
||||
sense_data->key = MSC_Handle->hbot.pbuf[2] & 0x0F;
|
||||
sense_data->asc = MSC_Handle->hbot.pbuf[12];
|
||||
sense_data->ascq = MSC_Handle->hbot.pbuf[13];
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief USBH_MSC_SCSI_Write
|
||||
* Issue write10 command.
|
||||
* @param phost: Host handle
|
||||
* @param lun: Logical Unit Number
|
||||
* @param address: sector address
|
||||
* @param pbuf: pointer to data
|
||||
* @param length: number of sector to write
|
||||
* @retval USBH Status
|
||||
*/
|
||||
#ifdef CONFIG_MASS_STORAGE_WRITES_PERMITTED
|
||||
USBH_StatusTypeDef USBH_MSC_SCSI_Write(USBH_HandleTypeDef *phost,
|
||||
uint8_t lun,
|
||||
uint32_t address,
|
||||
uint32_t length)
|
||||
{
|
||||
USBH_StatusTypeDef error = USBH_FAIL ;
|
||||
|
||||
MSC_HandleTypeDef *MSC_Handle = (MSC_HandleTypeDef *) phost->pActiveClass->pData;
|
||||
|
||||
switch(MSC_Handle->hbot.cmd_state)
|
||||
{
|
||||
case BOT_CMD_SEND:
|
||||
|
||||
/*Prepare the CBW and relevent field*/
|
||||
MSC_Handle->hbot.cbw.field.DataTransferLength = length * MSC_Handle->unit[lun].capacity.block_size;
|
||||
MSC_Handle->hbot.cbw.field.Flags = USB_EP_DIR_OUT;
|
||||
MSC_Handle->hbot.cbw.field.CBLength = CBW_LENGTH;
|
||||
|
||||
USBH_memset(MSC_Handle->hbot.cbw.field.CB, 0, CBW_CB_LENGTH);
|
||||
MSC_Handle->hbot.cbw.field.CB[0] = OPCODE_WRITE10;
|
||||
|
||||
/*logical block address*/
|
||||
MSC_Handle->hbot.cbw.field.CB[2] = (((uint8_t*)&address)[3]);
|
||||
MSC_Handle->hbot.cbw.field.CB[3] = (((uint8_t*)&address)[2]);
|
||||
MSC_Handle->hbot.cbw.field.CB[4] = (((uint8_t*)&address)[1]);
|
||||
MSC_Handle->hbot.cbw.field.CB[5] = (((uint8_t*)&address)[0]);
|
||||
|
||||
/*Transfer length */
|
||||
MSC_Handle->hbot.cbw.field.CB[7] = (((uint8_t *)&length)[1]) ;
|
||||
MSC_Handle->hbot.cbw.field.CB[8] = (((uint8_t *)&length)[0]) ;
|
||||
|
||||
MSC_Handle->hbot.state = BOT_SEND_CBW;
|
||||
MSC_Handle->hbot.cmd_state = BOT_CMD_WAIT;
|
||||
MSC_Handle->hbot.pbuf = NULL;
|
||||
error = USBH_BUSY;
|
||||
break;
|
||||
|
||||
case BOT_CMD_WAIT:
|
||||
error = USBH_MSC_BOT_Process(phost, lun);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return error;
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief USBH_MSC_SCSI_Read
|
||||
* Issue Read10 command.
|
||||
* @param phost: Host handle
|
||||
* @param lun: Logical Unit Number
|
||||
* @param address: sector address
|
||||
* @param pbuf: pointer to data
|
||||
* @param length: number of sector to read
|
||||
* @retval USBH Status
|
||||
*/
|
||||
USBH_StatusTypeDef USBH_MSC_SCSI_Read(USBH_HandleTypeDef *phost,
|
||||
uint8_t lun,
|
||||
uint32_t address,
|
||||
uint32_t length)
|
||||
{
|
||||
USBH_StatusTypeDef error = USBH_FAIL ;
|
||||
MSC_HandleTypeDef *MSC_Handle = (MSC_HandleTypeDef *) phost->pActiveClass->pData;
|
||||
|
||||
switch(MSC_Handle->hbot.cmd_state)
|
||||
{
|
||||
case BOT_CMD_SEND:
|
||||
/*Prepare the CBW and relevant fields*/
|
||||
MSC_Handle->hbot.cbw.field.DataTransferLength = length * MSC_Handle->unit[lun].capacity.block_size;;
|
||||
MSC_Handle->hbot.cbw.field.Flags = USB_EP_DIR_IN;
|
||||
MSC_Handle->hbot.cbw.field.CBLength = CBW_LENGTH;
|
||||
|
||||
USBH_memset(MSC_Handle->hbot.cbw.field.CB, 0, CBW_CB_LENGTH);
|
||||
MSC_Handle->hbot.cbw.field.CB[0] = OPCODE_READ10;
|
||||
|
||||
/*logical block address*/
|
||||
MSC_Handle->hbot.cbw.field.CB[2] = (((uint8_t*)&address)[3]);
|
||||
MSC_Handle->hbot.cbw.field.CB[3] = (((uint8_t*)&address)[2]);
|
||||
MSC_Handle->hbot.cbw.field.CB[4] = (((uint8_t*)&address)[1]);
|
||||
MSC_Handle->hbot.cbw.field.CB[5] = (((uint8_t*)&address)[0]);
|
||||
|
||||
/*Transfer length */
|
||||
MSC_Handle->hbot.cbw.field.CB[7] = (((uint8_t *)&length)[1]) ;
|
||||
MSC_Handle->hbot.cbw.field.CB[8] = (((uint8_t *)&length)[0]) ;
|
||||
|
||||
MSC_Handle->hbot.state = BOT_SEND_CBW;
|
||||
MSC_Handle->hbot.cmd_state = BOT_CMD_WAIT;
|
||||
MSC_Handle->hbot.pbuf = NULL;
|
||||
error = USBH_BUSY;
|
||||
break;
|
||||
|
||||
case BOT_CMD_WAIT:
|
||||
error = USBH_MSC_BOT_Process(phost, lun);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
USBH_StatusTypeDef USBH_MSC_SCSI_StartStopUnit(USBH_HandleTypeDef *phost,
|
||||
uint8_t lun,
|
||||
uint8_t startStop)
|
||||
{
|
||||
MSC_HandleTypeDef *MSC_Handle = (MSC_HandleTypeDef *) phost->pActiveClass->pData;
|
||||
|
||||
if (MSC_Handle->hbot.cmd_state == BOT_CMD_SEND)
|
||||
{
|
||||
/*Prepare the CBW and relevent field*/
|
||||
MSC_Handle->hbot.cbw.field.DataTransferLength = DATA_LEN_START_STOP_UNIT;
|
||||
MSC_Handle->hbot.cbw.field.Flags = USB_EP_DIR_OUT;
|
||||
MSC_Handle->hbot.cbw.field.CBLength = CBW_LENGTH;
|
||||
|
||||
USBH_memset(MSC_Handle->hbot.cbw.field.CB, 0, CBW_CB_LENGTH);
|
||||
MSC_Handle->hbot.cbw.field.CB[0] = OPCODE_START_STOP_UNIT;
|
||||
MSC_Handle->hbot.cbw.field.CB[4] = 0x02 | (startStop & 0x01); //LOEJ = 1, START = 0 for eject, START = 1 for load
|
||||
|
||||
MSC_Handle->hbot.state = BOT_SEND_CBW;
|
||||
MSC_Handle->hbot.cmd_state = BOT_CMD_WAIT;
|
||||
}
|
||||
|
||||
return USBH_MSC_BOT_Process(phost, lun);
|
||||
}
|
||||
|
||||
|
||||
#endif //#ifdef CONFIG_MASS_STORAGE_ENABLED
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
|
||||
|
||||
|
||||
|
@ -0,0 +1,170 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file usbh_core.h
|
||||
* @author MCD Application Team
|
||||
* @version V3.2.1
|
||||
* @date 26-June-2015
|
||||
* @brief Header file for usbh_core.c
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* <h2><center>© COPYRIGHT 2015 STMicroelectronics</center></h2>
|
||||
*
|
||||
* Licensed under MCD-ST Liberty SW License Agreement V2, (the "License");
|
||||
* You may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at:
|
||||
*
|
||||
* http://www.st.com/software_license_agreement_liberty_v2
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
/* Define to prevent recursive ----------------------------------------------*/
|
||||
#ifndef __USBH_CORE_H
|
||||
#define __USBH_CORE_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include "usbh_config.h"
|
||||
#include "usbh_def.h"
|
||||
#include "usbh_ioreq.h"
|
||||
#include "usbh_pipes.h"
|
||||
#include "usbh_ctlreq.h"
|
||||
|
||||
/** @addtogroup USBH_LIB
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @addtogroup USBH_LIB_CORE
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @defgroup USBH_CORE
|
||||
* @brief This file is the Header file for usbh_core.c
|
||||
* @{
|
||||
*/
|
||||
|
||||
|
||||
/** @defgroup USBH_CORE_Exported_Defines
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
#define HOST_USER_SELECT_CONFIGURATION 1
|
||||
#define HOST_USER_CLASS_ACTIVE 2
|
||||
#define HOST_USER_CLASS_SELECTED 3
|
||||
#define HOST_USER_CONNECTION 4
|
||||
#define HOST_USER_DISCONNECTION 5
|
||||
#define HOST_USER_UNRECOVERED_ERROR 6
|
||||
#define HOST_USER_CLASS_FAILED 7
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
|
||||
|
||||
/** @defgroup USBH_CORE_Exported_Macros
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @defgroup USBH_CORE_Exported_Variables
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @defgroup USBH_CORE_Exported_FunctionsPrototype
|
||||
* @{
|
||||
*/
|
||||
|
||||
|
||||
USBH_StatusTypeDef USBH_Init(USBH_HandleTypeDef *phost, void (*pUsrFunc)(USBH_HandleTypeDef *phost, uint8_t ), uint8_t id);
|
||||
USBH_StatusTypeDef USBH_DeInit(USBH_HandleTypeDef *phost);
|
||||
USBH_StatusTypeDef USBH_RegisterClass(USBH_HandleTypeDef *phost, USBH_ClassTypeDef *pclass);
|
||||
USBH_StatusTypeDef USBH_SelectInterface(USBH_HandleTypeDef *phost, uint8_t interface);
|
||||
uint8_t USBH_FindInterface(USBH_HandleTypeDef *phost,
|
||||
uint8_t Class,
|
||||
uint8_t SubClass,
|
||||
uint8_t Protocol);
|
||||
uint8_t USBH_GetActiveClass(USBH_HandleTypeDef *phost);
|
||||
|
||||
uint8_t USBH_FindInterfaceIndex(USBH_HandleTypeDef *phost,
|
||||
uint8_t interface_number,
|
||||
uint8_t alt_settings);
|
||||
|
||||
USBH_StatusTypeDef USBH_Start (USBH_HandleTypeDef *phost);
|
||||
USBH_StatusTypeDef USBH_Stop (USBH_HandleTypeDef *phost);
|
||||
USBH_StatusTypeDef USBH_Process (USBH_HandleTypeDef *phost);
|
||||
USBH_StatusTypeDef USBH_ReEnumerate (USBH_HandleTypeDef *phost);
|
||||
|
||||
/* USBH Low Level Driver */
|
||||
USBH_StatusTypeDef USBH_LL_Init (USBH_HandleTypeDef *phost);
|
||||
USBH_StatusTypeDef USBH_LL_DeInit (USBH_HandleTypeDef *phost);
|
||||
USBH_StatusTypeDef USBH_LL_Start (USBH_HandleTypeDef *phost);
|
||||
USBH_StatusTypeDef USBH_LL_Stop (USBH_HandleTypeDef *phost);
|
||||
|
||||
USBH_StatusTypeDef USBH_LL_Connect (USBH_HandleTypeDef *phost);
|
||||
USBH_StatusTypeDef USBH_LL_PortEnabled (USBH_HandleTypeDef *phost);
|
||||
USBH_StatusTypeDef USBH_LL_Disconnect (USBH_HandleTypeDef *phost);
|
||||
USBH_SpeedTypeDef USBH_LL_GetSpeed (USBH_HandleTypeDef *phost);
|
||||
USBH_StatusTypeDef USBH_LL_ResetPort (USBH_HandleTypeDef *phost);
|
||||
uint32_t USBH_LL_GetLastXferSize (USBH_HandleTypeDef *phost, uint8_t );
|
||||
USBH_StatusTypeDef USBH_LL_DriverVBUS (USBH_HandleTypeDef *phost, uint8_t );
|
||||
|
||||
USBH_StatusTypeDef USBH_LL_OpenPipe (USBH_HandleTypeDef *phost, uint8_t, uint8_t, uint8_t, uint8_t , uint8_t, uint16_t );
|
||||
USBH_StatusTypeDef USBH_LL_ClosePipe (USBH_HandleTypeDef *phost, uint8_t );
|
||||
USBH_StatusTypeDef USBH_LL_SubmitURB (USBH_HandleTypeDef *phost, uint8_t, uint8_t,uint8_t, uint8_t, uint8_t*, uint16_t, uint8_t );
|
||||
USBH_URBStateTypeDef USBH_LL_GetURBState (USBH_HandleTypeDef *phost, uint8_t );
|
||||
#if (USBH_USE_OS == 1)
|
||||
USBH_StatusTypeDef USBH_LL_NotifyURBChange (USBH_HandleTypeDef *phost);
|
||||
#endif
|
||||
USBH_StatusTypeDef USBH_LL_SetToggle (USBH_HandleTypeDef *phost, uint8_t , uint8_t );
|
||||
uint8_t USBH_LL_GetToggle (USBH_HandleTypeDef *phost, uint8_t );
|
||||
|
||||
/* USBH Time base */
|
||||
void USBH_Delay (uint32_t Delay);
|
||||
void USBH_LL_SetTimer (USBH_HandleTypeDef *phost, uint32_t );
|
||||
void USBH_LL_IncTimer (USBH_HandleTypeDef *phost);
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __USBH_CORE_H */
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
|
||||
|
||||
|
||||
|
@ -0,0 +1,159 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file usbh_ctlreq.h
|
||||
* @author MCD Application Team
|
||||
* @version V3.2.1
|
||||
* @date 26-June-2015
|
||||
* @brief Header file for usbh_ctlreq.c
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* <h2><center>© COPYRIGHT 2015 STMicroelectronics</center></h2>
|
||||
*
|
||||
* Licensed under MCD-ST Liberty SW License Agreement V2, (the "License");
|
||||
* You may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at:
|
||||
*
|
||||
* http://www.st.com/software_license_agreement_liberty_v2
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
******************************************************************************
|
||||
*
|
||||
* Modifications by Robert Fisk
|
||||
*/
|
||||
|
||||
|
||||
/* Define to prevent recursive ----------------------------------------------*/
|
||||
#ifndef __USBH_CTLREQ_H
|
||||
#define __USBH_CTLREQ_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include "usbh_core.h"
|
||||
|
||||
/** @addtogroup USBH_LIB
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @addtogroup USBH_LIB_CORE
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @defgroup USBH_CTLREQ
|
||||
* @brief This file is the
|
||||
* @{
|
||||
*/
|
||||
|
||||
|
||||
/** @defgroup USBH_CTLREQ_Exported_Defines
|
||||
* @{
|
||||
*/
|
||||
/*Standard Feature Selector for clear feature command*/
|
||||
#define FEATURE_SELECTOR_ENDPOINT 0X00
|
||||
#define FEATURE_SELECTOR_DEVICE 0X01
|
||||
|
||||
|
||||
#define INTERFACE_DESC_TYPE 0x04
|
||||
#define ENDPOINT_DESC_TYPE 0x05
|
||||
#define INTERFACE_DESC_SIZE 0x09
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
|
||||
/** @defgroup USBH_CTLREQ_Exported_Types
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
|
||||
/** @defgroup USBH_CTLREQ_Exported_Macros
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @defgroup USBH_CTLREQ_Exported_Variables
|
||||
* @{
|
||||
*/
|
||||
//extern uint8_t USBH_CfgDesc[512];
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @defgroup USBH_CTLREQ_Exported_FunctionsPrototype
|
||||
* @{
|
||||
*/
|
||||
USBH_StatusTypeDef USBH_CtlReq (USBH_HandleTypeDef *phost,
|
||||
uint8_t *buff,
|
||||
uint16_t length);
|
||||
|
||||
USBH_StatusTypeDef USBH_GetDescriptor(USBH_HandleTypeDef *phost,
|
||||
uint8_t req_type,
|
||||
uint16_t type_idx,
|
||||
uint16_t value,
|
||||
uint8_t* buff,
|
||||
uint16_t length );
|
||||
|
||||
USBH_StatusTypeDef USBH_Get_DevDesc(USBH_HandleTypeDef *phost,
|
||||
uint16_t length);
|
||||
|
||||
USBH_StatusTypeDef USBH_Get_StringDesc(USBH_HandleTypeDef *phost,
|
||||
uint8_t string_index,
|
||||
uint8_t *buff,
|
||||
uint16_t length);
|
||||
|
||||
USBH_StatusTypeDef USBH_SetCfg(USBH_HandleTypeDef *phost,
|
||||
uint16_t configuration_value);
|
||||
|
||||
USBH_StatusTypeDef USBH_Get_CfgDesc(USBH_HandleTypeDef *phost,
|
||||
uint16_t length);
|
||||
|
||||
USBH_StatusTypeDef USBH_SetAddress(USBH_HandleTypeDef *phost,
|
||||
uint8_t DeviceAddress);
|
||||
|
||||
USBH_StatusTypeDef USBH_SetInterface(USBH_HandleTypeDef *phost,
|
||||
uint8_t ep_num, uint8_t altSetting);
|
||||
|
||||
USBH_StatusTypeDef USBH_ClrFeature(USBH_HandleTypeDef *phost,
|
||||
uint8_t ep_num);
|
||||
|
||||
USBH_DescHeader_t *USBH_GetNextDesc (uint8_t *pbuf,
|
||||
uint16_t *ptr);
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __USBH_CTLREQ_H */
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
|
||||
|
||||
|
@ -0,0 +1,503 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file usbh_def.h
|
||||
* @author MCD Application Team
|
||||
* @version V3.2.1
|
||||
* @date 26-June-2015
|
||||
* @brief Definitions used in the USB host library
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* <h2><center>© COPYRIGHT 2015 STMicroelectronics</center></h2>
|
||||
*
|
||||
* Licensed under MCD-ST Liberty SW License Agreement V2, (the "License");
|
||||
* You may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at:
|
||||
*
|
||||
* http://www.st.com/software_license_agreement_liberty_v2
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
******************************************************************************
|
||||
*
|
||||
* Modifications by Robert Fisk
|
||||
*/
|
||||
|
||||
|
||||
/* Define to prevent recursive ----------------------------------------------*/
|
||||
#ifndef USBH_DEF_H
|
||||
#define USBH_DEF_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include "usbh_config.h"
|
||||
|
||||
/** @addtogroup USBH_LIB
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @addtogroup USBH_LIB_CORE
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @defgroup USBH_DEF
|
||||
* @brief This file is includes USB descriptors
|
||||
* @{
|
||||
*/
|
||||
|
||||
#ifndef NULL
|
||||
#define NULL 0
|
||||
#endif
|
||||
|
||||
#ifndef FALSE
|
||||
#define FALSE 0
|
||||
#endif
|
||||
|
||||
#ifndef TRUE
|
||||
#define TRUE 1
|
||||
#endif
|
||||
|
||||
|
||||
#define ValBit(VAR,POS) (VAR & (1 << POS))
|
||||
#define SetBit(VAR,POS) (VAR |= (1 << POS))
|
||||
#define ClrBit(VAR,POS) (VAR &= ((1 << POS)^255))
|
||||
|
||||
#define LE16(addr) (((uint16_t)(*((uint8_t *)(addr))))\
|
||||
+ (((uint16_t)(*(((uint8_t *)(addr)) + 1))) << 8))
|
||||
|
||||
#define LE16S(addr) (uint16_t)(LE16((addr)))
|
||||
|
||||
#define LE32(addr) ((((uint32_t)(*(((uint8_t *)(addr)) + 0))) + \
|
||||
(((uint32_t)(*(((uint8_t *)(addr)) + 1))) << 8) + \
|
||||
(((uint32_t)(*(((uint8_t *)(addr)) + 2))) << 16) + \
|
||||
(((uint32_t)(*(((uint8_t *)(addr)) + 3))) << 24)))
|
||||
|
||||
#define LE64(addr) ((((uint64_t)(*(((uint8_t *)(addr)) + 0))) + \
|
||||
(((uint64_t)(*(((uint8_t *)(addr)) + 1))) << 8) +\
|
||||
(((uint64_t)(*(((uint8_t *)(addr)) + 2))) << 16) +\
|
||||
(((uint64_t)(*(((uint8_t *)(addr)) + 3))) << 24) +\
|
||||
(((uint64_t)(*(((uint8_t *)(addr)) + 4))) << 32) +\
|
||||
(((uint64_t)(*(((uint8_t *)(addr)) + 5))) << 40) +\
|
||||
(((uint64_t)(*(((uint8_t *)(addr)) + 6))) << 48) +\
|
||||
(((uint64_t)(*(((uint8_t *)(addr)) + 7))) << 56)))
|
||||
|
||||
|
||||
#define LE24(addr) ((((uint32_t)(*(((uint8_t *)(addr)) + 0))) + \
|
||||
(((uint32_t)(*(((uint8_t *)(addr)) + 1))) << 8) + \
|
||||
(((uint32_t)(*(((uint8_t *)(addr)) + 2))) << 16)))
|
||||
|
||||
|
||||
#define LE32S(addr) (int32_t)(LE32((addr)))
|
||||
|
||||
|
||||
#define MIN(a, b) (((a) < (b)) ? (a) : (b))
|
||||
#define MAX(a, b) (((a) > (b)) ? (a) : (b))
|
||||
|
||||
|
||||
#define USB_LEN_DESC_HDR 0x02
|
||||
#define USB_LEN_DEV_DESC 0x12
|
||||
#define USB_LEN_CFG_DESC 0x09
|
||||
#define USB_LEN_IF_DESC 0x09
|
||||
#define USB_LEN_EP_DESC 0x07
|
||||
#define USB_LEN_OTG_DESC 0x03
|
||||
#define USB_LEN_SETUP_PKT 0x08
|
||||
|
||||
/* bmRequestType :D7 Data Phase Transfer Direction */
|
||||
#define USB_REQ_DIR_MASK 0x80
|
||||
#define USB_H2D 0x00
|
||||
#define USB_D2H 0x80
|
||||
|
||||
/* bmRequestType D6..5 Type */
|
||||
#define USB_REQ_TYPE_STANDARD 0x00
|
||||
#define USB_REQ_TYPE_CLASS 0x20
|
||||
#define USB_REQ_TYPE_VENDOR 0x40
|
||||
#define USB_REQ_TYPE_RESERVED 0x60
|
||||
|
||||
/* bmRequestType D4..0 Recipient */
|
||||
#define USB_REQ_RECIPIENT_DEVICE 0x00
|
||||
#define USB_REQ_RECIPIENT_INTERFACE 0x01
|
||||
#define USB_REQ_RECIPIENT_ENDPOINT 0x02
|
||||
#define USB_REQ_RECIPIENT_OTHER 0x03
|
||||
|
||||
/* Table 9-4. Standard Request Codes */
|
||||
/* bRequest , Value */
|
||||
#define USB_REQ_GET_STATUS 0x00
|
||||
#define USB_REQ_CLEAR_FEATURE 0x01
|
||||
#define USB_REQ_SET_FEATURE 0x03
|
||||
#define USB_REQ_SET_ADDRESS 0x05
|
||||
#define USB_REQ_GET_DESCRIPTOR 0x06
|
||||
#define USB_REQ_SET_DESCRIPTOR 0x07
|
||||
#define USB_REQ_GET_CONFIGURATION 0x08
|
||||
#define USB_REQ_SET_CONFIGURATION 0x09
|
||||
#define USB_REQ_GET_INTERFACE 0x0A
|
||||
#define USB_REQ_SET_INTERFACE 0x0B
|
||||
#define USB_REQ_SYNCH_FRAME 0x0C
|
||||
|
||||
/* Table 9-5. Descriptor Types of USB Specifications */
|
||||
#define USB_DESC_TYPE_DEVICE 1
|
||||
#define USB_DESC_TYPE_CONFIGURATION 2
|
||||
#define USB_DESC_TYPE_STRING 3
|
||||
#define USB_DESC_TYPE_INTERFACE 4
|
||||
#define USB_DESC_TYPE_ENDPOINT 5
|
||||
#define USB_DESC_TYPE_DEVICE_QUALIFIER 6
|
||||
#define USB_DESC_TYPE_OTHER_SPEED_CONFIGURATION 7
|
||||
#define USB_DESC_TYPE_INTERFACE_POWER 8
|
||||
#define USB_DESC_TYPE_HID 0x21
|
||||
#define USB_DESC_TYPE_HID_REPORT 0x22
|
||||
|
||||
|
||||
#define USB_DEVICE_DESC_SIZE 18
|
||||
#define USB_CONFIGURATION_DESC_SIZE 9
|
||||
#define USB_HID_DESC_SIZE 9
|
||||
#define USB_INTERFACE_DESC_SIZE 9
|
||||
#define USB_ENDPOINT_DESC_SIZE 7
|
||||
|
||||
/* Descriptor Type and Descriptor Index */
|
||||
/* Use the following values when calling the function USBH_GetDescriptor */
|
||||
#define USB_DESC_DEVICE ((USB_DESC_TYPE_DEVICE << 8) & 0xFF00)
|
||||
#define USB_DESC_CONFIGURATION ((USB_DESC_TYPE_CONFIGURATION << 8) & 0xFF00)
|
||||
#define USB_DESC_STRING ((USB_DESC_TYPE_STRING << 8) & 0xFF00)
|
||||
#define USB_DESC_INTERFACE ((USB_DESC_TYPE_INTERFACE << 8) & 0xFF00)
|
||||
#define USB_DESC_ENDPOINT ((USB_DESC_TYPE_INTERFACE << 8) & 0xFF00)
|
||||
#define USB_DESC_DEVICE_QUALIFIER ((USB_DESC_TYPE_DEVICE_QUALIFIER << 8) & 0xFF00)
|
||||
#define USB_DESC_OTHER_SPEED_CONFIGURATION ((USB_DESC_TYPE_OTHER_SPEED_CONFIGURATION << 8) & 0xFF00)
|
||||
#define USB_DESC_INTERFACE_POWER ((USB_DESC_TYPE_INTERFACE_POWER << 8) & 0xFF00)
|
||||
#define USB_DESC_HID_REPORT ((USB_DESC_TYPE_HID_REPORT << 8) & 0xFF00)
|
||||
#define USB_DESC_HID ((USB_DESC_TYPE_HID << 8) & 0xFF00)
|
||||
|
||||
|
||||
#define USB_EP_TYPE_CTRL 0x00
|
||||
#define USB_EP_TYPE_ISOC 0x01
|
||||
#define USB_EP_TYPE_BULK 0x02
|
||||
#define USB_EP_TYPE_INTR 0x03
|
||||
|
||||
#define USB_EP_DIR_OUT 0x00
|
||||
#define USB_EP_DIR_IN 0x80
|
||||
#define USB_EP_DIR_MSK 0x80
|
||||
|
||||
#ifndef USBH_MAX_PIPES_NBR
|
||||
#define USBH_MAX_PIPES_NBR 15
|
||||
#endif /* USBH_MAX_PIPES_NBR */
|
||||
|
||||
#define USBH_DEVICE_ADDRESS_DEFAULT 0
|
||||
#define USBH_MAX_ERROR_COUNT 10
|
||||
#define USBH_DEVICE_ADDRESS 1
|
||||
|
||||
#define USBH_CTRL_TRANSACTION_TIMEOUT_MS 200
|
||||
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
|
||||
#define USBH_CONFIGURATION_DESCRIPTOR_SIZE (USB_CONFIGURATION_DESC_SIZE \
|
||||
+ USB_INTERFACE_DESC_SIZE\
|
||||
+ (USBH_MAX_NUM_ENDPOINTS * USB_ENDPOINT_DESC_SIZE))
|
||||
|
||||
|
||||
#define CONFIG_DESC_wTOTAL_LENGTH (ConfigurationDescriptorData.ConfigDescfield.\
|
||||
ConfigurationDescriptor.wTotalLength)
|
||||
|
||||
|
||||
typedef union
|
||||
{
|
||||
uint16_t w;
|
||||
struct BW
|
||||
{
|
||||
uint8_t msb;
|
||||
uint8_t lsb;
|
||||
}
|
||||
bw;
|
||||
}
|
||||
uint16_t_uint8_t;
|
||||
|
||||
|
||||
typedef union _USB_Setup
|
||||
{
|
||||
uint32_t d8[2];
|
||||
|
||||
struct _SetupPkt_Struc
|
||||
{
|
||||
uint8_t bmRequestType;
|
||||
uint8_t bRequest;
|
||||
uint16_t_uint8_t wValue;
|
||||
uint16_t_uint8_t wIndex;
|
||||
uint16_t_uint8_t wLength;
|
||||
} b;
|
||||
}
|
||||
USB_Setup_TypeDef;
|
||||
|
||||
typedef struct _DescHeader
|
||||
{
|
||||
uint8_t bLength;
|
||||
uint8_t bDescriptorType;
|
||||
}
|
||||
USBH_DescHeader_t;
|
||||
|
||||
typedef struct _DeviceDescriptor
|
||||
{
|
||||
uint8_t bLength;
|
||||
uint8_t bDescriptorType;
|
||||
uint16_t bcdUSB; /* USB Specification Number which device complies too */
|
||||
uint8_t bDeviceClass;
|
||||
uint8_t bDeviceSubClass;
|
||||
uint8_t bDeviceProtocol;
|
||||
/* If equal to Zero, each interface specifies its own class
|
||||
code if equal to 0xFF, the class code is vendor specified.
|
||||
Otherwise field is valid Class Code.*/
|
||||
uint8_t bMaxPacketSize;
|
||||
uint16_t idVendor; /* Vendor ID (Assigned by USB Org) */
|
||||
uint16_t idProduct; /* Product ID (Assigned by Manufacturer) */
|
||||
uint16_t bcdDevice; /* Device Release Number */
|
||||
uint8_t iManufacturer; /* Index of Manufacturer String Descriptor */
|
||||
uint8_t iProduct; /* Index of Product String Descriptor */
|
||||
uint8_t iSerialNumber; /* Index of Serial Number String Descriptor */
|
||||
uint8_t bNumConfigurations; /* Number of Possible Configurations */
|
||||
}
|
||||
USBH_DevDescTypeDef;
|
||||
|
||||
typedef struct _EndpointDescriptor
|
||||
{
|
||||
uint8_t bLength;
|
||||
uint8_t bDescriptorType;
|
||||
uint8_t bEndpointAddress; /* indicates what endpoint this descriptor is describing */
|
||||
uint8_t bmAttributes; /* specifies the transfer type. */
|
||||
uint16_t wMaxPacketSize; /* Maximum Packet Size this endpoint is capable of sending or receiving */
|
||||
uint8_t bInterval; /* is used to specify the polling interval of certain transfers. */
|
||||
}
|
||||
USBH_EpDescTypeDef;
|
||||
|
||||
typedef struct _InterfaceDescriptor
|
||||
{
|
||||
uint8_t bLength;
|
||||
uint8_t bDescriptorType;
|
||||
uint8_t bInterfaceNumber;
|
||||
uint8_t bAlternateSetting; /* Value used to select alternative setting */
|
||||
uint8_t bNumEndpoints; /* Number of Endpoints used for this interface */
|
||||
uint8_t bInterfaceClass; /* Class Code (Assigned by USB Org) */
|
||||
uint8_t bInterfaceSubClass; /* Subclass Code (Assigned by USB Org) */
|
||||
uint8_t bInterfaceProtocol; /* Protocol Code */
|
||||
uint8_t iInterface; /* Index of String Descriptor Describing this interface */
|
||||
USBH_EpDescTypeDef Ep_Desc[USBH_MAX_NUM_ENDPOINTS];
|
||||
}
|
||||
USBH_InterfaceDescTypeDef;
|
||||
|
||||
|
||||
typedef struct _ConfigurationDescriptor
|
||||
{
|
||||
uint8_t bLength;
|
||||
uint8_t bDescriptorType;
|
||||
uint16_t wTotalLength; /* Total Length of Data Returned */
|
||||
uint8_t bNumInterfaces; /* Number of Interfaces */
|
||||
uint8_t bConfigurationValue; /* Value to use as an argument to select this configuration*/
|
||||
uint8_t iConfiguration; /*Index of String Descriptor Describing this configuration */
|
||||
uint8_t bmAttributes; /* D7 Bus Powered , D6 Self Powered, D5 Remote Wakeup , D4..0 Reserved (0)*/
|
||||
uint8_t bMaxPower; /*Maximum Power Consumption */
|
||||
USBH_InterfaceDescTypeDef Itf_Desc[USBH_MAX_NUM_INTERFACES];
|
||||
}
|
||||
USBH_CfgDescTypeDef;
|
||||
|
||||
|
||||
/* Following USB Host status */
|
||||
typedef enum
|
||||
{
|
||||
USBH_OK = 0,
|
||||
USBH_BUSY,
|
||||
USBH_FAIL,
|
||||
USBH_NOT_SUPPORTED,
|
||||
USBH_UNRECOVERED_ERROR,
|
||||
USBH_ERROR_SPEED_UNKNOWN,
|
||||
}USBH_StatusTypeDef;
|
||||
|
||||
|
||||
/** @defgroup USBH_CORE_Exported_Types
|
||||
* @{
|
||||
*/
|
||||
|
||||
typedef enum
|
||||
{
|
||||
USBH_SPEED_HIGH = 0,
|
||||
USBH_SPEED_FULL = 1,
|
||||
USBH_SPEED_LOW = 2,
|
||||
|
||||
}USBH_SpeedTypeDef;
|
||||
|
||||
/* Following states are used for gState */
|
||||
typedef enum
|
||||
{
|
||||
HOST_IDLE =0,
|
||||
HOST_DEV_WAIT_FOR_ATTACHMENT,
|
||||
HOST_DEV_ATTACHED,
|
||||
HOST_DEV_DISCONNECTED,
|
||||
HOST_DETECT_DEVICE_SPEED,
|
||||
HOST_ENUMERATION,
|
||||
HOST_CLASS_REQUEST,
|
||||
HOST_INPUT,
|
||||
HOST_SET_CONFIGURATION,
|
||||
HOST_CHECK_CLASS,
|
||||
HOST_CLASS,
|
||||
HOST_SUSPENDED,
|
||||
HOST_ABORT_STATE,
|
||||
}HOST_StateTypeDef;
|
||||
|
||||
/* Following states are used for EnumerationState */
|
||||
typedef enum
|
||||
{
|
||||
ENUM_IDLE = 0,
|
||||
ENUM_GET_FULL_DEV_DESC,
|
||||
ENUM_SET_ADDR,
|
||||
ENUM_GET_CFG_DESC,
|
||||
ENUM_GET_FULL_CFG_DESC,
|
||||
ENUM_GET_MFC_STRING_DESC,
|
||||
ENUM_GET_PRODUCT_STRING_DESC,
|
||||
ENUM_GET_SERIALNUM_STRING_DESC,
|
||||
} ENUM_StateTypeDef;
|
||||
|
||||
/* Following states are used for CtrlXferStateMachine */
|
||||
typedef enum
|
||||
{
|
||||
CTRL_IDLE =0,
|
||||
CTRL_SETUP,
|
||||
CTRL_SETUP_WAIT,
|
||||
CTRL_DATA_IN,
|
||||
CTRL_DATA_IN_WAIT,
|
||||
CTRL_DATA_OUT,
|
||||
CTRL_DATA_OUT_WAIT,
|
||||
CTRL_STATUS_IN,
|
||||
CTRL_STATUS_IN_WAIT,
|
||||
CTRL_STATUS_OUT,
|
||||
CTRL_STATUS_OUT_WAIT,
|
||||
CTRL_ERROR,
|
||||
CTRL_STALLED,
|
||||
CTRL_COMPLETE
|
||||
}CTRL_StateTypeDef;
|
||||
|
||||
|
||||
/* Following states are used for RequestState */
|
||||
typedef enum
|
||||
{
|
||||
CMD_IDLE =0,
|
||||
CMD_SEND,
|
||||
CMD_WAIT
|
||||
} CMD_StateTypeDef;
|
||||
|
||||
typedef enum {
|
||||
USBH_URB_IDLE = 0,
|
||||
USBH_URB_DONE,
|
||||
USBH_URB_NOTREADY,
|
||||
USBH_URB_NYET,
|
||||
USBH_URB_ERROR,
|
||||
USBH_URB_STALL
|
||||
}USBH_URBStateTypeDef;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
USBH_PORT_EVENT = 1,
|
||||
USBH_URB_EVENT,
|
||||
USBH_CONTROL_EVENT,
|
||||
USBH_CLASS_EVENT,
|
||||
USBH_STATE_CHANGED_EVENT,
|
||||
}
|
||||
USBH_OSEventTypeDef;
|
||||
|
||||
/* Control request structure */
|
||||
typedef struct
|
||||
{
|
||||
uint8_t pipe_in;
|
||||
uint8_t pipe_out;
|
||||
uint8_t pipe_size;
|
||||
uint8_t *buff;
|
||||
uint32_t timer;
|
||||
uint16_t length;
|
||||
USB_Setup_TypeDef setup;
|
||||
CTRL_StateTypeDef state;
|
||||
uint8_t errorcount;
|
||||
|
||||
} USBH_CtrlTypeDef;
|
||||
|
||||
/* Attached device structure */
|
||||
typedef struct
|
||||
{
|
||||
#if (USBH_KEEP_CFG_DESCRIPTOR == 1)
|
||||
uint8_t CfgDesc_Raw[USBH_MAX_SIZE_CONFIGURATION];
|
||||
#endif
|
||||
uint8_t Data[USBH_MAX_DATA_BUFFER];
|
||||
uint8_t address;
|
||||
uint8_t speed;
|
||||
__IO uint8_t is_connected;
|
||||
uint8_t current_interface;
|
||||
USBH_DevDescTypeDef DevDesc;
|
||||
USBH_CfgDescTypeDef CfgDesc;
|
||||
|
||||
}USBH_DeviceTypeDef;
|
||||
|
||||
struct _USBH_HandleTypeDef;
|
||||
|
||||
/* USB Host Class structure */
|
||||
typedef struct
|
||||
{
|
||||
const char *Name;
|
||||
uint8_t ClassCode;
|
||||
USBH_StatusTypeDef (*Init) (struct _USBH_HandleTypeDef *phost);
|
||||
USBH_StatusTypeDef (*DeInit) (struct _USBH_HandleTypeDef *phost);
|
||||
USBH_StatusTypeDef (*Requests) (struct _USBH_HandleTypeDef *phost);
|
||||
USBH_StatusTypeDef (*BgndProcess) (struct _USBH_HandleTypeDef *phost);
|
||||
USBH_StatusTypeDef (*SOFProcess) (struct _USBH_HandleTypeDef *phost);
|
||||
void* pData;
|
||||
} USBH_ClassTypeDef;
|
||||
|
||||
|
||||
|
||||
#define HOST_PIPE_COUNT 15
|
||||
|
||||
|
||||
/* USB Host handle structure */
|
||||
typedef struct _USBH_HandleTypeDef
|
||||
{
|
||||
__IO HOST_StateTypeDef gState; /* Host State Machine Value */
|
||||
ENUM_StateTypeDef EnumState; /* Enumeration state Machine */
|
||||
CMD_StateTypeDef RequestState;
|
||||
USBH_CtrlTypeDef Control;
|
||||
USBH_DeviceTypeDef device;
|
||||
USBH_ClassTypeDef* pClass[USBH_MAX_NUM_SUPPORTED_CLASS];
|
||||
USBH_ClassTypeDef* pActiveClass;
|
||||
uint32_t ClassNumber;
|
||||
uint32_t Pipes[HOST_PIPE_COUNT];
|
||||
__IO uint32_t Timer;
|
||||
uint8_t id;
|
||||
void* pData;
|
||||
void (* pUser )(struct _USBH_HandleTypeDef *pHandle, uint8_t id);
|
||||
|
||||
#if (USBH_USE_OS == 1)
|
||||
osMessageQId os_event;
|
||||
osThreadId thread;
|
||||
#endif
|
||||
|
||||
} USBH_HandleTypeDef;
|
||||
|
||||
|
||||
#if defined ( __GNUC__ )
|
||||
#ifndef __weak
|
||||
#define __weak __attribute__((weak))
|
||||
#endif /* __weak */
|
||||
#ifndef __packed
|
||||
#define __packed __attribute__((__packed__))
|
||||
#endif /* __packed */
|
||||
#endif /* __GNUC__ */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* USBH_DEF_H */
|
||||
|
||||
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
|
||||
|
@ -0,0 +1,168 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file usbh_ioreq.h
|
||||
* @author MCD Application Team
|
||||
* @version V3.2.1
|
||||
* @date 26-June-2015
|
||||
* @brief Header file for usbh_ioreq.c
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* <h2><center>© COPYRIGHT 2015 STMicroelectronics</center></h2>
|
||||
*
|
||||
* Licensed under MCD-ST Liberty SW License Agreement V2, (the "License");
|
||||
* You may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at:
|
||||
*
|
||||
* http://www.st.com/software_license_agreement_liberty_v2
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
/* Define to prevent recursive ----------------------------------------------*/
|
||||
#ifndef __USBH_IOREQ_H
|
||||
#define __USBH_IOREQ_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include "usbh_config.h"
|
||||
#include "usbh_core.h"
|
||||
|
||||
/** @addtogroup USBH_LIB
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @addtogroup USBH_LIB_CORE
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @defgroup USBH_IOREQ
|
||||
* @brief This file is the header file for usbh_ioreq.c
|
||||
* @{
|
||||
*/
|
||||
|
||||
|
||||
/** @defgroup USBH_IOREQ_Exported_Defines
|
||||
* @{
|
||||
*/
|
||||
|
||||
#define USBH_PID_SETUP 0
|
||||
#define USBH_PID_DATA 1
|
||||
|
||||
#define USBH_EP_CONTROL 0
|
||||
#define USBH_EP_ISO 1
|
||||
#define USBH_EP_BULK 2
|
||||
#define USBH_EP_INTERRUPT 3
|
||||
|
||||
#define USBH_SETUP_PKT_SIZE 8
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
|
||||
/** @defgroup USBH_IOREQ_Exported_Types
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
|
||||
/** @defgroup USBH_IOREQ_Exported_Macros
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @defgroup USBH_IOREQ_Exported_Variables
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @defgroup USBH_IOREQ_Exported_FunctionsPrototype
|
||||
* @{
|
||||
*/
|
||||
USBH_StatusTypeDef USBH_CtlSendSetup (USBH_HandleTypeDef *phost,
|
||||
uint8_t *buff,
|
||||
uint8_t hc_num);
|
||||
|
||||
USBH_StatusTypeDef USBH_CtlSendData (USBH_HandleTypeDef *phost,
|
||||
uint8_t *buff,
|
||||
uint16_t length,
|
||||
uint8_t hc_num,
|
||||
uint8_t do_ping );
|
||||
|
||||
USBH_StatusTypeDef USBH_CtlReceiveData(USBH_HandleTypeDef *phost,
|
||||
uint8_t *buff,
|
||||
uint16_t length,
|
||||
uint8_t hc_num);
|
||||
|
||||
USBH_StatusTypeDef USBH_BulkReceiveData(USBH_HandleTypeDef *phost,
|
||||
uint8_t *buff,
|
||||
uint16_t length,
|
||||
uint8_t hc_num);
|
||||
|
||||
USBH_StatusTypeDef USBH_BulkSendData (USBH_HandleTypeDef *phost,
|
||||
uint8_t *buff,
|
||||
uint16_t length,
|
||||
uint8_t hc_num,
|
||||
uint8_t do_ping );
|
||||
|
||||
USBH_StatusTypeDef USBH_InterruptReceiveData(USBH_HandleTypeDef *phost,
|
||||
uint8_t *buff,
|
||||
uint8_t length,
|
||||
uint8_t hc_num);
|
||||
|
||||
USBH_StatusTypeDef USBH_InterruptSendData(USBH_HandleTypeDef *phost,
|
||||
uint8_t *buff,
|
||||
uint8_t length,
|
||||
uint8_t hc_num);
|
||||
|
||||
|
||||
USBH_StatusTypeDef USBH_IsocReceiveData(USBH_HandleTypeDef *phost,
|
||||
uint8_t *buff,
|
||||
uint32_t length,
|
||||
uint8_t hc_num);
|
||||
|
||||
|
||||
USBH_StatusTypeDef USBH_IsocSendData(USBH_HandleTypeDef *phost,
|
||||
uint8_t *buff,
|
||||
uint32_t length,
|
||||
uint8_t hc_num);
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __USBH_IOREQ_H */
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
|
||||
|
||||
|
@ -0,0 +1,131 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file usbh_pipes.h
|
||||
* @author MCD Application Team
|
||||
* @version V3.2.1
|
||||
* @date 26-June-2015
|
||||
* @brief Header file for usbh_pipes.c
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* <h2><center>© COPYRIGHT 2015 STMicroelectronics</center></h2>
|
||||
*
|
||||
* Licensed under MCD-ST Liberty SW License Agreement V2, (the "License");
|
||||
* You may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at:
|
||||
*
|
||||
* http://www.st.com/software_license_agreement_liberty_v2
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
/* Define to prevent recursive ----------------------------------------------*/
|
||||
#ifndef __USBH_PIPES_H
|
||||
#define __USBH_PIPES_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include "usbh_core.h"
|
||||
|
||||
/** @addtogroup USBH_LIB
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @addtogroup USBH_LIB_CORE
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @defgroup USBH_PIPES
|
||||
* @brief This file is the header file for usbh_pipes.c
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @defgroup USBH_PIPES_Exported_Defines
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @defgroup USBH_PIPES_Exported_Types
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
|
||||
/** @defgroup USBH_PIPES_Exported_Macros
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @defgroup USBH_PIPES_Exported_Variables
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @defgroup USBH_PIPES_Exported_FunctionsPrototype
|
||||
* @{
|
||||
*/
|
||||
|
||||
USBH_StatusTypeDef USBH_OpenPipe (USBH_HandleTypeDef *phost,
|
||||
uint8_t ch_num,
|
||||
uint8_t epnum,
|
||||
uint8_t dev_address,
|
||||
uint8_t speed,
|
||||
uint8_t ep_type,
|
||||
uint16_t mps);
|
||||
|
||||
USBH_StatusTypeDef USBH_ClosePipe (USBH_HandleTypeDef *phost,
|
||||
uint8_t pipe_num);
|
||||
|
||||
uint8_t USBH_AllocPipe (USBH_HandleTypeDef *phost,
|
||||
uint8_t ep_addr);
|
||||
|
||||
USBH_StatusTypeDef USBH_FreePipe (USBH_HandleTypeDef *phost,
|
||||
uint8_t idx);
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __USBH_PIPES_H */
|
||||
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
|
||||
|
||||
|
@ -0,0 +1,271 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file usb_bsp.c
|
||||
* @author MCD Application Team
|
||||
* @version V3.2.1
|
||||
* @date 26-June-2015
|
||||
* @brief This file implements the board support package for the USB host library
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* <h2><center>© COPYRIGHT 2015 STMicroelectronics</center></h2>
|
||||
*
|
||||
* Licensed under MCD-ST Liberty SW License Agreement V2, (the "License");
|
||||
* You may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at:
|
||||
*
|
||||
* http://www.st.com/software_license_agreement_liberty_v2
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include "usbh_core.h"
|
||||
|
||||
/**
|
||||
* @brief USBH_LL_Init
|
||||
* Initialize the Low Level portion of the Host driver.
|
||||
* @param phost: Host handle
|
||||
* @retval USBH Status
|
||||
*/
|
||||
USBH_StatusTypeDef USBH_LL_Init (USBH_HandleTypeDef *phost)
|
||||
{
|
||||
|
||||
return USBH_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief USBH_LL_DeInit
|
||||
* De-Initialize the Low Level portion of the Host driver.
|
||||
* @param phost: Host handle
|
||||
* @retval USBH Status
|
||||
*/
|
||||
USBH_StatusTypeDef USBH_LL_DeInit (USBH_HandleTypeDef *phost)
|
||||
{
|
||||
|
||||
return USBH_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief USBH_LL_Start
|
||||
* Start the Low Level portion of the Host driver.
|
||||
* @param phost: Host handle
|
||||
* @retval USBH Status
|
||||
*/
|
||||
USBH_StatusTypeDef USBH_LL_Start(USBH_HandleTypeDef *phost)
|
||||
{
|
||||
|
||||
return USBH_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief USBH_LL_Stop
|
||||
* Stop the Low Level portion of the Host driver.
|
||||
* @param phost: Host handle
|
||||
* @retval USBH Status
|
||||
*/
|
||||
USBH_StatusTypeDef USBH_LL_Stop (USBH_HandleTypeDef *phost)
|
||||
{
|
||||
|
||||
return USBH_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief USBH_LL_GetSpeed
|
||||
* Return the USB Host Speed from the Low Level Driver.
|
||||
* @param phost: Host handle
|
||||
* @retval USBH Speeds
|
||||
*/
|
||||
USBH_SpeedTypeDef USBH_LL_GetSpeed (USBH_HandleTypeDef *phost)
|
||||
{
|
||||
USBH_SpeedTypeDef speed = USBH_SPEED_FULL;
|
||||
|
||||
|
||||
return speed;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief USBH_LL_ResetPort
|
||||
* Reset the Host Port of the Low Level Driver.
|
||||
* @param phost: Host handle
|
||||
* @retval USBH Status
|
||||
*/
|
||||
USBH_StatusTypeDef USBH_LL_ResetPort (USBH_HandleTypeDef *phost)
|
||||
{
|
||||
|
||||
return USBH_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief USBH_LL_GetLastXferSize
|
||||
* Return the last transferred packet size.
|
||||
* @param phost: Host handle
|
||||
* @param pipe: Pipe index
|
||||
* @retval Packet Size
|
||||
*/
|
||||
uint32_t USBH_LL_GetLastXferSize (USBH_HandleTypeDef *phost, uint8_t pipe)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief USBH_LL_OpenPipe
|
||||
* Open a pipe of the Low Level Driver.
|
||||
* @param phost: Host handle
|
||||
* @param pipe_num: Pipe index
|
||||
* @param epnum: Endpoint Number
|
||||
* @param dev_address: Device USB address
|
||||
* @param speed: Device Speed
|
||||
* @param ep_type: Endpoint Type
|
||||
* @param mps: Endpoint Max Packet Size
|
||||
* @retval USBH Status
|
||||
*/
|
||||
USBH_StatusTypeDef USBH_LL_OpenPipe (USBH_HandleTypeDef *phost,
|
||||
uint8_t pipe_num,
|
||||
uint8_t epnum,
|
||||
uint8_t dev_address,
|
||||
uint8_t speed,
|
||||
uint8_t ep_type,
|
||||
uint16_t mps)
|
||||
{
|
||||
|
||||
return USBH_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief USBH_LL_ClosePipe
|
||||
* Close a pipe of the Low Level Driver.
|
||||
* @param phost: Host handle
|
||||
* @param pipe_num: Pipe index
|
||||
* @retval USBH Status
|
||||
*/
|
||||
USBH_StatusTypeDef USBH_LL_ClosePipe (USBH_HandleTypeDef *phost, uint8_t pipe)
|
||||
{
|
||||
return USBH_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief USBH_LL_SubmitURB
|
||||
* Submit a new URB to the low level driver.
|
||||
* @param phost: Host handle
|
||||
* @param pipe: Pipe index
|
||||
* This parameter can be a value from 1 to 15
|
||||
* @param direction : Channel number
|
||||
* This parameter can be one of the these values:
|
||||
* 0 : Output
|
||||
* 1 : Input
|
||||
* @param ep_type : Endpoint Type
|
||||
* This parameter can be one of the these values:
|
||||
* @arg EP_TYPE_CTRL: Control type
|
||||
* @arg EP_TYPE_ISOC: Isochronous type
|
||||
* @arg EP_TYPE_BULK: Bulk type
|
||||
* @arg EP_TYPE_INTR: Interrupt type
|
||||
* @param token : Endpoint Type
|
||||
* This parameter can be one of the these values:
|
||||
* @arg 0: PID_SETUP
|
||||
* @arg 1: PID_DATA
|
||||
* @param pbuff : pointer to URB data
|
||||
* @param length : Length of URB data
|
||||
* @param do_ping : activate do ping protocol (for high speed only)
|
||||
* This parameter can be one of the these values:
|
||||
* 0 : do ping inactive
|
||||
* 1 : do ping active
|
||||
* @retval Status
|
||||
*/
|
||||
|
||||
USBH_StatusTypeDef USBH_LL_SubmitURB (USBH_HandleTypeDef *phost,
|
||||
uint8_t pipe,
|
||||
uint8_t direction ,
|
||||
uint8_t ep_type,
|
||||
uint8_t token,
|
||||
uint8_t* pbuff,
|
||||
uint16_t length,
|
||||
uint8_t do_ping )
|
||||
{
|
||||
|
||||
return USBH_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief USBH_LL_GetURBState
|
||||
* Get a URB state from the low level driver.
|
||||
* @param phost: Host handle
|
||||
* @param pipe: Pipe index
|
||||
* This parameter can be a value from 1 to 15
|
||||
* @retval URB state
|
||||
* This parameter can be one of the these values:
|
||||
* @arg URB_IDLE
|
||||
* @arg URB_DONE
|
||||
* @arg URB_NOTREADY
|
||||
* @arg URB_NYET
|
||||
* @arg URB_ERROR
|
||||
* @arg URB_STALL
|
||||
*/
|
||||
USBH_URBStateTypeDef USBH_LL_GetURBState (USBH_HandleTypeDef *phost, uint8_t pipe)
|
||||
{
|
||||
return USBH_URB_IDLE;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief USBH_LL_DriverVBUS
|
||||
* Drive VBUS.
|
||||
* @param phost: Host handle
|
||||
* @param state : VBUS state
|
||||
* This parameter can be one of the these values:
|
||||
* 0 : VBUS Active
|
||||
* 1 : VBUS Inactive
|
||||
* @retval Status
|
||||
*/
|
||||
|
||||
USBH_StatusTypeDef USBH_LL_DriverVBUS (USBH_HandleTypeDef *phost, uint8_t state)
|
||||
{
|
||||
|
||||
return USBH_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief USBH_LL_SetToggle
|
||||
* Set toggle for a pipe.
|
||||
* @param phost: Host handle
|
||||
* @param pipe: Pipe index
|
||||
* @param pipe_num: Pipe index
|
||||
* @param toggle: toggle (0/1)
|
||||
* @retval Status
|
||||
*/
|
||||
USBH_StatusTypeDef USBH_LL_SetToggle (USBH_HandleTypeDef *phost, uint8_t pipe, uint8_t toggle)
|
||||
{
|
||||
|
||||
return USBH_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief USBH_LL_GetToggle
|
||||
* Return the current toggle of a pipe.
|
||||
* @param phost: Host handle
|
||||
* @param pipe: Pipe index
|
||||
* @retval toggle (0/1)
|
||||
*/
|
||||
uint8_t USBH_LL_GetToggle (USBH_HandleTypeDef *phost, uint8_t pipe)
|
||||
{
|
||||
uint8_t toggle = 0;
|
||||
|
||||
|
||||
return toggle;
|
||||
}
|
||||
/**
|
||||
* @brief USBH_Delay
|
||||
* Delay routine for the USB Host Library
|
||||
* @param Delay: Delay in ms
|
||||
* @retval None
|
||||
*/
|
||||
void USBH_Delay (uint32_t Delay)
|
||||
{
|
||||
|
||||
}
|
||||
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
|
@ -0,0 +1,962 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file usbh_core.c
|
||||
* @author MCD Application Team
|
||||
* @version V3.2.1
|
||||
* @date 26-June-2015
|
||||
* @brief This file implements the functions for the core state machine process
|
||||
* the enumeration and the control transfer process
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* <h2><center>© COPYRIGHT 2015 STMicroelectronics</center></h2>
|
||||
*
|
||||
* Licensed under MCD-ST Liberty SW License Agreement V2, (the "License");
|
||||
* You may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at:
|
||||
*
|
||||
* http://www.st.com/software_license_agreement_liberty_v2
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
******************************************************************************
|
||||
*
|
||||
* Modifications by Robert Fisk
|
||||
*/
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
|
||||
#include "usbh_core.h"
|
||||
|
||||
|
||||
/** @addtogroup USBH_LIB
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @addtogroup USBH_LIB_CORE
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @defgroup USBH_CORE
|
||||
* @brief This file handles the basic enumeration when a device is connected
|
||||
* to the host.
|
||||
* @{
|
||||
*/
|
||||
|
||||
|
||||
/** @defgroup USBH_CORE_Private_Defines
|
||||
* @{
|
||||
*/
|
||||
#define USBH_ADDRESS_DEFAULT 0
|
||||
#define USBH_ADDRESS_ASSIGNED 1
|
||||
#define USBH_MPS_DEFAULT 0x40
|
||||
|
||||
#define USBH_ATTACH_DELAY_MS 200
|
||||
#define USBH_DETACH_DELAY_MS 500
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @defgroup USBH_CORE_Private_Macros
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
|
||||
/** @defgroup USBH_CORE_Private_Variables
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
|
||||
/** @defgroup USBH_CORE_Private_Functions
|
||||
* @{
|
||||
*/
|
||||
static USBH_StatusTypeDef USBH_HandleEnum (USBH_HandleTypeDef *phost);
|
||||
static void USBH_HandleSof (USBH_HandleTypeDef *phost);
|
||||
static USBH_StatusTypeDef DeInitStateMachine(USBH_HandleTypeDef *phost);
|
||||
|
||||
#if (USBH_USE_OS == 1)
|
||||
static void USBH_Process_OS(void const * argument);
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief HCD_Init
|
||||
* Initialize the HOST Core.
|
||||
* @param phost: Host Handle
|
||||
* @param pUsrFunc: User Callback
|
||||
* @retval USBH Status
|
||||
*/
|
||||
USBH_StatusTypeDef USBH_Init(USBH_HandleTypeDef *phost, void (*pUsrFunc)(USBH_HandleTypeDef *phost, uint8_t ), uint8_t id)
|
||||
{
|
||||
/* Check whether the USB Host handle is valid */
|
||||
if(phost == NULL)
|
||||
{
|
||||
USBH_ErrLog("Invalid Host handle");
|
||||
return USBH_FAIL;
|
||||
}
|
||||
|
||||
/* Set DRiver ID */
|
||||
phost->id = id;
|
||||
|
||||
/* Unlink class*/
|
||||
phost->pActiveClass = NULL;
|
||||
phost->ClassNumber = 0;
|
||||
|
||||
/* Restore default states and prepare EP0 */
|
||||
DeInitStateMachine(phost);
|
||||
|
||||
/* Assign User process */
|
||||
if(pUsrFunc != NULL)
|
||||
{
|
||||
phost->pUser = pUsrFunc;
|
||||
}
|
||||
|
||||
#if (USBH_USE_OS == 1)
|
||||
|
||||
/* Create USB Host Queue */
|
||||
osMessageQDef(USBH_Queue, 10, uint16_t);
|
||||
phost->os_event = osMessageCreate (osMessageQ(USBH_Queue), NULL);
|
||||
|
||||
/*Create USB Host Task */
|
||||
#if defined (USBH_PROCESS_STACK_SIZE)
|
||||
osThreadDef(USBH_Thread, USBH_Process_OS, USBH_PROCESS_PRIO, 0, USBH_PROCESS_STACK_SIZE);
|
||||
#else
|
||||
osThreadDef(USBH_Thread, USBH_Process_OS, USBH_PROCESS_PRIO, 0, 8 * configMINIMAL_STACK_SIZE);
|
||||
#endif
|
||||
phost->thread = osThreadCreate (osThread(USBH_Thread), phost);
|
||||
#endif
|
||||
|
||||
/* Initialize low level driver */
|
||||
USBH_LL_Init(phost);
|
||||
return USBH_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief HCD_Init
|
||||
* De-Initialize the Host portion of the driver.
|
||||
* @param phost: Host Handle
|
||||
* @retval USBH Status
|
||||
*/
|
||||
USBH_StatusTypeDef USBH_DeInit(USBH_HandleTypeDef *phost)
|
||||
{
|
||||
DeInitStateMachine(phost);
|
||||
|
||||
if(phost->pData != NULL)
|
||||
{
|
||||
phost->pActiveClass->pData = NULL;
|
||||
USBH_LL_Stop(phost);
|
||||
}
|
||||
|
||||
USBH_LL_DeInit(phost);
|
||||
|
||||
return USBH_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief DeInitStateMachine
|
||||
* De-Initialize the Host state machine.
|
||||
* @param phost: Host Handle
|
||||
* @retval USBH Status
|
||||
*/
|
||||
static USBH_StatusTypeDef DeInitStateMachine(USBH_HandleTypeDef *phost)
|
||||
{
|
||||
uint32_t i = 0;
|
||||
|
||||
/* Clear Pipes flags*/
|
||||
for ( ; i < USBH_MAX_PIPES_NBR; i++)
|
||||
{
|
||||
phost->Pipes[i] = 0;
|
||||
}
|
||||
|
||||
for(i = 0; i< USBH_MAX_DATA_BUFFER; i++)
|
||||
{
|
||||
phost->device.Data[i] = 0;
|
||||
}
|
||||
|
||||
phost->gState = HOST_IDLE;
|
||||
phost->EnumState = ENUM_IDLE;
|
||||
phost->RequestState = CMD_SEND;
|
||||
phost->Timer = 0;
|
||||
|
||||
phost->Control.state = CTRL_SETUP;
|
||||
phost->Control.pipe_size = USBH_MPS_DEFAULT;
|
||||
phost->Control.errorcount = 0;
|
||||
|
||||
phost->device.address = USBH_ADDRESS_DEFAULT;
|
||||
phost->device.speed = USBH_SPEED_FULL;
|
||||
phost->device.is_connected = 0;
|
||||
|
||||
return USBH_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief USBH_RegisterClass
|
||||
* Link class driver to Host Core.
|
||||
* @param phost : Host Handle
|
||||
* @param pclass: Class handle
|
||||
* @retval USBH Status
|
||||
*/
|
||||
USBH_StatusTypeDef USBH_RegisterClass(USBH_HandleTypeDef *phost, USBH_ClassTypeDef *pclass)
|
||||
{
|
||||
USBH_StatusTypeDef status = USBH_OK;
|
||||
|
||||
if(pclass != 0)
|
||||
{
|
||||
if(phost->ClassNumber < USBH_MAX_NUM_SUPPORTED_CLASS)
|
||||
{
|
||||
/* link the class to the USB Host handle */
|
||||
phost->pClass[phost->ClassNumber++] = pclass;
|
||||
status = USBH_OK;
|
||||
}
|
||||
else
|
||||
{
|
||||
USBH_ErrLog("Max Class Number reached");
|
||||
status = USBH_FAIL;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
USBH_ErrLog("Invalid Class handle");
|
||||
status = USBH_FAIL;
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief USBH_SelectInterface
|
||||
* Select current interface.
|
||||
* @param phost: Host Handle
|
||||
* @param interface: Interface number
|
||||
* @retval USBH Status
|
||||
*/
|
||||
USBH_StatusTypeDef USBH_SelectInterface(USBH_HandleTypeDef *phost, uint8_t interface)
|
||||
{
|
||||
USBH_StatusTypeDef status = USBH_OK;
|
||||
|
||||
if(interface < phost->device.CfgDesc.bNumInterfaces)
|
||||
{
|
||||
phost->device.current_interface = interface;
|
||||
USBH_UsrLog ("Switching to Interface (#%d)", interface);
|
||||
USBH_UsrLog ("Class : %xh", phost->device.CfgDesc.Itf_Desc[interface].bInterfaceClass );
|
||||
USBH_UsrLog ("SubClass : %xh", phost->device.CfgDesc.Itf_Desc[interface].bInterfaceSubClass );
|
||||
USBH_UsrLog ("Protocol : %xh", phost->device.CfgDesc.Itf_Desc[interface].bInterfaceProtocol );
|
||||
}
|
||||
else
|
||||
{
|
||||
USBH_ErrLog ("Cannot Select This Interface.");
|
||||
status = USBH_FAIL;
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief USBH_GetActiveClass
|
||||
* Return Device Class.
|
||||
* @param phost: Host Handle
|
||||
* @param interface: Interface index
|
||||
* @retval Class Code
|
||||
*/
|
||||
uint8_t USBH_GetActiveClass(USBH_HandleTypeDef *phost)
|
||||
{
|
||||
return (phost->device.CfgDesc.Itf_Desc[0].bInterfaceClass);
|
||||
}
|
||||
/**
|
||||
* @brief USBH_FindInterface
|
||||
* Find the interface index for a specific class.
|
||||
* @param phost: Host Handle
|
||||
* @param Class: Class code
|
||||
* @param SubClass: SubClass code
|
||||
* @param Protocol: Protocol code
|
||||
* @retval interface index in the configuration structure
|
||||
* @note : (1)interface index 0xFF means interface index not found
|
||||
*/
|
||||
uint8_t USBH_FindInterface(USBH_HandleTypeDef *phost, uint8_t Class, uint8_t SubClass, uint8_t Protocol)
|
||||
{
|
||||
USBH_InterfaceDescTypeDef *pif ;
|
||||
USBH_CfgDescTypeDef *pcfg ;
|
||||
int8_t if_ix = 0;
|
||||
|
||||
pif = (USBH_InterfaceDescTypeDef *)0;
|
||||
pcfg = &phost->device.CfgDesc;
|
||||
|
||||
while (if_ix < USBH_MAX_NUM_INTERFACES)
|
||||
{
|
||||
pif = &pcfg->Itf_Desc[if_ix];
|
||||
if(((pif->bInterfaceClass == Class) || (Class == 0xFF))&&
|
||||
((pif->bInterfaceSubClass == SubClass) || (SubClass == 0xFF))&&
|
||||
((pif->bInterfaceProtocol == Protocol) || (Protocol == 0xFF)))
|
||||
{
|
||||
return if_ix;
|
||||
}
|
||||
if_ix++;
|
||||
}
|
||||
return 0xFF;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief USBH_FindInterfaceIndex
|
||||
* Find the interface index for a specific class interface and alternate setting number.
|
||||
* @param phost: Host Handle
|
||||
* @param interface_number: interface number
|
||||
* @param alt_settings : alternate setting number
|
||||
* @retval interface index in the configuration structure
|
||||
* @note : (1)interface index 0xFF means interface index not found
|
||||
*/
|
||||
uint8_t USBH_FindInterfaceIndex(USBH_HandleTypeDef *phost, uint8_t interface_number, uint8_t alt_settings)
|
||||
{
|
||||
USBH_InterfaceDescTypeDef *pif ;
|
||||
USBH_CfgDescTypeDef *pcfg ;
|
||||
int8_t if_ix = 0;
|
||||
|
||||
pif = (USBH_InterfaceDescTypeDef *)0;
|
||||
pcfg = &phost->device.CfgDesc;
|
||||
|
||||
while (if_ix < USBH_MAX_NUM_INTERFACES)
|
||||
{
|
||||
pif = &pcfg->Itf_Desc[if_ix];
|
||||
if((pif->bInterfaceNumber == interface_number) && (pif->bAlternateSetting == alt_settings))
|
||||
{
|
||||
return if_ix;
|
||||
}
|
||||
if_ix++;
|
||||
}
|
||||
return 0xFF;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief USBH_Start
|
||||
* Start the USB Host Core.
|
||||
* @param phost: Host Handle
|
||||
* @retval USBH Status
|
||||
*/
|
||||
USBH_StatusTypeDef USBH_Start (USBH_HandleTypeDef *phost)
|
||||
{
|
||||
/* Start the low level driver */
|
||||
USBH_LL_Start(phost);
|
||||
|
||||
/* Activate VBUS on the port */
|
||||
USBH_LL_DriverVBUS (phost, TRUE);
|
||||
|
||||
return USBH_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief USBH_Stop
|
||||
* Stop the USB Host Core.
|
||||
* @param phost: Host Handle
|
||||
* @retval USBH Status
|
||||
*/
|
||||
USBH_StatusTypeDef USBH_Stop (USBH_HandleTypeDef *phost)
|
||||
{
|
||||
/* Stop and cleanup the low level driver */
|
||||
USBH_LL_Stop(phost);
|
||||
|
||||
/* DeActivate VBUS on the port */
|
||||
USBH_LL_DriverVBUS (phost, FALSE);
|
||||
|
||||
/* FRee Control Pipes */
|
||||
USBH_FreePipe (phost, phost->Control.pipe_in);
|
||||
USBH_FreePipe (phost, phost->Control.pipe_out);
|
||||
|
||||
return USBH_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief HCD_ReEnumerate
|
||||
* Perform a new Enumeration phase.
|
||||
* @param phost: Host Handle
|
||||
* @retval USBH Status
|
||||
*/
|
||||
USBH_StatusTypeDef USBH_ReEnumerate (USBH_HandleTypeDef *phost)
|
||||
{
|
||||
/*Stop Host */
|
||||
USBH_Stop(phost);
|
||||
|
||||
/*Device has disconnected, so wait for 200 ms */
|
||||
USBH_Delay(200);
|
||||
|
||||
/* Set State machines in default state */
|
||||
DeInitStateMachine(phost);
|
||||
|
||||
/* Start again the host */
|
||||
USBH_Start(phost);
|
||||
|
||||
#if (USBH_USE_OS == 1)
|
||||
osMessagePut ( phost->os_event, USBH_PORT_EVENT, 0);
|
||||
#endif
|
||||
return USBH_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief USBH_Process
|
||||
* Background process of the USB Core.
|
||||
* @param phost: Host Handle
|
||||
* @retval USBH Status
|
||||
*/
|
||||
USBH_StatusTypeDef USBH_Process(USBH_HandleTypeDef *phost)
|
||||
{
|
||||
__IO USBH_StatusTypeDef status = USBH_FAIL;
|
||||
uint8_t idx = 0;
|
||||
|
||||
switch (phost->gState)
|
||||
{
|
||||
case HOST_IDLE:
|
||||
|
||||
if (phost->device.is_connected)
|
||||
{
|
||||
/* Wait for 200 ms after connection */
|
||||
phost->gState = HOST_DEV_WAIT_FOR_ATTACHMENT;
|
||||
USBH_Delay(USBH_ATTACH_DELAY_MS);
|
||||
USBH_LL_ResetPort(phost);
|
||||
#if (USBH_USE_OS == 1)
|
||||
osMessagePut ( phost->os_event, USBH_PORT_EVENT, 0);
|
||||
#endif
|
||||
}
|
||||
break;
|
||||
|
||||
case HOST_DEV_WAIT_FOR_ATTACHMENT:
|
||||
break;
|
||||
|
||||
case HOST_DEV_ATTACHED :
|
||||
|
||||
USBH_UsrLog("USB Device Attached");
|
||||
|
||||
/* Wait for 100 ms after Reset */
|
||||
USBH_Delay(100);
|
||||
|
||||
phost->device.speed = USBH_LL_GetSpeed(phost);
|
||||
|
||||
phost->gState = HOST_ENUMERATION;
|
||||
|
||||
phost->Control.pipe_out = USBH_AllocPipe (phost, 0x00);
|
||||
phost->Control.pipe_in = USBH_AllocPipe (phost, 0x80);
|
||||
|
||||
|
||||
/* Open Control pipes */
|
||||
USBH_OpenPipe (phost,
|
||||
phost->Control.pipe_in,
|
||||
0x80,
|
||||
phost->device.address,
|
||||
phost->device.speed,
|
||||
USBH_EP_CONTROL,
|
||||
phost->Control.pipe_size);
|
||||
|
||||
/* Open Control pipes */
|
||||
USBH_OpenPipe (phost,
|
||||
phost->Control.pipe_out,
|
||||
0x00,
|
||||
phost->device.address,
|
||||
phost->device.speed,
|
||||
USBH_EP_CONTROL,
|
||||
phost->Control.pipe_size);
|
||||
|
||||
#if (USBH_USE_OS == 1)
|
||||
osMessagePut ( phost->os_event, USBH_PORT_EVENT, 0);
|
||||
#endif
|
||||
|
||||
break;
|
||||
|
||||
case HOST_ENUMERATION:
|
||||
/* Check for enumeration status */
|
||||
if ( USBH_HandleEnum(phost) == USBH_OK)
|
||||
{
|
||||
/* The function shall return USBH_OK when full enumeration is complete */
|
||||
USBH_UsrLog ("Enumeration done.");
|
||||
phost->device.current_interface = 0;
|
||||
if(phost->device.DevDesc.bNumConfigurations == 1)
|
||||
{
|
||||
USBH_UsrLog ("This device has only 1 configuration.");
|
||||
phost->gState = HOST_SET_CONFIGURATION;
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
phost->gState = HOST_INPUT;
|
||||
}
|
||||
|
||||
}
|
||||
break;
|
||||
|
||||
case HOST_INPUT:
|
||||
{
|
||||
/* user callback for end of device basic enumeration */
|
||||
if(phost->pUser != NULL)
|
||||
{
|
||||
phost->pUser(phost, HOST_USER_SELECT_CONFIGURATION);
|
||||
phost->gState = HOST_SET_CONFIGURATION;
|
||||
|
||||
#if (USBH_USE_OS == 1)
|
||||
osMessagePut ( phost->os_event, USBH_STATE_CHANGED_EVENT, 0);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case HOST_SET_CONFIGURATION:
|
||||
/* set configuration */
|
||||
if (USBH_SetCfg(phost, phost->device.CfgDesc.bConfigurationValue) == USBH_OK)
|
||||
{
|
||||
phost->gState = HOST_CHECK_CLASS;
|
||||
USBH_UsrLog ("Default configuration set.");
|
||||
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case HOST_CHECK_CLASS:
|
||||
|
||||
if(phost->ClassNumber == 0)
|
||||
{
|
||||
USBH_UsrLog ("No Class has been registered.");
|
||||
}
|
||||
else
|
||||
{
|
||||
phost->pActiveClass = NULL;
|
||||
|
||||
for (idx = 0; idx < USBH_MAX_NUM_SUPPORTED_CLASS ; idx ++)
|
||||
{
|
||||
if(phost->pClass[idx]->ClassCode == phost->device.CfgDesc.Itf_Desc[0].bInterfaceClass)
|
||||
{
|
||||
phost->pActiveClass = phost->pClass[idx];
|
||||
}
|
||||
}
|
||||
|
||||
if(phost->pActiveClass != NULL)
|
||||
{
|
||||
if(phost->pActiveClass->Init(phost)== USBH_OK)
|
||||
{
|
||||
phost->gState = HOST_CLASS_REQUEST;
|
||||
USBH_UsrLog ("%s class started.", phost->pActiveClass->Name);
|
||||
|
||||
/* Inform user that a class has been activated */
|
||||
phost->pUser(phost, HOST_USER_CLASS_SELECTED);
|
||||
}
|
||||
else
|
||||
{
|
||||
phost->pUser(phost, HOST_USER_CLASS_FAILED);
|
||||
phost->gState = HOST_ABORT_STATE;
|
||||
USBH_UsrLog ("Device not supporting %s class.", phost->pActiveClass->Name);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
phost->pUser(phost, HOST_USER_CLASS_FAILED);
|
||||
phost->gState = HOST_ABORT_STATE;
|
||||
USBH_UsrLog ("No registered class for this device.");
|
||||
}
|
||||
}
|
||||
|
||||
#if (USBH_USE_OS == 1)
|
||||
osMessagePut ( phost->os_event, USBH_STATE_CHANGED_EVENT, 0);
|
||||
#endif
|
||||
break;
|
||||
|
||||
case HOST_CLASS_REQUEST:
|
||||
/* process class standard control requests state machine */
|
||||
if(phost->pActiveClass != NULL)
|
||||
{
|
||||
status = phost->pActiveClass->Requests(phost);
|
||||
|
||||
if(status == USBH_OK)
|
||||
{
|
||||
phost->gState = HOST_CLASS;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
phost->gState = HOST_ABORT_STATE;
|
||||
USBH_ErrLog ("Invalid Class Driver.");
|
||||
|
||||
#if (USBH_USE_OS == 1)
|
||||
osMessagePut ( phost->os_event, USBH_STATE_CHANGED_EVENT, 0);
|
||||
#endif
|
||||
}
|
||||
|
||||
break;
|
||||
case HOST_CLASS:
|
||||
/* process class state machine */
|
||||
if(phost->pActiveClass != NULL)
|
||||
{
|
||||
phost->pActiveClass->BgndProcess(phost);
|
||||
}
|
||||
break;
|
||||
|
||||
case HOST_DEV_DISCONNECTED:
|
||||
USBH_Delay(USBH_DETACH_DELAY_MS);
|
||||
DeInitStateMachine(phost);
|
||||
|
||||
/* Re-Initilaize Host for new Enumeration */
|
||||
if(phost->pActiveClass != NULL)
|
||||
{
|
||||
phost->pActiveClass->DeInit(phost);
|
||||
phost->pActiveClass = NULL;
|
||||
}
|
||||
break;
|
||||
|
||||
case HOST_ABORT_STATE:
|
||||
default :
|
||||
break;
|
||||
}
|
||||
return USBH_OK;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief USBH_HandleEnum
|
||||
* This function includes the complete enumeration process
|
||||
* @param phost: Host Handle
|
||||
* @retval USBH_Status
|
||||
*/
|
||||
static USBH_StatusTypeDef USBH_HandleEnum (USBH_HandleTypeDef *phost)
|
||||
{
|
||||
USBH_StatusTypeDef Status = USBH_BUSY;
|
||||
|
||||
switch (phost->EnumState)
|
||||
{
|
||||
case ENUM_IDLE:
|
||||
/* Get Device Desc for only 1st 8 bytes : To get EP0 MaxPacketSize */
|
||||
if ( USBH_Get_DevDesc(phost, 8) == USBH_OK)
|
||||
{
|
||||
phost->Control.pipe_size = phost->device.DevDesc.bMaxPacketSize;
|
||||
|
||||
phost->EnumState = ENUM_GET_FULL_DEV_DESC;
|
||||
|
||||
/* modify control channels configuration for MaxPacket size */
|
||||
USBH_OpenPipe (phost,
|
||||
phost->Control.pipe_in,
|
||||
0x80,
|
||||
phost->device.address,
|
||||
phost->device.speed,
|
||||
USBH_EP_CONTROL,
|
||||
phost->Control.pipe_size);
|
||||
|
||||
/* Open Control pipes */
|
||||
USBH_OpenPipe (phost,
|
||||
phost->Control.pipe_out,
|
||||
0x00,
|
||||
phost->device.address,
|
||||
phost->device.speed,
|
||||
USBH_EP_CONTROL,
|
||||
phost->Control.pipe_size);
|
||||
|
||||
}
|
||||
break;
|
||||
|
||||
case ENUM_GET_FULL_DEV_DESC:
|
||||
/* Get FULL Device Desc */
|
||||
if ( USBH_Get_DevDesc(phost, USB_DEVICE_DESC_SIZE)== USBH_OK)
|
||||
{
|
||||
USBH_UsrLog("PID: %xh", phost->device.DevDesc.idProduct );
|
||||
USBH_UsrLog("VID: %xh", phost->device.DevDesc.idVendor );
|
||||
|
||||
phost->EnumState = ENUM_SET_ADDR;
|
||||
|
||||
}
|
||||
break;
|
||||
|
||||
case ENUM_SET_ADDR:
|
||||
/* set address */
|
||||
if ( USBH_SetAddress(phost, USBH_DEVICE_ADDRESS) == USBH_OK)
|
||||
{
|
||||
USBH_Delay(2);
|
||||
phost->device.address = USBH_DEVICE_ADDRESS;
|
||||
|
||||
/* user callback for device address assigned */
|
||||
USBH_UsrLog("Address (#%d) assigned.", phost->device.address);
|
||||
phost->EnumState = ENUM_GET_CFG_DESC;
|
||||
|
||||
/* modify control channels to update device address */
|
||||
USBH_OpenPipe (phost,
|
||||
phost->Control.pipe_in,
|
||||
0x80,
|
||||
phost->device.address,
|
||||
phost->device.speed,
|
||||
USBH_EP_CONTROL,
|
||||
phost->Control.pipe_size);
|
||||
|
||||
/* Open Control pipes */
|
||||
USBH_OpenPipe (phost,
|
||||
phost->Control.pipe_out,
|
||||
0x00,
|
||||
phost->device.address,
|
||||
phost->device.speed,
|
||||
USBH_EP_CONTROL,
|
||||
phost->Control.pipe_size);
|
||||
}
|
||||
break;
|
||||
|
||||
case ENUM_GET_CFG_DESC:
|
||||
/* get standard configuration descriptor */
|
||||
if ( USBH_Get_CfgDesc(phost,
|
||||
USB_CONFIGURATION_DESC_SIZE) == USBH_OK)
|
||||
{
|
||||
phost->EnumState = ENUM_GET_FULL_CFG_DESC;
|
||||
}
|
||||
break;
|
||||
|
||||
case ENUM_GET_FULL_CFG_DESC:
|
||||
/* get FULL config descriptor (config, interface, endpoints) */
|
||||
if (USBH_Get_CfgDesc(phost,
|
||||
phost->device.CfgDesc.wTotalLength) == USBH_OK)
|
||||
{
|
||||
phost->EnumState = ENUM_GET_MFC_STRING_DESC;
|
||||
}
|
||||
break;
|
||||
|
||||
case ENUM_GET_MFC_STRING_DESC:
|
||||
if (phost->device.DevDesc.iManufacturer != 0)
|
||||
{ /* Check that Manufacturer String is available */
|
||||
|
||||
if ( USBH_Get_StringDesc(phost,
|
||||
phost->device.DevDesc.iManufacturer,
|
||||
phost->device.Data ,
|
||||
0xff) == USBH_OK)
|
||||
{
|
||||
/* User callback for Manufacturing string */
|
||||
USBH_UsrLog("Manufacturer : %s", (char *)phost->device.Data);
|
||||
phost->EnumState = ENUM_GET_PRODUCT_STRING_DESC;
|
||||
|
||||
#if (USBH_USE_OS == 1)
|
||||
osMessagePut ( phost->os_event, USBH_STATE_CHANGED_EVENT, 0);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
USBH_UsrLog("Manufacturer : N/A");
|
||||
phost->EnumState = ENUM_GET_PRODUCT_STRING_DESC;
|
||||
#if (USBH_USE_OS == 1)
|
||||
osMessagePut ( phost->os_event, USBH_STATE_CHANGED_EVENT, 0);
|
||||
#endif
|
||||
}
|
||||
break;
|
||||
|
||||
case ENUM_GET_PRODUCT_STRING_DESC:
|
||||
if (phost->device.DevDesc.iProduct != 0)
|
||||
{ /* Check that Product string is available */
|
||||
if ( USBH_Get_StringDesc(phost,
|
||||
phost->device.DevDesc.iProduct,
|
||||
phost->device.Data,
|
||||
0xff) == USBH_OK)
|
||||
{
|
||||
/* User callback for Product string */
|
||||
USBH_UsrLog("Product : %s", (char *)phost->device.Data);
|
||||
phost->EnumState = ENUM_GET_SERIALNUM_STRING_DESC;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
USBH_UsrLog("Product : N/A");
|
||||
phost->EnumState = ENUM_GET_SERIALNUM_STRING_DESC;
|
||||
#if (USBH_USE_OS == 1)
|
||||
osMessagePut ( phost->os_event, USBH_STATE_CHANGED_EVENT, 0);
|
||||
#endif
|
||||
}
|
||||
break;
|
||||
|
||||
case ENUM_GET_SERIALNUM_STRING_DESC:
|
||||
if (phost->device.DevDesc.iSerialNumber != 0)
|
||||
{ /* Check that Serial number string is available */
|
||||
if ( USBH_Get_StringDesc(phost,
|
||||
phost->device.DevDesc.iSerialNumber,
|
||||
phost->device.Data,
|
||||
0xff) == USBH_OK)
|
||||
{
|
||||
/* User callback for Serial number string */
|
||||
USBH_UsrLog("Serial Number : %s", (char *)phost->device.Data);
|
||||
Status = USBH_OK;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
USBH_UsrLog("Serial Number : N/A");
|
||||
Status = USBH_OK;
|
||||
#if (USBH_USE_OS == 1)
|
||||
osMessagePut ( phost->os_event, USBH_STATE_CHANGED_EVENT, 0);
|
||||
#endif
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return Status;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief USBH_LL_SetTimer
|
||||
* Set the initial Host Timer tick
|
||||
* @param phost: Host Handle
|
||||
* @retval None
|
||||
*/
|
||||
void USBH_LL_SetTimer (USBH_HandleTypeDef *phost, uint32_t time)
|
||||
{
|
||||
phost->Timer = time;
|
||||
}
|
||||
/**
|
||||
* @brief USBH_LL_IncTimer
|
||||
* Increment Host Timer tick
|
||||
* @param phost: Host Handle
|
||||
* @retval None
|
||||
*/
|
||||
void USBH_LL_IncTimer (USBH_HandleTypeDef *phost)
|
||||
{
|
||||
phost->Timer ++;
|
||||
USBH_HandleSof(phost);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief USBH_HandleSof
|
||||
* Call SOF process
|
||||
* @param phost: Host Handle
|
||||
* @retval None
|
||||
*/
|
||||
void USBH_HandleSof (USBH_HandleTypeDef *phost)
|
||||
{
|
||||
if((phost->gState == HOST_CLASS)&&(phost->pActiveClass != NULL))
|
||||
{
|
||||
phost->pActiveClass->SOFProcess(phost);
|
||||
}
|
||||
}
|
||||
/**
|
||||
* @brief USBH_LL_Connect
|
||||
* Handle USB Host connexion event
|
||||
* @param phost: Host Handle
|
||||
* @retval USBH_Status
|
||||
*/
|
||||
USBH_StatusTypeDef USBH_LL_Connect (USBH_HandleTypeDef *phost)
|
||||
{
|
||||
if(phost->gState == HOST_IDLE )
|
||||
{
|
||||
phost->device.is_connected = 1;
|
||||
|
||||
if(phost->pUser != NULL)
|
||||
{
|
||||
phost->pUser(phost, HOST_USER_CONNECTION);
|
||||
}
|
||||
}
|
||||
else if (phost->gState == HOST_DEV_WAIT_FOR_ATTACHMENT)
|
||||
{
|
||||
//On a cold boot with a low-speed device pre-attached,
|
||||
//we get a second port-connected interrupt!???
|
||||
//So go back and do the port reset again...
|
||||
phost->gState = HOST_IDLE;
|
||||
}
|
||||
return USBH_OK;
|
||||
}
|
||||
|
||||
|
||||
|
||||
USBH_StatusTypeDef USBH_LL_PortEnabled (USBH_HandleTypeDef *phost)
|
||||
{
|
||||
if(phost->gState == HOST_DEV_WAIT_FOR_ATTACHMENT )
|
||||
{
|
||||
phost->gState = HOST_DEV_ATTACHED ;
|
||||
}
|
||||
return USBH_OK;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief USBH_LL_Disconnect
|
||||
* Handle USB Host disconnection event
|
||||
* @param phost: Host Handle
|
||||
* @retval USBH_Status
|
||||
*/
|
||||
USBH_StatusTypeDef USBH_LL_Disconnect (USBH_HandleTypeDef *phost)
|
||||
{
|
||||
//Ignore false disconnect interrupt that sometimes intrudes
|
||||
//while we are waiting for the port to enable :(
|
||||
if (phost->gState == HOST_DEV_WAIT_FOR_ATTACHMENT)
|
||||
{
|
||||
return USBH_FAIL;
|
||||
}
|
||||
|
||||
/*Stop Host */
|
||||
USBH_LL_Stop(phost);
|
||||
|
||||
/* FRee Control Pipes */
|
||||
USBH_FreePipe (phost, phost->Control.pipe_in);
|
||||
USBH_FreePipe (phost, phost->Control.pipe_out);
|
||||
|
||||
phost->device.is_connected = 0;
|
||||
|
||||
if(phost->pUser != NULL)
|
||||
{
|
||||
phost->pUser(phost, HOST_USER_DISCONNECTION);
|
||||
}
|
||||
USBH_UsrLog("USB Device disconnected");
|
||||
|
||||
/* Start the low level driver */
|
||||
USBH_LL_Start(phost);
|
||||
|
||||
phost->gState = HOST_DEV_DISCONNECTED;
|
||||
|
||||
#if (USBH_USE_OS == 1)
|
||||
osMessagePut ( phost->os_event, USBH_PORT_EVENT, 0);
|
||||
#endif
|
||||
|
||||
return USBH_OK;
|
||||
}
|
||||
|
||||
|
||||
#if (USBH_USE_OS == 1)
|
||||
/**
|
||||
* @brief USB Host Thread task
|
||||
* @param pvParameters not used
|
||||
* @retval None
|
||||
*/
|
||||
static void USBH_Process_OS(void const * argument)
|
||||
{
|
||||
osEvent event;
|
||||
|
||||
for(;;)
|
||||
{
|
||||
event = osMessageGet(((USBH_HandleTypeDef *)argument)->os_event, osWaitForever );
|
||||
|
||||
if( event.status == osEventMessage )
|
||||
{
|
||||
USBH_Process((USBH_HandleTypeDef *)argument);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief USBH_LL_NotifyURBChange
|
||||
* Notify URB state Change
|
||||
* @param phost: Host handle
|
||||
* @retval USBH Status
|
||||
*/
|
||||
USBH_StatusTypeDef USBH_LL_NotifyURBChange (USBH_HandleTypeDef *phost)
|
||||
{
|
||||
osMessagePut ( phost->os_event, USBH_URB_EVENT, 0);
|
||||
return USBH_OK;
|
||||
}
|
||||
#endif
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
|
@ -0,0 +1,870 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file usbh_ctlreq.c
|
||||
* @author MCD Application Team
|
||||
* @version V3.2.1
|
||||
* @date 26-June-2015
|
||||
* @brief This file implements the control requests for device enumeration
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* <h2><center>© COPYRIGHT 2015 STMicroelectronics</center></h2>
|
||||
*
|
||||
* Licensed under MCD-ST Liberty SW License Agreement V2, (the "License");
|
||||
* You may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at:
|
||||
*
|
||||
* http://www.st.com/software_license_agreement_liberty_v2
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
******************************************************************************
|
||||
*
|
||||
* Modifications by Robert Fisk
|
||||
*/
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
|
||||
#include "usbh_ctlreq.h"
|
||||
|
||||
/** @addtogroup USBH_LIB
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @addtogroup USBH_LIB_CORE
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @defgroup USBH_CTLREQ
|
||||
* @brief This file implements the standard requests for device enumeration
|
||||
* @{
|
||||
*/
|
||||
|
||||
|
||||
/** @defgroup USBH_CTLREQ_Private_Defines
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
|
||||
/** @defgroup USBH_CTLREQ_Private_TypesDefinitions
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
|
||||
|
||||
/** @defgroup USBH_CTLREQ_Private_Macros
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
|
||||
/** @defgroup USBH_CTLREQ_Private_Variables
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @defgroup USBH_CTLREQ_Private_FunctionPrototypes
|
||||
* @{
|
||||
*/
|
||||
static USBH_StatusTypeDef USBH_HandleControl (USBH_HandleTypeDef *phost);
|
||||
|
||||
static void USBH_ParseDevDesc (USBH_DevDescTypeDef* , uint8_t *buf, uint16_t length);
|
||||
|
||||
static void USBH_ParseCfgDesc (USBH_CfgDescTypeDef* cfg_desc,
|
||||
uint8_t *buf,
|
||||
uint16_t length);
|
||||
|
||||
|
||||
static void USBH_ParseEPDesc (USBH_EpDescTypeDef *ep_descriptor, uint8_t *buf);
|
||||
static void USBH_ParseStringDesc (uint8_t* psrc, uint8_t* pdest, uint16_t length);
|
||||
static void USBH_ParseInterfaceDesc (USBH_InterfaceDescTypeDef *if_descriptor, uint8_t *buf);
|
||||
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
|
||||
/** @defgroup USBH_CTLREQ_Private_Functions
|
||||
* @{
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* @brief USBH_Get_DevDesc
|
||||
* Issue Get Device Descriptor command to the device. Once the response
|
||||
* received, it parses the device descriptor and updates the status.
|
||||
* @param phost: Host Handle
|
||||
* @param length: Length of the descriptor
|
||||
* @retval USBH Status
|
||||
*/
|
||||
USBH_StatusTypeDef USBH_Get_DevDesc(USBH_HandleTypeDef *phost, uint16_t length)
|
||||
{
|
||||
USBH_StatusTypeDef status;
|
||||
|
||||
if (length > USBH_MAX_DATA_BUFFER)
|
||||
{
|
||||
length = USBH_MAX_DATA_BUFFER;
|
||||
}
|
||||
|
||||
if((status = USBH_GetDescriptor(phost,
|
||||
USB_REQ_RECIPIENT_DEVICE | USB_REQ_TYPE_STANDARD,
|
||||
USB_DESC_DEVICE,
|
||||
0,
|
||||
phost->device.Data,
|
||||
length)) == USBH_OK)
|
||||
{
|
||||
/* Commands successfully sent and Response Received */
|
||||
USBH_ParseDevDesc(&phost->device.DevDesc, phost->device.Data, length);
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief USBH_Get_CfgDesc
|
||||
* Issues Configuration Descriptor to the device. Once the response
|
||||
* received, it parses the configuration descriptor and updates the
|
||||
* status.
|
||||
* @param phost: Host Handle
|
||||
* @param length: Length of the descriptor
|
||||
* @retval USBH Status
|
||||
*/
|
||||
USBH_StatusTypeDef USBH_Get_CfgDesc(USBH_HandleTypeDef *phost,
|
||||
uint16_t length)
|
||||
|
||||
{
|
||||
USBH_StatusTypeDef status;
|
||||
uint8_t *pData;
|
||||
|
||||
#if (USBH_KEEP_CFG_DESCRIPTOR == 1)
|
||||
pData = phost->device.CfgDesc_Raw;
|
||||
|
||||
if (length > USBH_MAX_SIZE_CONFIGURATION)
|
||||
{
|
||||
length = USBH_MAX_SIZE_CONFIGURATION;
|
||||
}
|
||||
#else
|
||||
pData = phost->device.Data;
|
||||
|
||||
if (length > USBH_MAX_DATA_BUFFER)
|
||||
{
|
||||
length = USBH_MAX_DATA_BUFFER;
|
||||
}
|
||||
#endif
|
||||
if((status = USBH_GetDescriptor(phost,
|
||||
USB_REQ_RECIPIENT_DEVICE | USB_REQ_TYPE_STANDARD,
|
||||
USB_DESC_CONFIGURATION,
|
||||
0,
|
||||
pData,
|
||||
length)) == USBH_OK)
|
||||
{
|
||||
/* Commands successfully sent and Response Received */
|
||||
USBH_ParseCfgDesc (&phost->device.CfgDesc,
|
||||
pData,
|
||||
length);
|
||||
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief USBH_Get_StringDesc
|
||||
* Issues string Descriptor command to the device. Once the response
|
||||
* received, it parses the string descriptor and updates the status.
|
||||
* @param phost: Host Handle
|
||||
* @param string_index: String index for the descriptor
|
||||
* @param buff: Buffer address for the descriptor
|
||||
* @param length: Length of the descriptor
|
||||
* @retval USBH Status
|
||||
*/
|
||||
USBH_StatusTypeDef USBH_Get_StringDesc(USBH_HandleTypeDef *phost,
|
||||
uint8_t string_index,
|
||||
uint8_t *buff,
|
||||
uint16_t length)
|
||||
{
|
||||
USBH_StatusTypeDef status;
|
||||
|
||||
if (length > USBH_MAX_DATA_BUFFER)
|
||||
{
|
||||
length = USBH_MAX_DATA_BUFFER;
|
||||
}
|
||||
|
||||
if((status = USBH_GetDescriptor(phost,
|
||||
USB_REQ_RECIPIENT_DEVICE | USB_REQ_TYPE_STANDARD,
|
||||
USB_DESC_STRING | string_index,
|
||||
0x0409,
|
||||
phost->device.Data,
|
||||
length)) == USBH_OK)
|
||||
{
|
||||
/* Commands successfully sent and Response Received */
|
||||
USBH_ParseStringDesc(phost->device.Data,buff, length);
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief USBH_GetDescriptor
|
||||
* Issues Descriptor command to the device. Once the response received,
|
||||
* it parses the descriptor and updates the status.
|
||||
* @param phost: Host Handle
|
||||
* @param req_type: Descriptor type
|
||||
* @param value_idx: Value for the GetDescriptr request
|
||||
* @param buff: Buffer to store the descriptor
|
||||
* @param length: Length of the descriptor
|
||||
* @retval USBH Status
|
||||
*/
|
||||
USBH_StatusTypeDef USBH_GetDescriptor(USBH_HandleTypeDef *phost,
|
||||
uint8_t req_type,
|
||||
uint16_t type_idx,
|
||||
uint16_t value,
|
||||
uint8_t* buff,
|
||||
uint16_t length )
|
||||
{
|
||||
if(phost->RequestState == CMD_SEND)
|
||||
{
|
||||
phost->Control.setup.b.bmRequestType = USB_D2H | req_type;
|
||||
phost->Control.setup.b.bRequest = USB_REQ_GET_DESCRIPTOR;
|
||||
phost->Control.setup.b.wValue.w = type_idx;
|
||||
phost->Control.setup.b.wIndex.w = value;
|
||||
phost->Control.setup.b.wLength.w = length;
|
||||
}
|
||||
return USBH_CtlReq(phost, buff , length );
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief USBH_SetAddress
|
||||
* This command sets the address to the connected device
|
||||
* @param phost: Host Handle
|
||||
* @param DeviceAddress: Device address to assign
|
||||
* @retval USBH Status
|
||||
*/
|
||||
USBH_StatusTypeDef USBH_SetAddress(USBH_HandleTypeDef *phost,
|
||||
uint8_t DeviceAddress)
|
||||
{
|
||||
if(phost->RequestState == CMD_SEND)
|
||||
{
|
||||
phost->Control.setup.b.bmRequestType = USB_H2D | USB_REQ_RECIPIENT_DEVICE | \
|
||||
USB_REQ_TYPE_STANDARD;
|
||||
|
||||
phost->Control.setup.b.bRequest = USB_REQ_SET_ADDRESS;
|
||||
|
||||
phost->Control.setup.b.wValue.w = (uint16_t)DeviceAddress;
|
||||
phost->Control.setup.b.wIndex.w = 0;
|
||||
phost->Control.setup.b.wLength.w = 0;
|
||||
}
|
||||
return USBH_CtlReq(phost, 0 , 0 );
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief USBH_SetCfg
|
||||
* The command sets the configuration value to the connected device
|
||||
* @param phost: Host Handle
|
||||
* @param cfg_idx: Configuration value
|
||||
* @retval USBH Status
|
||||
*/
|
||||
USBH_StatusTypeDef USBH_SetCfg(USBH_HandleTypeDef *phost,
|
||||
uint16_t cfg_idx)
|
||||
{
|
||||
if(phost->RequestState == CMD_SEND)
|
||||
{
|
||||
phost->Control.setup.b.bmRequestType = USB_H2D | USB_REQ_RECIPIENT_DEVICE |\
|
||||
USB_REQ_TYPE_STANDARD;
|
||||
phost->Control.setup.b.bRequest = USB_REQ_SET_CONFIGURATION;
|
||||
phost->Control.setup.b.wValue.w = cfg_idx;
|
||||
phost->Control.setup.b.wIndex.w = 0;
|
||||
phost->Control.setup.b.wLength.w = 0;
|
||||
}
|
||||
|
||||
return USBH_CtlReq(phost, 0 , 0 );
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief USBH_SetInterface
|
||||
* The command sets the Interface value to the connected device
|
||||
* @param phost: Host Handle
|
||||
* @param altSetting: Interface value
|
||||
* @retval USBH Status
|
||||
*/
|
||||
USBH_StatusTypeDef USBH_SetInterface(USBH_HandleTypeDef *phost,
|
||||
uint8_t ep_num, uint8_t altSetting)
|
||||
{
|
||||
|
||||
if(phost->RequestState == CMD_SEND)
|
||||
{
|
||||
phost->Control.setup.b.bmRequestType = USB_H2D | USB_REQ_RECIPIENT_INTERFACE | \
|
||||
USB_REQ_TYPE_STANDARD;
|
||||
|
||||
phost->Control.setup.b.bRequest = USB_REQ_SET_INTERFACE;
|
||||
phost->Control.setup.b.wValue.w = altSetting;
|
||||
phost->Control.setup.b.wIndex.w = ep_num;
|
||||
phost->Control.setup.b.wLength.w = 0;
|
||||
}
|
||||
return USBH_CtlReq(phost, 0 , 0 );
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief USBH_ClrFeature
|
||||
* This request is used to clear or disable a specific feature.
|
||||
* @param phost: Host Handle
|
||||
* @param ep_num: endpoint number
|
||||
* @param hc_num: Host channel number
|
||||
* @retval USBH Status
|
||||
*/
|
||||
USBH_StatusTypeDef USBH_ClrFeature(USBH_HandleTypeDef *phost,
|
||||
uint8_t ep_num)
|
||||
{
|
||||
if(phost->RequestState == CMD_SEND)
|
||||
{
|
||||
phost->Control.setup.b.bmRequestType = USB_H2D |
|
||||
USB_REQ_RECIPIENT_ENDPOINT |
|
||||
USB_REQ_TYPE_STANDARD;
|
||||
|
||||
phost->Control.setup.b.bRequest = USB_REQ_CLEAR_FEATURE;
|
||||
phost->Control.setup.b.wValue.w = FEATURE_SELECTOR_ENDPOINT;
|
||||
phost->Control.setup.b.wIndex.w = ep_num;
|
||||
phost->Control.setup.b.wLength.w = 0;
|
||||
}
|
||||
return USBH_CtlReq(phost, 0 , 0 );
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief USBH_ParseDevDesc
|
||||
* This function Parses the device descriptor
|
||||
* @param dev_desc: device_descriptor destination address
|
||||
* @param buf: Buffer where the source descriptor is available
|
||||
* @param length: Length of the descriptor
|
||||
* @retval None
|
||||
*/
|
||||
static void USBH_ParseDevDesc (USBH_DevDescTypeDef* dev_desc,
|
||||
uint8_t *buf,
|
||||
uint16_t length)
|
||||
{
|
||||
dev_desc->bLength = *(uint8_t *) (buf + 0);
|
||||
dev_desc->bDescriptorType = *(uint8_t *) (buf + 1);
|
||||
dev_desc->bcdUSB = LE16 (buf + 2);
|
||||
dev_desc->bDeviceClass = *(uint8_t *) (buf + 4);
|
||||
dev_desc->bDeviceSubClass = *(uint8_t *) (buf + 5);
|
||||
dev_desc->bDeviceProtocol = *(uint8_t *) (buf + 6);
|
||||
dev_desc->bMaxPacketSize = *(uint8_t *) (buf + 7);
|
||||
|
||||
if (length > 8)
|
||||
{ /* For 1st time after device connection, Host may issue only 8 bytes for
|
||||
Device Descriptor Length */
|
||||
dev_desc->idVendor = LE16 (buf + 8);
|
||||
dev_desc->idProduct = LE16 (buf + 10);
|
||||
dev_desc->bcdDevice = LE16 (buf + 12);
|
||||
dev_desc->iManufacturer = *(uint8_t *) (buf + 14);
|
||||
dev_desc->iProduct = *(uint8_t *) (buf + 15);
|
||||
dev_desc->iSerialNumber = *(uint8_t *) (buf + 16);
|
||||
dev_desc->bNumConfigurations = *(uint8_t *) (buf + 17);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief USBH_ParseCfgDesc
|
||||
* This function Parses the configuration descriptor
|
||||
* @param cfg_desc: Configuration Descriptor address
|
||||
* @param buf: Buffer where the source descriptor is available
|
||||
* @param length: Length of the descriptor
|
||||
* @retval None
|
||||
*/
|
||||
static void USBH_ParseCfgDesc (USBH_CfgDescTypeDef* cfg_desc,
|
||||
uint8_t *buf,
|
||||
uint16_t length)
|
||||
{
|
||||
USBH_InterfaceDescTypeDef *pif ;
|
||||
USBH_EpDescTypeDef *pep;
|
||||
USBH_DescHeader_t *pdesc = (USBH_DescHeader_t *)buf;
|
||||
uint16_t ptr;
|
||||
int8_t if_ix = 0;
|
||||
int8_t ep_ix = 0;
|
||||
|
||||
pdesc = (USBH_DescHeader_t *)buf;
|
||||
|
||||
/* Parse configuration descriptor */
|
||||
cfg_desc->bLength = *(uint8_t *) (buf + 0);
|
||||
cfg_desc->bDescriptorType = *(uint8_t *) (buf + 1);
|
||||
cfg_desc->wTotalLength = LE16 (buf + 2);
|
||||
cfg_desc->bNumInterfaces = *(uint8_t *) (buf + 4);
|
||||
cfg_desc->bConfigurationValue = *(uint8_t *) (buf + 5);
|
||||
cfg_desc->iConfiguration = *(uint8_t *) (buf + 6);
|
||||
cfg_desc->bmAttributes = *(uint8_t *) (buf + 7);
|
||||
cfg_desc->bMaxPower = *(uint8_t *) (buf + 8);
|
||||
|
||||
|
||||
if (length > USB_CONFIGURATION_DESC_SIZE)
|
||||
{
|
||||
ptr = USB_LEN_CFG_DESC;
|
||||
pif = (USBH_InterfaceDescTypeDef *)0;
|
||||
|
||||
//***************
|
||||
//Todo: This does not check for malformed descriptors. Needs hardening!
|
||||
//***************
|
||||
while ((if_ix < USBH_MAX_NUM_INTERFACES ) && (ptr < cfg_desc->wTotalLength))
|
||||
{
|
||||
pdesc = USBH_GetNextDesc((uint8_t *)pdesc, &ptr);
|
||||
if (pdesc->bDescriptorType == USB_DESC_TYPE_INTERFACE)
|
||||
{
|
||||
pif = &cfg_desc->Itf_Desc[if_ix];
|
||||
USBH_ParseInterfaceDesc (pif, (uint8_t *)pdesc);
|
||||
|
||||
ep_ix = 0;
|
||||
pep = (USBH_EpDescTypeDef *)0;
|
||||
while ((ep_ix < pif->bNumEndpoints) && (ptr < cfg_desc->wTotalLength))
|
||||
{
|
||||
pdesc = USBH_GetNextDesc((uint8_t*) pdesc, &ptr);
|
||||
if (pdesc->bDescriptorType == USB_DESC_TYPE_ENDPOINT)
|
||||
{
|
||||
pep = &cfg_desc->Itf_Desc[if_ix].Ep_Desc[ep_ix];
|
||||
USBH_ParseEPDesc (pep, (uint8_t *)pdesc);
|
||||
ep_ix++;
|
||||
}
|
||||
}
|
||||
if_ix++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @brief USBH_ParseInterfaceDesc
|
||||
* This function Parses the interface descriptor
|
||||
* @param if_descriptor : Interface descriptor destination
|
||||
* @param buf: Buffer where the descriptor data is available
|
||||
* @retval None
|
||||
*/
|
||||
static void USBH_ParseInterfaceDesc (USBH_InterfaceDescTypeDef *if_descriptor,
|
||||
uint8_t *buf)
|
||||
{
|
||||
if_descriptor->bLength = *(uint8_t *) (buf + 0);
|
||||
if_descriptor->bDescriptorType = *(uint8_t *) (buf + 1);
|
||||
if_descriptor->bInterfaceNumber = *(uint8_t *) (buf + 2);
|
||||
if_descriptor->bAlternateSetting = *(uint8_t *) (buf + 3);
|
||||
if_descriptor->bNumEndpoints = *(uint8_t *) (buf + 4);
|
||||
if_descriptor->bInterfaceClass = *(uint8_t *) (buf + 5);
|
||||
if_descriptor->bInterfaceSubClass = *(uint8_t *) (buf + 6);
|
||||
if_descriptor->bInterfaceProtocol = *(uint8_t *) (buf + 7);
|
||||
if_descriptor->iInterface = *(uint8_t *) (buf + 8);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief USBH_ParseEPDesc
|
||||
* This function Parses the endpoint descriptor
|
||||
* @param ep_descriptor: Endpoint descriptor destination address
|
||||
* @param buf: Buffer where the parsed descriptor stored
|
||||
* @retval None
|
||||
*/
|
||||
static void USBH_ParseEPDesc (USBH_EpDescTypeDef *ep_descriptor,
|
||||
uint8_t *buf)
|
||||
{
|
||||
|
||||
ep_descriptor->bLength = *(uint8_t *) (buf + 0);
|
||||
ep_descriptor->bDescriptorType = *(uint8_t *) (buf + 1);
|
||||
ep_descriptor->bEndpointAddress = *(uint8_t *) (buf + 2);
|
||||
ep_descriptor->bmAttributes = *(uint8_t *) (buf + 3);
|
||||
ep_descriptor->wMaxPacketSize = LE16 (buf + 4);
|
||||
ep_descriptor->bInterval = *(uint8_t *) (buf + 6);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief USBH_ParseStringDesc
|
||||
* This function Parses the string descriptor
|
||||
* @param psrc: Source pointer containing the descriptor data
|
||||
* @param pdest: Destination address pointer
|
||||
* @param length: Length of the descriptor
|
||||
* @retval None
|
||||
*/
|
||||
static void USBH_ParseStringDesc (uint8_t* psrc,
|
||||
uint8_t* pdest,
|
||||
uint16_t length)
|
||||
{
|
||||
uint16_t strlength;
|
||||
uint16_t idx;
|
||||
|
||||
/* The UNICODE string descriptor is not NULL-terminated. The string length is
|
||||
computed by substracting two from the value of the first byte of the descriptor.
|
||||
*/
|
||||
|
||||
/* Check which is lower size, the Size of string or the length of bytes read
|
||||
from the device */
|
||||
|
||||
if ( psrc[1] == USB_DESC_TYPE_STRING)
|
||||
{ /* Make sure the Descriptor is String Type */
|
||||
|
||||
/* psrc[0] contains Size of Descriptor, subtract 2 to get the length of string */
|
||||
strlength = ( ( (psrc[0]-2) <= length) ? (psrc[0]-2) :length);
|
||||
psrc += 2; /* Adjust the offset ignoring the String Len and Descriptor type */
|
||||
|
||||
for (idx = 0; idx < strlength; idx+=2 )
|
||||
{/* Copy Only the string and ignore the UNICODE ID, hence add the src */
|
||||
*pdest = psrc[idx];
|
||||
pdest++;
|
||||
}
|
||||
*pdest = 0; /* mark end of string */
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief USBH_GetNextDesc
|
||||
* This function return the next descriptor header
|
||||
* @param buf: Buffer where the cfg descriptor is available
|
||||
* @param ptr: data pointer inside the cfg descriptor
|
||||
* @retval next header
|
||||
*/
|
||||
USBH_DescHeader_t *USBH_GetNextDesc (uint8_t *pbuf, uint16_t *ptr)
|
||||
{
|
||||
USBH_DescHeader_t *pnext;
|
||||
|
||||
*ptr += ((USBH_DescHeader_t *)pbuf)->bLength;
|
||||
pnext = (USBH_DescHeader_t *)((uint8_t *)pbuf + \
|
||||
((USBH_DescHeader_t *)pbuf)->bLength);
|
||||
|
||||
return(pnext);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief USBH_CtlReq
|
||||
* USBH_CtlReq sends a control request and provide the status after
|
||||
* completion of the request
|
||||
* @param phost: Host Handle
|
||||
* @param req: Setup Request Structure
|
||||
* @param buff: data buffer address to store the response
|
||||
* @param length: length of the response
|
||||
* @retval USBH Status
|
||||
*/
|
||||
USBH_StatusTypeDef USBH_CtlReq (USBH_HandleTypeDef *phost,
|
||||
uint8_t *buff,
|
||||
uint16_t length)
|
||||
{
|
||||
USBH_StatusTypeDef status;
|
||||
status = USBH_BUSY;
|
||||
|
||||
switch (phost->RequestState)
|
||||
{
|
||||
case CMD_SEND:
|
||||
/* Start a SETUP transfer */
|
||||
phost->Control.buff = buff;
|
||||
phost->Control.length = length;
|
||||
phost->Control.state = CTRL_SETUP;
|
||||
phost->RequestState = CMD_WAIT;
|
||||
status = USBH_BUSY;
|
||||
#if (USBH_USE_OS == 1)
|
||||
osMessagePut ( phost->os_event, USBH_CONTROL_EVENT, 0);
|
||||
#endif
|
||||
break;
|
||||
|
||||
case CMD_WAIT:
|
||||
status = USBH_HandleControl(phost);
|
||||
if (status != USBH_BUSY)
|
||||
{
|
||||
phost->RequestState = CMD_SEND;
|
||||
phost->Control.state = CTRL_IDLE;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief USBH_HandleControl
|
||||
* Handles the USB control transfer state machine
|
||||
* @param phost: Host Handle
|
||||
* @retval USBH Status
|
||||
*/
|
||||
static USBH_StatusTypeDef USBH_HandleControl (USBH_HandleTypeDef *phost)
|
||||
{
|
||||
uint8_t direction;
|
||||
USBH_StatusTypeDef status = USBH_BUSY;
|
||||
USBH_URBStateTypeDef URB_Status = USBH_URB_IDLE;
|
||||
|
||||
switch (phost->Control.state)
|
||||
{
|
||||
case CTRL_SETUP:
|
||||
/* send a SETUP packet */
|
||||
phost->Control.timer = phost->Timer;
|
||||
USBH_CtlSendSetup(phost,
|
||||
(uint8_t *)phost->Control.setup.d8 ,
|
||||
phost->Control.pipe_out);
|
||||
phost->Control.state = CTRL_SETUP_WAIT;
|
||||
break;
|
||||
|
||||
case CTRL_SETUP_WAIT:
|
||||
URB_Status = USBH_LL_GetURBState(phost, phost->Control.pipe_out);
|
||||
/* case SETUP packet sent successfully */
|
||||
if(URB_Status == USBH_URB_DONE)
|
||||
{
|
||||
direction = (phost->Control.setup.b.bmRequestType & USB_REQ_DIR_MASK);
|
||||
|
||||
/* check if there is a data stage */
|
||||
if (phost->Control.setup.b.wLength.w != 0 )
|
||||
{
|
||||
if (direction == USB_D2H)
|
||||
{
|
||||
/* Data Direction is IN */
|
||||
phost->Control.state = CTRL_DATA_IN;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Data Direction is OUT */
|
||||
phost->Control.state = CTRL_DATA_OUT;
|
||||
}
|
||||
}
|
||||
/* No DATA stage */
|
||||
else
|
||||
{
|
||||
/* If there is No Data Transfer Stage */
|
||||
if (direction == USB_D2H)
|
||||
{
|
||||
/* Data Direction is IN */
|
||||
phost->Control.state = CTRL_STATUS_OUT;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Data Direction is OUT */
|
||||
phost->Control.state = CTRL_STATUS_IN;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if(URB_Status == USBH_URB_ERROR)
|
||||
{
|
||||
phost->Control.state = CTRL_ERROR;
|
||||
}
|
||||
else if (URB_Status == USBH_URB_NOTREADY)
|
||||
{
|
||||
//Some mice cause a transaction error interrupt (HCINT_TXERR) at this point.
|
||||
//Other mice just NAK our transaction.
|
||||
//Either way we need to retry, but keep our original timeout so we don't wait forever.
|
||||
USBH_CtlSendSetup(phost,
|
||||
(uint8_t *)phost->Control.setup.d8 ,
|
||||
phost->Control.pipe_out);
|
||||
}
|
||||
|
||||
if ((int32_t)(phost->Timer - phost->Control.timer) >= USBH_CTRL_TRANSACTION_TIMEOUT_MS)
|
||||
{
|
||||
phost->Control.state = CTRL_ERROR;
|
||||
}
|
||||
break;
|
||||
|
||||
case CTRL_DATA_IN:
|
||||
/* Issue an IN token */
|
||||
phost->Control.timer = phost->Timer;
|
||||
USBH_CtlReceiveData(phost,
|
||||
phost->Control.buff,
|
||||
phost->Control.length,
|
||||
phost->Control.pipe_in);
|
||||
|
||||
phost->Control.state = CTRL_DATA_IN_WAIT;
|
||||
break;
|
||||
|
||||
case CTRL_DATA_IN_WAIT:
|
||||
URB_Status = USBH_LL_GetURBState(phost , phost->Control.pipe_in);
|
||||
|
||||
/* check is DATA packet transferred successfully */
|
||||
if (URB_Status == USBH_URB_DONE)
|
||||
{
|
||||
phost->Control.state = CTRL_STATUS_OUT;
|
||||
}
|
||||
|
||||
/* manage error cases*/
|
||||
if (URB_Status == USBH_URB_STALL)
|
||||
{
|
||||
//Command not supported, report to callee
|
||||
status = USBH_NOT_SUPPORTED;
|
||||
}
|
||||
else if (URB_Status == USBH_URB_ERROR)
|
||||
{
|
||||
/* Device error */
|
||||
phost->Control.state = CTRL_ERROR;
|
||||
}
|
||||
|
||||
if ((int32_t)(phost->Timer - phost->Control.timer) >= USBH_CTRL_TRANSACTION_TIMEOUT_MS)
|
||||
{
|
||||
phost->Control.state = CTRL_ERROR;
|
||||
}
|
||||
break;
|
||||
|
||||
case CTRL_DATA_OUT:
|
||||
phost->Control.timer = phost->Timer;
|
||||
USBH_CtlSendData (phost,
|
||||
phost->Control.buff,
|
||||
phost->Control.length ,
|
||||
phost->Control.pipe_out,
|
||||
1);
|
||||
phost->Control.state = CTRL_DATA_OUT_WAIT;
|
||||
break;
|
||||
|
||||
case CTRL_DATA_OUT_WAIT:
|
||||
URB_Status = USBH_LL_GetURBState(phost, phost->Control.pipe_out);
|
||||
|
||||
if (URB_Status == USBH_URB_DONE)
|
||||
{ /* If the Setup Pkt is sent successful, then change the state */
|
||||
phost->Control.state = CTRL_STATUS_IN;
|
||||
}
|
||||
|
||||
/* handle error cases */
|
||||
else if (URB_Status == USBH_URB_STALL)
|
||||
{
|
||||
//Command not supported, report to callee
|
||||
status = USBH_NOT_SUPPORTED;
|
||||
}
|
||||
else if (URB_Status == USBH_URB_NOTREADY)
|
||||
{
|
||||
/* Nack received from device */
|
||||
phost->Control.state = CTRL_DATA_OUT;
|
||||
}
|
||||
else if (URB_Status == USBH_URB_ERROR)
|
||||
{
|
||||
/* device error */
|
||||
phost->Control.state = CTRL_ERROR;
|
||||
status = USBH_FAIL;
|
||||
}
|
||||
|
||||
if ((int32_t)(phost->Timer - phost->Control.timer) >= USBH_CTRL_TRANSACTION_TIMEOUT_MS)
|
||||
{
|
||||
phost->Control.state = CTRL_ERROR;
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
case CTRL_STATUS_IN:
|
||||
/* Send 0 bytes out packet */
|
||||
phost->Control.timer = phost->Timer;
|
||||
USBH_CtlReceiveData (phost,
|
||||
0,
|
||||
0,
|
||||
phost->Control.pipe_in);
|
||||
phost->Control.state = CTRL_STATUS_IN_WAIT;
|
||||
break;
|
||||
|
||||
case CTRL_STATUS_IN_WAIT:
|
||||
URB_Status = USBH_LL_GetURBState(phost , phost->Control.pipe_in);
|
||||
|
||||
if ( URB_Status == USBH_URB_DONE)
|
||||
{ /* Control transfers completed, Exit the State Machine */
|
||||
phost->Control.state = CTRL_COMPLETE;
|
||||
status = USBH_OK;
|
||||
}
|
||||
|
||||
else if (URB_Status == USBH_URB_ERROR)
|
||||
{
|
||||
phost->Control.state = CTRL_ERROR;
|
||||
}
|
||||
else if(URB_Status == USBH_URB_STALL)
|
||||
{
|
||||
//Command not supported, report to callee
|
||||
status = USBH_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
if ((int32_t)(phost->Timer - phost->Control.timer) >= USBH_CTRL_TRANSACTION_TIMEOUT_MS)
|
||||
{
|
||||
phost->Control.state = CTRL_ERROR;
|
||||
}
|
||||
break;
|
||||
|
||||
case CTRL_STATUS_OUT:
|
||||
phost->Control.timer = phost->Timer;
|
||||
USBH_CtlSendData (phost,
|
||||
0,
|
||||
0,
|
||||
phost->Control.pipe_out,
|
||||
1);
|
||||
phost->Control.state = CTRL_STATUS_OUT_WAIT;
|
||||
break;
|
||||
|
||||
case CTRL_STATUS_OUT_WAIT:
|
||||
URB_Status = USBH_LL_GetURBState(phost , phost->Control.pipe_out);
|
||||
if (URB_Status == USBH_URB_DONE)
|
||||
{
|
||||
status = USBH_OK;
|
||||
phost->Control.state = CTRL_COMPLETE;
|
||||
}
|
||||
else if (URB_Status == USBH_URB_NOTREADY)
|
||||
{
|
||||
phost->Control.state = CTRL_STATUS_OUT;
|
||||
}
|
||||
else if (URB_Status == USBH_URB_ERROR)
|
||||
{
|
||||
phost->Control.state = CTRL_ERROR;
|
||||
}
|
||||
|
||||
if ((int32_t)(phost->Timer - phost->Control.timer) >= USBH_CTRL_TRANSACTION_TIMEOUT_MS)
|
||||
{
|
||||
phost->Control.state = CTRL_ERROR;
|
||||
}
|
||||
break;
|
||||
|
||||
case CTRL_ERROR:
|
||||
/*
|
||||
After a halt condition is encountered or an error is detected by the
|
||||
host, a control endpoint is allowed to recover by accepting the next Setup
|
||||
PID; i.e., recovery actions via some other pipe are not required for control
|
||||
endpoints. For the Default Control Pipe, a device reset will ultimately be
|
||||
required to clear the halt or error condition if the next Setup PID is not
|
||||
accepted.
|
||||
*/
|
||||
if (++ phost->Control.errorcount <= USBH_MAX_ERROR_COUNT)
|
||||
{
|
||||
/* try to recover control */
|
||||
// USBH_LL_Stop(phost);
|
||||
|
||||
/* Do the transmission again, starting from SETUP Packet */
|
||||
phost->Control.state = CTRL_SETUP;
|
||||
phost->RequestState = CMD_SEND;
|
||||
}
|
||||
else
|
||||
{
|
||||
phost->pUser(phost, HOST_USER_UNRECOVERED_ERROR);
|
||||
phost->Control.errorcount = 0;
|
||||
USBH_ErrLog("Control error");
|
||||
status = USBH_FAIL;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
|
||||
|
||||
|
||||
|
||||
|
@ -0,0 +1,358 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file usbh_ioreq.c
|
||||
* @author MCD Application Team
|
||||
* @version V3.2.1
|
||||
* @date 26-June-2015
|
||||
* @brief This file handles the issuing of the USB transactions
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* <h2><center>© COPYRIGHT 2015 STMicroelectronics</center></h2>
|
||||
*
|
||||
* Licensed under MCD-ST Liberty SW License Agreement V2, (the "License");
|
||||
* You may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at:
|
||||
*
|
||||
* http://www.st.com/software_license_agreement_liberty_v2
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
|
||||
#include "usbh_ioreq.h"
|
||||
|
||||
/** @addtogroup USBH_LIB
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @addtogroup USBH_LIB_CORE
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @defgroup USBH_IOREQ
|
||||
* @brief This file handles the standard protocol processing (USB v2.0)
|
||||
* @{
|
||||
*/
|
||||
|
||||
|
||||
/** @defgroup USBH_IOREQ_Private_Defines
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
|
||||
/** @defgroup USBH_IOREQ_Private_TypesDefinitions
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
|
||||
|
||||
/** @defgroup USBH_IOREQ_Private_Macros
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
|
||||
/** @defgroup USBH_IOREQ_Private_Variables
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
/** @defgroup USBH_IOREQ_Private_FunctionPrototypes
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
|
||||
/** @defgroup USBH_IOREQ_Private_Functions
|
||||
* @{
|
||||
*/
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @brief USBH_CtlSendSetup
|
||||
* Sends the Setup Packet to the Device
|
||||
* @param phost: Host Handle
|
||||
* @param buff: Buffer pointer from which the Data will be send to Device
|
||||
* @param pipe_num: Pipe Number
|
||||
* @retval USBH Status
|
||||
*/
|
||||
USBH_StatusTypeDef USBH_CtlSendSetup (USBH_HandleTypeDef *phost,
|
||||
uint8_t *buff,
|
||||
uint8_t pipe_num)
|
||||
{
|
||||
|
||||
USBH_LL_SubmitURB (phost, /* Driver handle */
|
||||
pipe_num, /* Pipe index */
|
||||
0, /* Direction : OUT */
|
||||
USBH_EP_CONTROL, /* EP type */
|
||||
USBH_PID_SETUP, /* Type setup */
|
||||
buff, /* data buffer */
|
||||
USBH_SETUP_PKT_SIZE, /* data length */
|
||||
0);
|
||||
return USBH_OK;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief USBH_CtlSendData
|
||||
* Sends a data Packet to the Device
|
||||
* @param phost: Host Handle
|
||||
* @param buff: Buffer pointer from which the Data will be sent to Device
|
||||
* @param length: Length of the data to be sent
|
||||
* @param pipe_num: Pipe Number
|
||||
* @retval USBH Status
|
||||
*/
|
||||
USBH_StatusTypeDef USBH_CtlSendData (USBH_HandleTypeDef *phost,
|
||||
uint8_t *buff,
|
||||
uint16_t length,
|
||||
uint8_t pipe_num,
|
||||
uint8_t do_ping )
|
||||
{
|
||||
if(phost->device.speed != USBH_SPEED_HIGH)
|
||||
{
|
||||
do_ping = 0;
|
||||
}
|
||||
|
||||
USBH_LL_SubmitURB (phost, /* Driver handle */
|
||||
pipe_num, /* Pipe index */
|
||||
0, /* Direction : OUT */
|
||||
USBH_EP_CONTROL, /* EP type */
|
||||
USBH_PID_DATA, /* Type Data */
|
||||
buff, /* data buffer */
|
||||
length, /* data length */
|
||||
do_ping); /* do ping (HS Only)*/
|
||||
|
||||
return USBH_OK;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief USBH_CtlReceiveData
|
||||
* Receives the Device Response to the Setup Packet
|
||||
* @param phost: Host Handle
|
||||
* @param buff: Buffer pointer in which the response needs to be copied
|
||||
* @param length: Length of the data to be received
|
||||
* @param pipe_num: Pipe Number
|
||||
* @retval USBH Status.
|
||||
*/
|
||||
USBH_StatusTypeDef USBH_CtlReceiveData(USBH_HandleTypeDef *phost,
|
||||
uint8_t* buff,
|
||||
uint16_t length,
|
||||
uint8_t pipe_num)
|
||||
{
|
||||
USBH_LL_SubmitURB (phost, /* Driver handle */
|
||||
pipe_num, /* Pipe index */
|
||||
1, /* Direction : IN */
|
||||
USBH_EP_CONTROL, /* EP type */
|
||||
USBH_PID_DATA, /* Type Data */
|
||||
buff, /* data buffer */
|
||||
length, /* data length */
|
||||
0);
|
||||
return USBH_OK;
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief USBH_BulkSendData
|
||||
* Sends the Bulk Packet to the device
|
||||
* @param phost: Host Handle
|
||||
* @param buff: Buffer pointer from which the Data will be sent to Device
|
||||
* @param length: Length of the data to be sent
|
||||
* @param pipe_num: Pipe Number
|
||||
* @retval USBH Status
|
||||
*/
|
||||
USBH_StatusTypeDef USBH_BulkSendData (USBH_HandleTypeDef *phost,
|
||||
uint8_t *buff,
|
||||
uint16_t length,
|
||||
uint8_t pipe_num,
|
||||
uint8_t do_ping )
|
||||
{
|
||||
if(phost->device.speed != USBH_SPEED_HIGH)
|
||||
{
|
||||
do_ping = 0;
|
||||
}
|
||||
|
||||
USBH_LL_SubmitURB (phost, /* Driver handle */
|
||||
pipe_num, /* Pipe index */
|
||||
0, /* Direction : IN */
|
||||
USBH_EP_BULK, /* EP type */
|
||||
USBH_PID_DATA, /* Type Data */
|
||||
buff, /* data buffer */
|
||||
length, /* data length */
|
||||
do_ping); /* do ping (HS Only)*/
|
||||
return USBH_OK;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief USBH_BulkReceiveData
|
||||
* Receives IN bulk packet from device
|
||||
* @param phost: Host Handle
|
||||
* @param buff: Buffer pointer in which the received data packet to be copied
|
||||
* @param length: Length of the data to be received
|
||||
* @param pipe_num: Pipe Number
|
||||
* @retval USBH Status.
|
||||
*/
|
||||
USBH_StatusTypeDef USBH_BulkReceiveData(USBH_HandleTypeDef *phost,
|
||||
uint8_t *buff,
|
||||
uint16_t length,
|
||||
uint8_t pipe_num)
|
||||
{
|
||||
USBH_LL_SubmitURB (phost, /* Driver handle */
|
||||
pipe_num, /* Pipe index */
|
||||
1, /* Direction : IN */
|
||||
USBH_EP_BULK, /* EP type */
|
||||
USBH_PID_DATA, /* Type Data */
|
||||
buff, /* data buffer */
|
||||
length, /* data length */
|
||||
0);
|
||||
return USBH_OK;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief USBH_InterruptReceiveData
|
||||
* Receives the Device Response to the Interrupt IN token
|
||||
* @param phost: Host Handle
|
||||
* @param buff: Buffer pointer in which the response needs to be copied
|
||||
* @param length: Length of the data to be received
|
||||
* @param pipe_num: Pipe Number
|
||||
* @retval USBH Status.
|
||||
*/
|
||||
USBH_StatusTypeDef USBH_InterruptReceiveData(USBH_HandleTypeDef *phost,
|
||||
uint8_t *buff,
|
||||
uint8_t length,
|
||||
uint8_t pipe_num)
|
||||
{
|
||||
USBH_LL_SubmitURB (phost, /* Driver handle */
|
||||
pipe_num, /* Pipe index */
|
||||
1, /* Direction : IN */
|
||||
USBH_EP_INTERRUPT, /* EP type */
|
||||
USBH_PID_DATA, /* Type Data */
|
||||
buff, /* data buffer */
|
||||
length, /* data length */
|
||||
0);
|
||||
|
||||
return USBH_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief USBH_InterruptSendData
|
||||
* Sends the data on Interrupt OUT Endpoint
|
||||
* @param phost: Host Handle
|
||||
* @param buff: Buffer pointer from where the data needs to be copied
|
||||
* @param length: Length of the data to be sent
|
||||
* @param pipe_num: Pipe Number
|
||||
* @retval USBH Status.
|
||||
*/
|
||||
USBH_StatusTypeDef USBH_InterruptSendData(USBH_HandleTypeDef *phost,
|
||||
uint8_t *buff,
|
||||
uint8_t length,
|
||||
uint8_t pipe_num)
|
||||
{
|
||||
USBH_LL_SubmitURB (phost, /* Driver handle */
|
||||
pipe_num, /* Pipe index */
|
||||
0, /* Direction : OUT */
|
||||
USBH_EP_INTERRUPT, /* EP type */
|
||||
USBH_PID_DATA, /* Type Data */
|
||||
buff, /* data buffer */
|
||||
length, /* data length */
|
||||
0);
|
||||
|
||||
return USBH_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief USBH_IsocReceiveData
|
||||
* Receives the Device Response to the Isochronous IN token
|
||||
* @param phost: Host Handle
|
||||
* @param buff: Buffer pointer in which the response needs to be copied
|
||||
* @param length: Length of the data to be received
|
||||
* @param pipe_num: Pipe Number
|
||||
* @retval USBH Status.
|
||||
*/
|
||||
USBH_StatusTypeDef USBH_IsocReceiveData(USBH_HandleTypeDef *phost,
|
||||
uint8_t *buff,
|
||||
uint32_t length,
|
||||
uint8_t pipe_num)
|
||||
{
|
||||
USBH_LL_SubmitURB (phost, /* Driver handle */
|
||||
pipe_num, /* Pipe index */
|
||||
1, /* Direction : IN */
|
||||
USBH_EP_ISO, /* EP type */
|
||||
USBH_PID_DATA, /* Type Data */
|
||||
buff, /* data buffer */
|
||||
length, /* data length */
|
||||
0);
|
||||
|
||||
|
||||
return USBH_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief USBH_IsocSendData
|
||||
* Sends the data on Isochronous OUT Endpoint
|
||||
* @param phost: Host Handle
|
||||
* @param buff: Buffer pointer from where the data needs to be copied
|
||||
* @param length: Length of the data to be sent
|
||||
* @param pipe_num: Pipe Number
|
||||
* @retval USBH Status.
|
||||
*/
|
||||
USBH_StatusTypeDef USBH_IsocSendData(USBH_HandleTypeDef *phost,
|
||||
uint8_t *buff,
|
||||
uint32_t length,
|
||||
uint8_t pipe_num)
|
||||
{
|
||||
USBH_LL_SubmitURB (phost, /* Driver handle */
|
||||
pipe_num, /* Pipe index */
|
||||
0, /* Direction : OUT */
|
||||
USBH_EP_ISO, /* EP type */
|
||||
USBH_PID_DATA, /* Type Data */
|
||||
buff, /* data buffer */
|
||||
length, /* data length */
|
||||
0);
|
||||
|
||||
return USBH_OK;
|
||||
}
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
|
||||
|
||||
|
||||
|
@ -0,0 +1,205 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file usbh_pipes.c
|
||||
* @author MCD Application Team
|
||||
* @version V3.2.1
|
||||
* @date 26-June-2015
|
||||
* @brief This file implements functions for opening and closing Pipes
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* <h2><center>© COPYRIGHT 2015 STMicroelectronics</center></h2>
|
||||
*
|
||||
* Licensed under MCD-ST Liberty SW License Agreement V2, (the "License");
|
||||
* You may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at:
|
||||
*
|
||||
* http://www.st.com/software_license_agreement_liberty_v2
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include "usbh_pipes.h"
|
||||
|
||||
/** @addtogroup USBH_LIB
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @addtogroup USBH_LIB_CORE
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @defgroup USBH_PIPES
|
||||
* @brief This file includes opening and closing Pipes
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @defgroup USBH_PIPES_Private_Defines
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @defgroup USBH_PIPES_Private_TypesDefinitions
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
|
||||
/** @defgroup USBH_PIPES_Private_Macros
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
|
||||
/** @defgroup USBH_PIPES_Private_Variables
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
|
||||
/** @defgroup USBH_PIPES_Private_Functions
|
||||
* @{
|
||||
*/
|
||||
static uint16_t USBH_GetFreePipe (USBH_HandleTypeDef *phost);
|
||||
|
||||
|
||||
/**
|
||||
* @brief USBH_Open_Pipe
|
||||
* Open a pipe
|
||||
* @param phost: Host Handle
|
||||
* @param pipe_num: Pipe Number
|
||||
* @param dev_address: USB Device address allocated to attached device
|
||||
* @param speed : USB device speed (Full/Low)
|
||||
* @param ep_type: end point type (Bulk/int/ctl)
|
||||
* @param mps: max pkt size
|
||||
* @retval USBH Status
|
||||
*/
|
||||
USBH_StatusTypeDef USBH_OpenPipe (USBH_HandleTypeDef *phost,
|
||||
uint8_t pipe_num,
|
||||
uint8_t epnum,
|
||||
uint8_t dev_address,
|
||||
uint8_t speed,
|
||||
uint8_t ep_type,
|
||||
uint16_t mps)
|
||||
{
|
||||
|
||||
USBH_LL_OpenPipe(phost,
|
||||
pipe_num,
|
||||
epnum,
|
||||
dev_address,
|
||||
speed,
|
||||
ep_type,
|
||||
mps);
|
||||
|
||||
return USBH_OK;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief USBH_ClosePipe
|
||||
* Close a pipe
|
||||
* @param phost: Host Handle
|
||||
* @param pipe_num: Pipe Number
|
||||
* @retval USBH Status
|
||||
*/
|
||||
USBH_StatusTypeDef USBH_ClosePipe (USBH_HandleTypeDef *phost,
|
||||
uint8_t pipe_num)
|
||||
{
|
||||
|
||||
USBH_LL_ClosePipe(phost, pipe_num);
|
||||
|
||||
return USBH_OK;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief USBH_Alloc_Pipe
|
||||
* Allocate a new Pipe
|
||||
* @param phost: Host Handle
|
||||
* @param ep_addr: End point for which the Pipe to be allocated
|
||||
* @retval Pipe number
|
||||
*/
|
||||
uint8_t USBH_AllocPipe (USBH_HandleTypeDef *phost, uint8_t ep_addr)
|
||||
{
|
||||
uint16_t pipe;
|
||||
|
||||
pipe = USBH_GetFreePipe(phost);
|
||||
|
||||
if (pipe != 0xFFFF)
|
||||
{
|
||||
phost->Pipes[pipe] = 0x8000 | ep_addr;
|
||||
}
|
||||
return pipe;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief USBH_Free_Pipe
|
||||
* Free the USB Pipe
|
||||
* @param phost: Host Handle
|
||||
* @param idx: Pipe number to be freed
|
||||
* @retval USBH Status
|
||||
*/
|
||||
USBH_StatusTypeDef USBH_FreePipe (USBH_HandleTypeDef *phost, uint8_t idx)
|
||||
{
|
||||
if (idx < HOST_PIPE_COUNT)
|
||||
{
|
||||
phost->Pipes[idx] &= 0x7FFF;
|
||||
}
|
||||
return USBH_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief USBH_GetFreePipe
|
||||
* @param phost: Host Handle
|
||||
* Get a free Pipe number for allocation to a device endpoint
|
||||
* @retval idx: Free Pipe number
|
||||
*/
|
||||
static uint16_t USBH_GetFreePipe (USBH_HandleTypeDef *phost)
|
||||
{
|
||||
uint8_t idx = 0;
|
||||
|
||||
//We need to limit allocated pipes to the number actually provided by hardware!
|
||||
for (idx = 0 ; idx < ((HCD_HandleTypeDef*)phost->pData)->Init.Host_channels; idx++)
|
||||
{
|
||||
if ((phost->Pipes[idx] & 0x8000) == 0)
|
||||
{
|
||||
return idx;
|
||||
}
|
||||
}
|
||||
return 0xFFFF;
|
||||
}
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
|
||||
|
||||
|
@ -0,0 +1,451 @@
|
||||
/*
|
||||
* downstream_hid.c
|
||||
*
|
||||
* Created on: Apr 10, 2016
|
||||
* Author: Robert Fisk
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
|
||||
|
||||
#include "downstream_hid.h"
|
||||
#include "downstream_statemachine.h"
|
||||
#include "usbh_hid.h"
|
||||
#include "stm32f4xx_hal.h"
|
||||
#include "build_config.h"
|
||||
|
||||
|
||||
#if defined (CONFIG_KEYBOARD_ENABLED) || defined (CONFIG_MOUSE_ENABLED)
|
||||
|
||||
extern USBH_HandleTypeDef hUsbHostFS; //Hard-link ourselves to usb_host.c
|
||||
extern InterfaceCommandClassTypeDef ConfiguredDeviceClass; //Do a cheap hard-link to downstream_statemachine.c, rather than keep a duplicate here
|
||||
|
||||
|
||||
//Information required to extract the data we need from incoming device reports.
|
||||
uint8_t ReportButtonBitOffset;
|
||||
uint8_t ReportButtonBitLength;
|
||||
uint8_t ReportXBitOffset;
|
||||
uint8_t ReportXBitLength;
|
||||
uint8_t ReportYBitOffset;
|
||||
uint8_t ReportYBitLength;
|
||||
uint8_t ReportWheelBitOffset;
|
||||
uint8_t ReportWheelBitLength;
|
||||
|
||||
//Stuff used while parsing HID report
|
||||
uint8_t* ReportDataPointer;
|
||||
uint8_t ItemHeader;
|
||||
uint8_t ItemData;
|
||||
|
||||
|
||||
|
||||
static HAL_StatusTypeDef Downstream_HID_Mouse_ParseReportDescriptor(void);
|
||||
static HAL_StatusTypeDef Downstream_HID_GetNextReportItem(void);
|
||||
static void Downstream_HID_Mouse_ExtractDataFromReport(DownstreamPacketTypeDef* packetToSend);
|
||||
static void Downstream_HID_Keyboard_ExtractDataFromReport(DownstreamPacketTypeDef* packetToSend);
|
||||
static uint8_t Downstream_HID_Mouse_Extract8BitValue(HID_HandleTypeDef* hidHandle,
|
||||
uint8_t valueBitOffset,
|
||||
uint8_t valueBitLength);
|
||||
|
||||
|
||||
InterfaceCommandClassTypeDef Downstream_HID_ApproveConnectedDevice(void)
|
||||
{
|
||||
HID_HandleTypeDef* HID_Handle = (HID_HandleTypeDef*)hUsbHostFS.pActiveClass->pData;
|
||||
|
||||
#ifdef CONFIG_MOUSE_ENABLED
|
||||
if (HID_Handle->Protocol == HID_MOUSE_PROTOCOL)
|
||||
{
|
||||
if (Downstream_HID_Mouse_ParseReportDescriptor() == HAL_OK)
|
||||
{
|
||||
return COMMAND_CLASS_HID_MOUSE; //success!
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#ifdef CONFIG_KEYBOARD_ENABLED
|
||||
if (HID_Handle->Protocol == HID_KEYBRD_PROTOCOL)
|
||||
{
|
||||
return COMMAND_CLASS_HID_KEYBOARD; //success!
|
||||
}
|
||||
#endif
|
||||
|
||||
//else:
|
||||
return COMMAND_CLASS_INTERFACE; //fail
|
||||
}
|
||||
|
||||
|
||||
#ifdef CONFIG_MOUSE_ENABLED
|
||||
static HAL_StatusTypeDef Downstream_HID_Mouse_ParseReportDescriptor(void)
|
||||
{
|
||||
uint32_t currentReportBitIndex = 0;
|
||||
uint8_t currentUsagePage = 0;
|
||||
uint8_t currentUsageIndex = 0;
|
||||
uint8_t xUsageIndex = 0xFF;
|
||||
uint8_t yUsageIndex = 0xFF;
|
||||
uint8_t wheelUsageIndex = 0xFF;
|
||||
uint8_t currentReportSize = 0;
|
||||
uint8_t currentReportCount = 0;
|
||||
|
||||
ReportDataPointer = hUsbHostFS.device.Data;
|
||||
|
||||
ReportButtonBitLength = 0;
|
||||
ReportXBitLength = 0;
|
||||
ReportYBitLength = 0;
|
||||
ReportWheelBitLength = 0;
|
||||
|
||||
while ((Downstream_HID_GetNextReportItem() == HAL_OK) && ((ReportButtonBitLength == 0) ||
|
||||
(ReportXBitLength == 0) ||
|
||||
(ReportYBitLength == 0) ||
|
||||
(ReportWheelBitLength == 0)))
|
||||
{
|
||||
switch (ItemHeader)
|
||||
{
|
||||
case HID_ITEM_USAGE_PAGE:
|
||||
currentUsagePage = ItemData;
|
||||
currentUsageIndex = 0;
|
||||
xUsageIndex = 0xFF;
|
||||
yUsageIndex = 0xFF;
|
||||
wheelUsageIndex = 0xFF;
|
||||
break;
|
||||
|
||||
case HID_ITEM_COLLECTION: //Physical collections also clear the usage index...
|
||||
if (ItemData == HID_ITEM_COLLECTION_PHYS)
|
||||
{
|
||||
currentUsageIndex = 0;
|
||||
xUsageIndex = 0xFF;
|
||||
yUsageIndex = 0xFF;
|
||||
wheelUsageIndex = 0xFF;
|
||||
}
|
||||
break;
|
||||
|
||||
case HID_ITEM_END_COLLECTION: //...and so do collection ends
|
||||
currentUsageIndex = 0;
|
||||
xUsageIndex = 0xFF;
|
||||
yUsageIndex = 0xFF;
|
||||
wheelUsageIndex = 0xFF;
|
||||
break;
|
||||
|
||||
case HID_ITEM_USAGE:
|
||||
switch (ItemData)
|
||||
{
|
||||
case HID_ITEM_USAGE_X:
|
||||
xUsageIndex = currentUsageIndex;
|
||||
break;
|
||||
|
||||
case HID_ITEM_USAGE_Y:
|
||||
yUsageIndex = currentUsageIndex;
|
||||
break;
|
||||
|
||||
case HID_ITEM_USAGE_WHEEL:
|
||||
wheelUsageIndex = currentUsageIndex;
|
||||
break;
|
||||
}
|
||||
currentUsageIndex++;
|
||||
break;
|
||||
|
||||
case HID_ITEM_REPORT_SIZE:
|
||||
currentReportSize = ItemData;
|
||||
break;
|
||||
|
||||
case HID_ITEM_REPORT_COUNT:
|
||||
currentReportCount = ItemData;
|
||||
break;
|
||||
|
||||
case HID_ITEM_REPORT_ID:
|
||||
currentReportBitIndex += 8; //Rudimentary support for a single report ID
|
||||
break;
|
||||
|
||||
case HID_ITEM_INPUT:
|
||||
switch (currentUsagePage)
|
||||
{
|
||||
case HID_ITEM_USAGE_PAGE_BUTTON:
|
||||
if (ItemData == HID_ITEM_INPUT_ABS)
|
||||
{
|
||||
//Buttons found!
|
||||
if (currentReportSize != 1)
|
||||
{
|
||||
return HAL_ERROR;
|
||||
}
|
||||
ReportButtonBitOffset = currentReportBitIndex;
|
||||
ReportButtonBitLength = currentReportCount;
|
||||
if (ReportButtonBitLength > HID_MOUSE_MAX_BUTTONS)
|
||||
{
|
||||
ReportButtonBitLength = HID_MOUSE_MAX_BUTTONS;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case HID_ITEM_USAGE_PAGE_DESKTOP:
|
||||
if (ItemData == HID_ITEM_INPUT_REL)
|
||||
{
|
||||
//Movement data found!
|
||||
if ((currentReportSize < 8) || (currentReportSize > 16))
|
||||
{
|
||||
return HAL_ERROR;
|
||||
}
|
||||
if (xUsageIndex != 0xFF)
|
||||
{
|
||||
ReportXBitOffset = currentReportBitIndex + (currentReportSize * xUsageIndex);
|
||||
ReportXBitLength = currentReportSize;
|
||||
if ((ReportXBitOffset + ReportXBitLength) > (HID_MAX_REPORT_LEN * 8))
|
||||
{
|
||||
return HAL_ERROR;
|
||||
}
|
||||
}
|
||||
if (yUsageIndex != 0xFF)
|
||||
{
|
||||
ReportYBitOffset = currentReportBitIndex + (currentReportSize * yUsageIndex);
|
||||
ReportYBitLength = currentReportSize;
|
||||
if ((ReportYBitOffset + ReportYBitLength) > (HID_MAX_REPORT_LEN * 8))
|
||||
{
|
||||
return HAL_ERROR;
|
||||
}
|
||||
}
|
||||
if (wheelUsageIndex != 0xFF)
|
||||
{
|
||||
ReportWheelBitOffset = currentReportBitIndex + (currentReportSize * wheelUsageIndex);
|
||||
ReportWheelBitLength = currentReportSize;
|
||||
if ((ReportWheelBitOffset + ReportWheelBitLength) > (HID_MAX_REPORT_LEN * 8))
|
||||
{
|
||||
return HAL_ERROR;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
currentUsageIndex = 0;
|
||||
xUsageIndex = 0xFF;
|
||||
yUsageIndex = 0xFF;
|
||||
wheelUsageIndex = 0xFF;
|
||||
currentReportBitIndex += (currentReportSize * currentReportCount);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
//We don't mind if we didn't find a scrollwheel item.
|
||||
if ((ReportButtonBitLength == 0) ||
|
||||
(ReportXBitLength == 0) ||
|
||||
(ReportYBitLength == 0))
|
||||
{
|
||||
return HAL_ERROR;
|
||||
}
|
||||
|
||||
return HAL_OK;
|
||||
}
|
||||
|
||||
|
||||
//Retrieves the next item in the HID report, and at most one of its associated data bytes.
|
||||
//Then it updates ReportDataPointer based on the actual length of the retrieved item.
|
||||
static HAL_StatusTypeDef Downstream_HID_GetNextReportItem(void)
|
||||
{
|
||||
HID_HandleTypeDef* HID_Handle = (HID_HandleTypeDef*)hUsbHostFS.pActiveClass->pData;
|
||||
uint32_t itemLength;
|
||||
|
||||
if ((ReportDataPointer >= &hUsbHostFS.device.Data[USBH_MAX_DATA_BUFFER]) ||
|
||||
((ReportDataPointer - &hUsbHostFS.device.Data[0]) >= HID_Handle->HID_Desc.wItemLength))
|
||||
{
|
||||
return HAL_ERROR;
|
||||
}
|
||||
|
||||
ItemHeader = *ReportDataPointer & HID_ITEM_MASK;
|
||||
itemLength = *ReportDataPointer & HID_ITEM_LENGTH_MASK;
|
||||
ReportDataPointer++;
|
||||
|
||||
if (itemLength == 3)
|
||||
{
|
||||
itemLength = 4; //Length = 3 actually means 4 bytes
|
||||
}
|
||||
|
||||
if (ItemHeader == HID_ITEM_LONG)
|
||||
{
|
||||
itemLength += *ReportDataPointer; //Long items have another length byte
|
||||
}
|
||||
else
|
||||
{
|
||||
if (itemLength > 0)
|
||||
{
|
||||
ItemData = *ReportDataPointer; //If it is a short item, grab its first data byte
|
||||
}
|
||||
}
|
||||
|
||||
ReportDataPointer += itemLength;
|
||||
return HAL_OK;
|
||||
}
|
||||
#endif //#ifdef CONFIG_MOUSE_ENABLED
|
||||
|
||||
|
||||
|
||||
void Downstream_HID_PacketProcessor(DownstreamPacketTypeDef* receivedPacket)
|
||||
{
|
||||
if (receivedPacket->Command == COMMAND_HID_GET_REPORT)
|
||||
{
|
||||
Downstream_ReleasePacket(receivedPacket);
|
||||
if (USBH_HID_GetInterruptReport(&hUsbHostFS,
|
||||
Downstream_HID_InterruptReportCallback) != HAL_OK)
|
||||
{
|
||||
Downstream_PacketProcessor_FreakOut();
|
||||
}
|
||||
Downstream_PacketProcessor_NotifyDisconnectReplyRequired();
|
||||
return;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_KEYBOARD_ENABLED
|
||||
if (receivedPacket->Command == COMMAND_HID_SET_REPORT)
|
||||
{
|
||||
if ((ConfiguredDeviceClass != COMMAND_CLASS_HID_KEYBOARD) ||
|
||||
(receivedPacket->Length16 != ((HID_KEYBOARD_OUTPUT_DATA_LEN + 1) / 2) + DOWNSTREAM_PACKET_HEADER_LEN_16) ||
|
||||
((receivedPacket->Data[0] & ~((1 << HID_KEYBOARD_MAX_LED) - 1)) != 0))
|
||||
{
|
||||
Downstream_PacketProcessor_FreakOut();
|
||||
}
|
||||
USBH_HID_SetReport(&hUsbHostFS,
|
||||
HID_REPORT_DIRECTION_OUT,
|
||||
0,
|
||||
receivedPacket->Data,
|
||||
HID_KEYBOARD_OUTPUT_DATA_LEN,
|
||||
Downstream_HID_SendReportCallback);
|
||||
Downstream_ReleasePacket(receivedPacket);
|
||||
Downstream_PacketProcessor_NotifyDisconnectReplyRequired();
|
||||
return;
|
||||
}
|
||||
#endif //#ifdef CONFIG_KEYBOARD_ENABLED
|
||||
|
||||
//else:
|
||||
Downstream_PacketProcessor_FreakOut();
|
||||
}
|
||||
|
||||
|
||||
void Downstream_HID_InterruptReportCallback(USBH_StatusTypeDef result)
|
||||
{
|
||||
DownstreamPacketTypeDef* freePacket;
|
||||
|
||||
freePacket = Downstream_GetFreePacketImmediately();
|
||||
|
||||
if (result == USBH_OK)
|
||||
{
|
||||
//Data received from device
|
||||
#ifdef CONFIG_MOUSE_ENABLED
|
||||
if (ConfiguredDeviceClass == COMMAND_CLASS_HID_MOUSE)
|
||||
{
|
||||
Downstream_HID_Mouse_ExtractDataFromReport(freePacket);
|
||||
freePacket->Length16 = ((HID_MOUSE_INPUT_DATA_LEN + 1) / 2) + DOWNSTREAM_PACKET_HEADER_LEN_16;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
#ifdef CONFIG_KEYBOARD_ENABLED
|
||||
if (ConfiguredDeviceClass == COMMAND_CLASS_HID_KEYBOARD)
|
||||
{
|
||||
Downstream_HID_Keyboard_ExtractDataFromReport(freePacket);
|
||||
freePacket->Length16 = ((HID_KEYBOARD_INPUT_DATA_LEN + 1) / 2) + DOWNSTREAM_PACKET_HEADER_LEN_16;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
|
||||
//else if...
|
||||
{
|
||||
Downstream_PacketProcessor_FreakOut();
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
//NAK received from device, return zero-length packet
|
||||
freePacket->Length16 = DOWNSTREAM_PACKET_HEADER_LEN_16;
|
||||
}
|
||||
|
||||
freePacket->CommandClass = ConfiguredDeviceClass;
|
||||
freePacket->Command = COMMAND_HID_GET_REPORT;
|
||||
Downstream_PacketProcessor_ClassReply(freePacket);
|
||||
}
|
||||
|
||||
|
||||
#ifdef CONFIG_MOUSE_ENABLED
|
||||
static void Downstream_HID_Mouse_ExtractDataFromReport(DownstreamPacketTypeDef* packetToSend)
|
||||
{
|
||||
HID_HandleTypeDef* HID_Handle = (HID_HandleTypeDef*)hUsbHostFS.pActiveClass->pData;
|
||||
uint32_t readData;
|
||||
|
||||
readData = *(uint32_t*)&(HID_Handle->Data[(ReportButtonBitOffset / 8)]);
|
||||
readData >>= (ReportButtonBitOffset % 8);
|
||||
readData &= ((1 << ReportButtonBitLength) - 1); //Truncate extra buttons
|
||||
packetToSend->Data[0] = readData;
|
||||
|
||||
packetToSend->Data[1] = Downstream_HID_Mouse_Extract8BitValue(HID_Handle,
|
||||
ReportXBitOffset,
|
||||
ReportXBitLength);
|
||||
|
||||
packetToSend->Data[2] = Downstream_HID_Mouse_Extract8BitValue(HID_Handle,
|
||||
ReportYBitOffset,
|
||||
ReportYBitLength);
|
||||
|
||||
packetToSend->Data[3] = Downstream_HID_Mouse_Extract8BitValue(HID_Handle,
|
||||
ReportWheelBitOffset,
|
||||
ReportWheelBitLength);
|
||||
}
|
||||
|
||||
|
||||
|
||||
static uint8_t Downstream_HID_Mouse_Extract8BitValue(HID_HandleTypeDef* hidHandle,
|
||||
uint8_t valueBitOffset,
|
||||
uint8_t valueBitLength)
|
||||
{
|
||||
int32_t readData;
|
||||
|
||||
readData = *(uint32_t*)&(hidHandle->Data[(valueBitOffset / 8)]);
|
||||
readData >>= (valueBitOffset % 8);
|
||||
if (readData & (1 << (valueBitLength - 1))) //If value is negative...
|
||||
{
|
||||
readData |= ~((1 << valueBitLength) - 1); //...sign-extend to full width...
|
||||
}
|
||||
else
|
||||
{
|
||||
readData &= (1 << valueBitLength) - 1; //...else zero out unwanted bits
|
||||
}
|
||||
if (readData < INT8_MIN) readData = INT8_MIN; //Limit to 8-bit values
|
||||
if (readData > INT8_MAX) readData = INT8_MAX;
|
||||
return (int8_t)readData;
|
||||
}
|
||||
#endif //#ifdef CONFIG_MOUSE_ENABLED
|
||||
|
||||
|
||||
#ifdef CONFIG_KEYBOARD_ENABLED
|
||||
static void Downstream_HID_Keyboard_ExtractDataFromReport(DownstreamPacketTypeDef* packetToSend)
|
||||
{
|
||||
HID_HandleTypeDef* HID_Handle = (HID_HandleTypeDef*)hUsbHostFS.pActiveClass->pData;
|
||||
uint32_t i;
|
||||
uint8_t readData;
|
||||
|
||||
packetToSend->Data[0] = HID_Handle->Data[0]; //Modifier keys - pass straight through
|
||||
packetToSend->Data[1] = 0; //Constant byte
|
||||
|
||||
for (i = 2; i < HID_KEYBOARD_INPUT_DATA_LEN; i++) //Key array
|
||||
{
|
||||
readData = HID_Handle->Data[i];
|
||||
if (readData > HID_KEYBOARD_MAX_KEY)
|
||||
{
|
||||
readData = HID_KEYBOARD_MAX_KEY;
|
||||
}
|
||||
packetToSend->Data[i] = readData;
|
||||
}
|
||||
}
|
||||
#endif //#ifdef CONFIG_KEYBOARD_ENABLED
|
||||
|
||||
|
||||
|
||||
void Downstream_HID_SendReportCallback(USBH_StatusTypeDef result)
|
||||
{
|
||||
UNUSED(result);
|
||||
|
||||
DownstreamPacketTypeDef* freePacket;
|
||||
|
||||
freePacket = Downstream_GetFreePacketImmediately();
|
||||
freePacket->Length16 = DOWNSTREAM_PACKET_HEADER_LEN_16;
|
||||
freePacket->CommandClass = ConfiguredDeviceClass;
|
||||
freePacket->Command = COMMAND_HID_SET_REPORT;
|
||||
Downstream_PacketProcessor_ClassReply(freePacket);
|
||||
}
|
||||
|
||||
|
||||
#endif //#if defined (CONFIG_KEYBOARD_ENABLED) || defined (CONFIG_MOUSE_ENABLED)
|
||||
|
@ -0,0 +1,358 @@
|
||||
/*
|
||||
* downstream_msc.c
|
||||
*
|
||||
* Created on: 8/08/2015
|
||||
* Author: Robert Fisk
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
|
||||
#include "downstream_msc.h"
|
||||
#include "downstream_interface_def.h"
|
||||
#include "downstream_statemachine.h"
|
||||
#include "downstream_spi.h"
|
||||
#include "usbh_msc.h"
|
||||
#include "build_config.h"
|
||||
#include "led.h"
|
||||
|
||||
|
||||
#ifdef CONFIG_MASS_STORAGE_ENABLED
|
||||
|
||||
extern USBH_HandleTypeDef hUsbHostFS; //Hard-link ourselves to usb_host.c
|
||||
|
||||
|
||||
//Stuff we need to save for our callbacks to use:
|
||||
DownstreamMSCCallbackPacketTypeDef GetStreamDataCallback;
|
||||
uint32_t ByteCount;
|
||||
DownstreamPacketTypeDef* ReadStreamPacket;
|
||||
uint8_t ReadStreamBusy;
|
||||
|
||||
|
||||
static void Downstream_MSC_PacketProcessor_TestUnitReady(DownstreamPacketTypeDef* receivedPacket);
|
||||
static void Downstream_MSC_PacketProcessor_TestUnitReadyCallback(USBH_StatusTypeDef result);
|
||||
static void Downstream_MSC_PacketProcessor_GetCapacity(DownstreamPacketTypeDef* receivedPacket);
|
||||
static void Downstream_MSC_PacketProcessor_BeginRead(DownstreamPacketTypeDef* receivedPacket);
|
||||
static void Downstream_MSC_PacketProcessor_BeginWrite(DownstreamPacketTypeDef* receivedPacket);
|
||||
static void Downstream_MSC_PacketProcessor_RdWrCompleteCallback(USBH_StatusTypeDef result);
|
||||
static void Downstream_MSC_GetStreamDataPacketCallback(DownstreamPacketTypeDef* receivedPacket);
|
||||
static void Downstream_MSC_PacketProcessor_Disconnect(DownstreamPacketTypeDef* receivedPacket);
|
||||
static void Downstream_MSC_PacketProcessor_DisconnectCallback(USBH_StatusTypeDef result);
|
||||
|
||||
|
||||
//High-level checks on the connected device. We don't want some weirdly
|
||||
//configured device to bomb our USB stack, accidentally or otherwise.
|
||||
InterfaceCommandClassTypeDef Downstream_MSC_ApproveConnectedDevice(void)
|
||||
{
|
||||
MSC_HandleTypeDef* MSC_Handle = (MSC_HandleTypeDef*)hUsbHostFS.pActiveClass->pData;
|
||||
|
||||
if (MSC_Handle->unit[MSC_FIXED_LUN].error != MSC_OK)
|
||||
{
|
||||
return COMMAND_CLASS_INTERFACE; //fail
|
||||
}
|
||||
|
||||
if ((MSC_Handle->unit[MSC_FIXED_LUN].capacity.block_nbr == 0) ||
|
||||
(MSC_Handle->unit[MSC_FIXED_LUN].capacity.block_nbr == UINT32_MAX))
|
||||
{
|
||||
return COMMAND_CLASS_INTERFACE; //fail
|
||||
}
|
||||
|
||||
if (MSC_Handle->unit[MSC_FIXED_LUN].capacity.block_size != MSC_SUPPORTED_BLOCK_SIZE)
|
||||
{
|
||||
return COMMAND_CLASS_INTERFACE; //fail
|
||||
}
|
||||
|
||||
return COMMAND_CLASS_MASS_STORAGE; //success!
|
||||
}
|
||||
|
||||
|
||||
void Downstream_MSC_PacketProcessor(DownstreamPacketTypeDef* receivedPacket)
|
||||
{
|
||||
switch (receivedPacket->Command)
|
||||
{
|
||||
case COMMAND_MSC_TEST_UNIT_READY:
|
||||
Downstream_MSC_PacketProcessor_TestUnitReady(receivedPacket);
|
||||
break;
|
||||
|
||||
case COMMAND_MSC_GET_CAPACITY:
|
||||
Downstream_MSC_PacketProcessor_GetCapacity(receivedPacket);
|
||||
break;
|
||||
|
||||
case COMMAND_MSC_READ:
|
||||
Downstream_MSC_PacketProcessor_BeginRead(receivedPacket);
|
||||
break;
|
||||
|
||||
#ifdef CONFIG_MASS_STORAGE_WRITES_PERMITTED
|
||||
case COMMAND_MSC_WRITE:
|
||||
Downstream_MSC_PacketProcessor_BeginWrite(receivedPacket);
|
||||
break;
|
||||
#endif
|
||||
|
||||
case COMMAND_MSC_DISCONNECT:
|
||||
Downstream_MSC_PacketProcessor_Disconnect(receivedPacket);
|
||||
break;
|
||||
|
||||
case COMMAND_MSC_POLL_DISCONNECT:
|
||||
Downstream_PacketProcessor_ClassReply(receivedPacket); //Device is still connected, so send the packet straight back
|
||||
break;
|
||||
|
||||
default:
|
||||
Downstream_PacketProcessor_FreakOut();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
static void Downstream_MSC_PacketProcessor_TestUnitReady(DownstreamPacketTypeDef* receivedPacket)
|
||||
{
|
||||
Downstream_ReleasePacket(receivedPacket);
|
||||
|
||||
if (USBH_MSC_UnitIsReady(&hUsbHostFS,
|
||||
MSC_FIXED_LUN,
|
||||
Downstream_MSC_PacketProcessor_TestUnitReadyCallback) != USBH_BUSY)
|
||||
{
|
||||
Downstream_MSC_PacketProcessor_TestUnitReadyCallback(USBH_FAIL);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void Downstream_MSC_PacketProcessor_TestUnitReadyCallback(USBH_StatusTypeDef result)
|
||||
{
|
||||
DownstreamPacketTypeDef* freePacket;
|
||||
|
||||
freePacket = Downstream_GetFreePacketImmediately();
|
||||
freePacket->CommandClass = COMMAND_CLASS_MASS_STORAGE;
|
||||
freePacket->Command = COMMAND_MSC_TEST_UNIT_READY;
|
||||
freePacket->Length16 = DOWNSTREAM_PACKET_HEADER_LEN_16 + 1;
|
||||
|
||||
if (result == USBH_OK)
|
||||
{
|
||||
freePacket->Data[0] = HAL_OK;
|
||||
}
|
||||
else
|
||||
{
|
||||
freePacket->Data[0] = HAL_ERROR;
|
||||
}
|
||||
Downstream_PacketProcessor_ClassReply(freePacket);
|
||||
}
|
||||
|
||||
|
||||
|
||||
static void Downstream_MSC_PacketProcessor_GetCapacity(DownstreamPacketTypeDef* receivedPacket)
|
||||
{
|
||||
MSC_HandleTypeDef* MSC_Handle = (MSC_HandleTypeDef*)hUsbHostFS.pActiveClass->pData;
|
||||
|
||||
receivedPacket->Length16 = DOWNSTREAM_PACKET_HEADER_LEN_16 + (8 / 2);
|
||||
*(uint32_t*)&(receivedPacket->Data[0]) = MSC_Handle->unit[MSC_FIXED_LUN].capacity.block_nbr;
|
||||
*(uint32_t*)&(receivedPacket->Data[4]) = (uint32_t)MSC_Handle->unit[MSC_FIXED_LUN].capacity.block_size;
|
||||
Downstream_PacketProcessor_ClassReply(receivedPacket);
|
||||
}
|
||||
|
||||
|
||||
|
||||
static void Downstream_MSC_PacketProcessor_BeginRead(DownstreamPacketTypeDef* receivedPacket)
|
||||
{
|
||||
uint64_t readBlockAddress;
|
||||
uint32_t readBlockCount;
|
||||
uint64_t readByteCount;
|
||||
MSC_HandleTypeDef* MSC_Handle = (MSC_HandleTypeDef*)hUsbHostFS.pActiveClass->pData;
|
||||
|
||||
if (receivedPacket->Length16 != (DOWNSTREAM_PACKET_HEADER_LEN_16 + ((4 * 3) / 2)))
|
||||
{
|
||||
Downstream_PacketProcessor_FreakOut();
|
||||
return;
|
||||
}
|
||||
|
||||
LED_SetState(LED_STATUS_FLASH_READWRITE);
|
||||
readBlockAddress = *(uint64_t*)&(receivedPacket->Data[0]);
|
||||
readBlockCount = *(uint32_t*)&(receivedPacket->Data[8]);
|
||||
readByteCount = readBlockCount * MSC_Handle->unit[MSC_FIXED_LUN].capacity.block_size;
|
||||
if ((readBlockAddress >= (uint64_t)MSC_Handle->unit[MSC_FIXED_LUN].capacity.block_nbr) ||
|
||||
((readBlockAddress + readBlockCount - 1) >= (uint64_t)MSC_Handle->unit[MSC_FIXED_LUN].capacity.block_nbr) ||
|
||||
(readByteCount > UINT32_MAX))
|
||||
{
|
||||
Downstream_PacketProcessor_FreakOut();
|
||||
return;
|
||||
}
|
||||
|
||||
receivedPacket->Data[0] = HAL_ERROR;
|
||||
receivedPacket->Length16 = DOWNSTREAM_PACKET_HEADER_LEN_16 + 1;
|
||||
if (USBH_MSC_Read(&hUsbHostFS,
|
||||
MSC_FIXED_LUN,
|
||||
(uint32_t)readBlockAddress,
|
||||
readBlockCount,
|
||||
Downstream_MSC_PacketProcessor_RdWrCompleteCallback) == USBH_BUSY)
|
||||
{
|
||||
Downstream_ReleasePacket(receivedPacket);
|
||||
return;
|
||||
}
|
||||
|
||||
//Fail:
|
||||
Downstream_PacketProcessor_ClassReply(receivedPacket);
|
||||
}
|
||||
|
||||
|
||||
static void Downstream_MSC_PacketProcessor_RdWrCompleteCallback(USBH_StatusTypeDef result)
|
||||
{
|
||||
if (result != USBH_OK)
|
||||
{
|
||||
Downstream_GetFreePacket(Downstream_PacketProcessor_GenericErrorReply);
|
||||
return;
|
||||
}
|
||||
Downstream_ReceivePacket(Downstream_PacketProcessor);
|
||||
}
|
||||
|
||||
|
||||
|
||||
#ifdef CONFIG_MASS_STORAGE_WRITES_PERMITTED
|
||||
static void Downstream_MSC_PacketProcessor_BeginWrite(DownstreamPacketTypeDef* receivedPacket)
|
||||
{
|
||||
uint64_t writeBlockAddress;
|
||||
uint32_t writeBlockCount;
|
||||
uint64_t writeByteCount;
|
||||
MSC_HandleTypeDef* MSC_Handle = (MSC_HandleTypeDef*)hUsbHostFS.pActiveClass->pData;
|
||||
|
||||
if (receivedPacket->Length16 != (DOWNSTREAM_PACKET_HEADER_LEN_16 + ((4 * 3) / 2)))
|
||||
{
|
||||
Downstream_PacketProcessor_FreakOut();
|
||||
return;
|
||||
}
|
||||
|
||||
writeBlockAddress = *(uint64_t*)&(receivedPacket->Data[0]);
|
||||
writeBlockCount = *(uint32_t*)&(receivedPacket->Data[8]);
|
||||
writeByteCount = writeBlockCount * MSC_Handle->unit[MSC_FIXED_LUN].capacity.block_size;
|
||||
if ((writeBlockAddress >= (uint64_t)MSC_Handle->unit[MSC_FIXED_LUN].capacity.block_nbr) ||
|
||||
((writeBlockAddress + writeBlockCount - 1) >= (uint64_t)MSC_Handle->unit[MSC_FIXED_LUN].capacity.block_nbr) ||
|
||||
(writeByteCount > UINT32_MAX))
|
||||
{
|
||||
Downstream_PacketProcessor_FreakOut();
|
||||
return;
|
||||
}
|
||||
|
||||
ReadStreamPacket = NULL; //Prepare for GetStreamDataPacket's use
|
||||
ReadStreamBusy = 0;
|
||||
ByteCount = (uint32_t)writeByteCount;
|
||||
|
||||
receivedPacket->Data[0] = HAL_ERROR;
|
||||
receivedPacket->Length16 = DOWNSTREAM_PACKET_HEADER_LEN_16 + 1;
|
||||
|
||||
//Our host stack has no way to detect if write-protection is enabled.
|
||||
//So currently we can't return HAL_BUSY to Upstream in this situation.
|
||||
if (USBH_MSC_Write(&hUsbHostFS,
|
||||
MSC_FIXED_LUN,
|
||||
(uint32_t)writeBlockAddress,
|
||||
writeBlockCount,
|
||||
Downstream_MSC_PacketProcessor_RdWrCompleteCallback) == USBH_BUSY)
|
||||
{
|
||||
Downstream_ReleasePacket(receivedPacket);
|
||||
return;
|
||||
}
|
||||
|
||||
//Fail:
|
||||
Downstream_PacketProcessor_ClassReply(receivedPacket);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
//Used by USB MSC host driver
|
||||
HAL_StatusTypeDef Downstream_MSC_PutStreamDataPacket(DownstreamPacketTypeDef* packetToSend,
|
||||
uint32_t dataLength8)
|
||||
{
|
||||
if ((dataLength8 % 2) != 0)
|
||||
{
|
||||
return HAL_ERROR;
|
||||
}
|
||||
|
||||
packetToSend->Length16 = (dataLength8 / 2) + DOWNSTREAM_PACKET_HEADER_LEN_16;
|
||||
packetToSend->CommandClass = COMMAND_CLASS_MASS_STORAGE | COMMAND_CLASS_DATA_FLAG;
|
||||
packetToSend->Command = COMMAND_MSC_READ;
|
||||
return Downstream_TransmitPacket(packetToSend);
|
||||
}
|
||||
|
||||
|
||||
#ifdef CONFIG_MASS_STORAGE_WRITES_PERMITTED
|
||||
//Used by USB MSC host driver
|
||||
HAL_StatusTypeDef Downstream_MSC_GetStreamDataPacket(DownstreamMSCCallbackPacketTypeDef callback)
|
||||
{
|
||||
GetStreamDataCallback = callback;
|
||||
|
||||
if (ReadStreamBusy != 0)
|
||||
{
|
||||
return HAL_OK;
|
||||
}
|
||||
ReadStreamBusy = 1;
|
||||
|
||||
if (ReadStreamPacket && GetStreamDataCallback) //Do we have a stored packet and an address to send it?
|
||||
{
|
||||
Downstream_MSC_GetStreamDataPacketCallback(ReadStreamPacket); //Send it now!
|
||||
ReadStreamPacket = NULL;
|
||||
return HAL_OK; //Our callback will call us again, so we don't need to get a packet in this case.
|
||||
}
|
||||
return Downstream_ReceivePacket(Downstream_MSC_GetStreamDataPacketCallback);
|
||||
}
|
||||
|
||||
|
||||
void Downstream_MSC_GetStreamDataPacketCallback(DownstreamPacketTypeDef* receivedPacket)
|
||||
{
|
||||
uint16_t dataLength8;
|
||||
|
||||
ReadStreamBusy = 0;
|
||||
if (GetStreamDataCallback == NULL)
|
||||
{
|
||||
ReadStreamPacket = receivedPacket; //We used up our callback already, so save this one for later.
|
||||
return;
|
||||
}
|
||||
|
||||
dataLength8 = (receivedPacket->Length16 - DOWNSTREAM_PACKET_HEADER_LEN_16) * 2;
|
||||
|
||||
if ((receivedPacket->CommandClass != (COMMAND_CLASS_MASS_STORAGE | COMMAND_CLASS_DATA_FLAG)) || //Must be MSC command with data flag set
|
||||
(receivedPacket->Command != COMMAND_MSC_WRITE) || //Must be write command
|
||||
(receivedPacket->Length16 <= DOWNSTREAM_PACKET_HEADER_LEN_16) || //Should be at least one data byte in the packet.
|
||||
(dataLength8 > ByteCount))
|
||||
{
|
||||
Downstream_PacketProcessor_FreakOut();
|
||||
return;
|
||||
}
|
||||
|
||||
ByteCount -= dataLength8;
|
||||
GetStreamDataCallback(receivedPacket, dataLength8); //usb_msc_scsi will use this packet, so don't release now
|
||||
if (ByteCount > 0)
|
||||
{
|
||||
Downstream_MSC_GetStreamDataPacket(NULL); //Try to get the next packet now, before USB asks for it
|
||||
}
|
||||
|
||||
}
|
||||
#endif //#ifdef CONFIG_MASS_STORAGE_WRITES_PERMITTED
|
||||
|
||||
|
||||
|
||||
static void Downstream_MSC_PacketProcessor_Disconnect(DownstreamPacketTypeDef* receivedPacket)
|
||||
{
|
||||
Downstream_ReleasePacket(receivedPacket);
|
||||
|
||||
USBH_MSC_StartStopUnit(&hUsbHostFS,
|
||||
MSC_FIXED_LUN,
|
||||
MSC_START_STOP_EJECT_FLAG,
|
||||
Downstream_MSC_PacketProcessor_DisconnectCallback);
|
||||
}
|
||||
|
||||
|
||||
|
||||
static void Downstream_MSC_PacketProcessor_DisconnectCallback(USBH_StatusTypeDef result)
|
||||
{
|
||||
DownstreamPacketTypeDef* freePacket;
|
||||
|
||||
if (result == USBH_OK)
|
||||
{
|
||||
freePacket = Downstream_GetFreePacketImmediately();
|
||||
freePacket->CommandClass = COMMAND_CLASS_MASS_STORAGE;
|
||||
freePacket->Command = COMMAND_MSC_DISCONNECT;
|
||||
freePacket->Length16 = DOWNSTREAM_PACKET_HEADER_LEN_16;
|
||||
Downstream_PacketProcessor_ClassReply(freePacket);
|
||||
}
|
||||
}
|
||||
|
||||
#endif //#ifdef CONFIG_MASS_STORAGE_ENABLED
|
||||
|
@ -0,0 +1,419 @@
|
||||
/*
|
||||
* upstream_spi.c
|
||||
*
|
||||
* Created on: 24/07/2015
|
||||
* Author: Robert Fisk
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
|
||||
#include "downstream_interface_def.h"
|
||||
#include "downstream_spi.h"
|
||||
#include "downstream_statemachine.h"
|
||||
#include "board_config.h"
|
||||
#include "led.h"
|
||||
|
||||
|
||||
SPI_HandleTypeDef Hspi1;
|
||||
DownstreamPacketTypeDef DownstreamPacket0;
|
||||
DownstreamPacketTypeDef DownstreamPacket1;
|
||||
DownstreamPacketTypeDef* CurrentWorkingPacket;
|
||||
DownstreamPacketTypeDef* NextTxPacket = NULL;
|
||||
|
||||
InterfaceStateTypeDef DownstreamInterfaceState = DOWNSTREAM_INTERFACE_IDLE;
|
||||
FreePacketCallbackTypeDef PendingFreePacketCallback = NULL; //Indicates someone is waiting for a packet buffer to become available
|
||||
SpiPacketReceivedCallbackTypeDef ReceivePacketCallback = NULL; //Indicates someone is waiting for a received packet
|
||||
|
||||
uint32_t TemporaryIncomingPacketLength = 0;
|
||||
uint8_t SpiInterruptCompleted = 0;
|
||||
|
||||
|
||||
HAL_StatusTypeDef Downstream_CheckPreparePacketReception(void);
|
||||
void Downstream_PrepareReceivePacketSize(DownstreamPacketTypeDef* freePacket);
|
||||
|
||||
|
||||
|
||||
void Downstream_InitSPI(void)
|
||||
{
|
||||
DownstreamPacket0.Busy = NOT_BUSY;
|
||||
DownstreamPacket1.Busy = NOT_BUSY;
|
||||
|
||||
Hspi1.Instance = SPI1;
|
||||
Hspi1.Init.Mode = SPI_MODE_SLAVE;
|
||||
Hspi1.Init.Direction = SPI_DIRECTION_2LINES;
|
||||
Hspi1.Init.DataSize = SPI_DATASIZE_16BIT;
|
||||
Hspi1.Init.CLKPolarity = SPI_POLARITY_LOW;
|
||||
Hspi1.Init.CLKPhase = SPI_PHASE_1EDGE;
|
||||
Hspi1.Init.NSS = SPI_NSS_HARD_INPUT;
|
||||
Hspi1.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_2;
|
||||
Hspi1.Init.FirstBit = SPI_FIRSTBIT_MSB;
|
||||
Hspi1.Init.TIMode = SPI_TIMODE_DISABLED;
|
||||
Hspi1.Init.CRCCalculation = SPI_CRCCALCULATION_ENABLE;
|
||||
Hspi1.Init.CRCPolynomial = SPI_CRC_DEFAULTPOLYNOMIAL;
|
||||
HAL_SPI_Init(&Hspi1);
|
||||
}
|
||||
|
||||
|
||||
//Used by downstream state machine and USB host classes.
|
||||
HAL_StatusTypeDef Downstream_GetFreePacket(FreePacketCallbackTypeDef callback)
|
||||
{
|
||||
if (DownstreamInterfaceState >= DOWNSTREAM_INTERFACE_ERROR)
|
||||
{
|
||||
return HAL_ERROR;
|
||||
}
|
||||
|
||||
//Do we already have a queued callback?
|
||||
if (PendingFreePacketCallback != NULL)
|
||||
{
|
||||
DOWNSTREAM_SPI_FREAKOUT;
|
||||
return HAL_ERROR;
|
||||
}
|
||||
|
||||
//Check if there is a free buffer now
|
||||
if (DownstreamPacket0.Busy == NOT_BUSY)
|
||||
{
|
||||
DownstreamPacket0.Busy = BUSY;
|
||||
callback(&DownstreamPacket0);
|
||||
return HAL_OK;
|
||||
}
|
||||
if (DownstreamPacket1.Busy == NOT_BUSY)
|
||||
{
|
||||
DownstreamPacket1.Busy = BUSY;
|
||||
callback(&DownstreamPacket1);
|
||||
return HAL_OK;
|
||||
}
|
||||
|
||||
//Otherwise save requested address for when a buffer becomes free in the future
|
||||
PendingFreePacketCallback = callback;
|
||||
return HAL_OK;
|
||||
}
|
||||
|
||||
|
||||
|
||||
DownstreamPacketTypeDef* Downstream_GetFreePacketImmediately(void)
|
||||
{
|
||||
if (DownstreamInterfaceState >= DOWNSTREAM_INTERFACE_ERROR)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
//We are expecting a free buffer now
|
||||
if (DownstreamPacket0.Busy == NOT_BUSY)
|
||||
{
|
||||
DownstreamPacket0.Busy = BUSY;
|
||||
return &DownstreamPacket0;
|
||||
}
|
||||
if (DownstreamPacket1.Busy == NOT_BUSY)
|
||||
{
|
||||
DownstreamPacket1.Busy = BUSY;
|
||||
return &DownstreamPacket1;
|
||||
}
|
||||
|
||||
//Should not happen:
|
||||
DOWNSTREAM_SPI_FREAKOUT;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//Used by Downstream state machine and USB host classes.
|
||||
void Downstream_ReleasePacket(DownstreamPacketTypeDef* packetToRelease)
|
||||
{
|
||||
FreePacketCallbackTypeDef tempCallback;
|
||||
|
||||
if (DownstreamInterfaceState >= DOWNSTREAM_INTERFACE_ERROR)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if ((packetToRelease != &DownstreamPacket0) &&
|
||||
(packetToRelease != &DownstreamPacket1))
|
||||
{
|
||||
DOWNSTREAM_SPI_FREAKOUT;
|
||||
return;
|
||||
}
|
||||
|
||||
if (PendingFreePacketCallback != NULL)
|
||||
{
|
||||
tempCallback = PendingFreePacketCallback; //In extreme situations, running this callback can trigger another request for a free packet,
|
||||
PendingFreePacketCallback = NULL; //thereby causing GetFreePacket to freak out. So we need to clear the callback indicator first.
|
||||
tempCallback(packetToRelease);
|
||||
}
|
||||
else
|
||||
{
|
||||
packetToRelease->Busy = NOT_BUSY;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//Used by Downstream state machine and USB classes.
|
||||
//Ok to call when idle or transmitting.
|
||||
//Not OK to call when receiving or awaiting reception.
|
||||
HAL_StatusTypeDef Downstream_ReceivePacket(SpiPacketReceivedCallbackTypeDef callback)
|
||||
{
|
||||
if (DownstreamInterfaceState >= DOWNSTREAM_INTERFACE_ERROR)
|
||||
{
|
||||
return HAL_ERROR;
|
||||
}
|
||||
|
||||
if ((DownstreamInterfaceState == DOWNSTREAM_INTERFACE_RX_SIZE_WAIT) ||
|
||||
(DownstreamInterfaceState == DOWNSTREAM_INTERFACE_RX_PACKET_WAIT) ||
|
||||
(ReceivePacketCallback != NULL))
|
||||
{
|
||||
DOWNSTREAM_SPI_FREAKOUT;
|
||||
return HAL_ERROR;
|
||||
}
|
||||
|
||||
ReceivePacketCallback = callback;
|
||||
return Downstream_CheckPreparePacketReception();
|
||||
}
|
||||
|
||||
|
||||
//Internal use only
|
||||
HAL_StatusTypeDef Downstream_CheckPreparePacketReception(void)
|
||||
{
|
||||
if (DownstreamInterfaceState >= DOWNSTREAM_INTERFACE_ERROR)
|
||||
{
|
||||
return HAL_ERROR;
|
||||
}
|
||||
|
||||
if (DownstreamInterfaceState == DOWNSTREAM_INTERFACE_IDLE)
|
||||
{
|
||||
DownstreamInterfaceState = DOWNSTREAM_INTERFACE_RX_SIZE_WAIT;
|
||||
return Downstream_GetFreePacket(Downstream_PrepareReceivePacketSize);
|
||||
}
|
||||
return HAL_OK;
|
||||
}
|
||||
|
||||
|
||||
//Internal use only
|
||||
void Downstream_PrepareReceivePacketSize(DownstreamPacketTypeDef* freePacket)
|
||||
{
|
||||
if (DownstreamInterfaceState >= DOWNSTREAM_INTERFACE_ERROR)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (DownstreamInterfaceState != DOWNSTREAM_INTERFACE_RX_SIZE_WAIT)
|
||||
{
|
||||
DOWNSTREAM_SPI_FREAKOUT;
|
||||
return;
|
||||
}
|
||||
CurrentWorkingPacket = freePacket;
|
||||
CurrentWorkingPacket->Length16 = 0;
|
||||
if (HAL_SPI_TransmitReceive_DMA(&Hspi1,
|
||||
(uint8_t*)&CurrentWorkingPacket->Length16,
|
||||
(uint8_t*)&CurrentWorkingPacket->Length16,
|
||||
2) != HAL_OK) //We only need to read one word, but the peripheral library freaks out...
|
||||
{
|
||||
DOWNSTREAM_SPI_FREAKOUT;
|
||||
return;
|
||||
}
|
||||
|
||||
UPSTREAM_TX_REQUEST_ASSERT;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//Used by Downstream state machine and USB classes.
|
||||
//Call when idle or transmitting.
|
||||
//It doesn't make sense to call when receiving or awaiting reception.
|
||||
HAL_StatusTypeDef Downstream_TransmitPacket(DownstreamPacketTypeDef* packetToWrite)
|
||||
{
|
||||
if (DownstreamInterfaceState >= DOWNSTREAM_INTERFACE_ERROR)
|
||||
{
|
||||
return HAL_ERROR;
|
||||
}
|
||||
|
||||
//Sanity checks
|
||||
if ((packetToWrite != &DownstreamPacket0) &&
|
||||
(packetToWrite != &DownstreamPacket1))
|
||||
{
|
||||
DOWNSTREAM_SPI_FREAKOUT;
|
||||
return HAL_ERROR;
|
||||
}
|
||||
if ((packetToWrite->Busy != BUSY) ||
|
||||
(packetToWrite->Length16 < DOWNSTREAM_PACKET_LEN_MIN_16) ||
|
||||
(packetToWrite->Length16 > DOWNSTREAM_PACKET_LEN_16))
|
||||
{
|
||||
DOWNSTREAM_SPI_FREAKOUT;
|
||||
return HAL_ERROR;
|
||||
}
|
||||
if (NextTxPacket != NULL)
|
||||
{
|
||||
DOWNSTREAM_SPI_FREAKOUT;
|
||||
return HAL_ERROR;
|
||||
}
|
||||
|
||||
switch (DownstreamInterfaceState)
|
||||
{
|
||||
case DOWNSTREAM_INTERFACE_TX_SIZE_WAIT:
|
||||
case DOWNSTREAM_INTERFACE_TX_PACKET_WAIT:
|
||||
NextTxPacket = packetToWrite;
|
||||
break;
|
||||
|
||||
case DOWNSTREAM_INTERFACE_IDLE:
|
||||
DownstreamInterfaceState = DOWNSTREAM_INTERFACE_TX_SIZE_WAIT;
|
||||
CurrentWorkingPacket = packetToWrite;
|
||||
|
||||
if (HAL_SPI_TransmitReceive_DMA(&Hspi1,
|
||||
(uint8_t*)&CurrentWorkingPacket->Length16,
|
||||
(uint8_t*)&TemporaryIncomingPacketLength,
|
||||
2) != HAL_OK) //We only need to write one word, but the peripheral library freaks out...
|
||||
{
|
||||
DOWNSTREAM_SPI_FREAKOUT;
|
||||
return HAL_ERROR;
|
||||
}
|
||||
UPSTREAM_TX_REQUEST_ASSERT;
|
||||
break;
|
||||
|
||||
default:
|
||||
DOWNSTREAM_SPI_FREAKOUT;
|
||||
return HAL_ERROR;
|
||||
}
|
||||
|
||||
return HAL_OK;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//Do stuff at main loop priority after SPI transaction is complete
|
||||
void Downstream_SPIProcess(void)
|
||||
{
|
||||
SpiPacketReceivedCallbackTypeDef tempPacketCallback;
|
||||
|
||||
if (SpiInterruptCompleted == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
SpiInterruptCompleted = 0;
|
||||
|
||||
if (DownstreamInterfaceState >= DOWNSTREAM_INTERFACE_ERROR)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
//Finished transmitting packet size
|
||||
if (DownstreamInterfaceState == DOWNSTREAM_INTERFACE_TX_SIZE_WAIT)
|
||||
{
|
||||
if ((uint16_t)TemporaryIncomingPacketLength != 0)
|
||||
{
|
||||
//Currently we just freak out if Upstream sends us an unexpected command.
|
||||
//Theoretically we could reset our downstream state machine and accept the new command...
|
||||
DOWNSTREAM_SPI_FREAKOUT;
|
||||
return;
|
||||
}
|
||||
|
||||
DownstreamInterfaceState = DOWNSTREAM_INTERFACE_TX_PACKET_WAIT;
|
||||
if (HAL_SPI_TransmitReceive_DMA(&Hspi1,
|
||||
&CurrentWorkingPacket->CommandClass,
|
||||
&CurrentWorkingPacket->CommandClass,
|
||||
((CurrentWorkingPacket->Length16 < 2) ? 2 : CurrentWorkingPacket->Length16)) != HAL_OK)
|
||||
{
|
||||
DOWNSTREAM_SPI_FREAKOUT;
|
||||
return;
|
||||
}
|
||||
UPSTREAM_TX_REQUEST_ASSERT;
|
||||
return;
|
||||
}
|
||||
|
||||
//Finished transmitting packet body
|
||||
if (DownstreamInterfaceState == DOWNSTREAM_INTERFACE_TX_PACKET_WAIT)
|
||||
{
|
||||
Downstream_ReleasePacket(CurrentWorkingPacket);
|
||||
if (NextTxPacket != NULL)
|
||||
{
|
||||
//NextTxPacket has already passed the checks in Downstream_TransmitPacket.
|
||||
//So we just need to pass it to HAL_SPI_Transmit_DMA.
|
||||
DownstreamInterfaceState = DOWNSTREAM_INTERFACE_TX_SIZE_WAIT;
|
||||
CurrentWorkingPacket = NextTxPacket;
|
||||
NextTxPacket = NULL;
|
||||
if (HAL_SPI_TransmitReceive_DMA(&Hspi1,
|
||||
(uint8_t*)&CurrentWorkingPacket->Length16,
|
||||
(uint8_t*)&TemporaryIncomingPacketLength,
|
||||
2) != HAL_OK) //We only need to write one word, but the peripheral library freaks out...
|
||||
{
|
||||
DOWNSTREAM_SPI_FREAKOUT;
|
||||
return;
|
||||
}
|
||||
UPSTREAM_TX_REQUEST_ASSERT;
|
||||
return;
|
||||
}
|
||||
|
||||
DownstreamInterfaceState = DOWNSTREAM_INTERFACE_IDLE;
|
||||
if (ReceivePacketCallback != NULL)
|
||||
{
|
||||
Downstream_CheckPreparePacketReception();
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if (DownstreamInterfaceState == DOWNSTREAM_INTERFACE_RX_SIZE_WAIT)
|
||||
{
|
||||
if ((CurrentWorkingPacket->Length16 < DOWNSTREAM_PACKET_LEN_MIN_16) ||
|
||||
(CurrentWorkingPacket->Length16 > DOWNSTREAM_PACKET_LEN_16))
|
||||
{
|
||||
DOWNSTREAM_SPI_FREAKOUT;
|
||||
return;
|
||||
}
|
||||
DownstreamInterfaceState = DOWNSTREAM_INTERFACE_RX_PACKET_WAIT;
|
||||
if (HAL_SPI_TransmitReceive_DMA(&Hspi1,
|
||||
&CurrentWorkingPacket->CommandClass,
|
||||
&CurrentWorkingPacket->CommandClass,
|
||||
((CurrentWorkingPacket->Length16 < 2) ? 2 : CurrentWorkingPacket->Length16)) != HAL_OK)
|
||||
{
|
||||
DOWNSTREAM_SPI_FREAKOUT;
|
||||
return;
|
||||
}
|
||||
UPSTREAM_TX_REQUEST_ASSERT;
|
||||
return;
|
||||
}
|
||||
|
||||
if (DownstreamInterfaceState == DOWNSTREAM_INTERFACE_RX_PACKET_WAIT)
|
||||
{
|
||||
DownstreamInterfaceState = DOWNSTREAM_INTERFACE_IDLE;
|
||||
if (ReceivePacketCallback == NULL)
|
||||
{
|
||||
DOWNSTREAM_SPI_FREAKOUT;
|
||||
return;
|
||||
}
|
||||
//Packet processor may want to receive another packet immediately,
|
||||
//so clear ReceivePacketCallback before the call.
|
||||
//It is the callback's responsibility to release the packet buffer we are passing to it!
|
||||
tempPacketCallback = ReceivePacketCallback;
|
||||
ReceivePacketCallback = NULL;
|
||||
tempPacketCallback(CurrentWorkingPacket);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
//case default:
|
||||
DOWNSTREAM_SPI_FREAKOUT;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//Called at the end of the SPI TxRx DMA transfer,
|
||||
//at DMA2 interrupt priority. Assume *hspi points to our hspi1.
|
||||
//We use TxRx to send our reply packet to check if Upstream was trying
|
||||
//to send us a packet at the same time.
|
||||
//We also TxRx our packet body because the SPI silicon is buggy at the end of
|
||||
//a transmit-only DMA transfer with CRC! (it does not clear RXNE flag on request)
|
||||
void HAL_SPI_TxRxCpltCallback(SPI_HandleTypeDef *hspi)
|
||||
{
|
||||
UPSTREAM_TX_REQUEST_DEASSERT;
|
||||
SpiInterruptCompleted = 1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//Something bad happened! Possibly CRC error...
|
||||
void HAL_SPI_ErrorCallback(SPI_HandleTypeDef *hspi)
|
||||
{
|
||||
DOWNSTREAM_SPI_FREAKOUT;
|
||||
}
|
||||
|
@ -0,0 +1,338 @@
|
||||
/*
|
||||
* downstream_statemachine.c
|
||||
*
|
||||
* Created on: 2/08/2015
|
||||
* Author: Robert Fisk
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
|
||||
#include "downstream_statemachine.h"
|
||||
#include "downstream_interface_def.h"
|
||||
#include "downstream_spi.h"
|
||||
#include "downstream_msc.h"
|
||||
#include "downstream_hid.h"
|
||||
#include "usbh_core.h"
|
||||
#include "usbh_msc.h"
|
||||
#include "usbh_hid.h"
|
||||
#include "led.h"
|
||||
#include "build_config.h"
|
||||
|
||||
|
||||
DownstreamStateTypeDef DownstreamState = STATE_DEVICE_NOT_READY;
|
||||
InterfaceCommandClassTypeDef ConfiguredDeviceClass = COMMAND_CLASS_INTERFACE;
|
||||
uint8_t NotifyDisconnectReply = 0;
|
||||
|
||||
|
||||
static void Downstream_PacketProcessor_Interface(DownstreamPacketTypeDef* receivedPacket);
|
||||
static void Downstream_PacketProcessor_Interface_ReplyNotifyDevice(DownstreamPacketTypeDef* replyPacket);
|
||||
static void Downstream_PacketProcessor_NotifyDisconnectReply(DownstreamPacketTypeDef* packetToSend);
|
||||
|
||||
|
||||
#ifdef CONFIG_USB_ID_ENABLED
|
||||
|
||||
//usb device id def
|
||||
typedef struct usb_id{
|
||||
uint16_t vendor;
|
||||
uint16_t product;
|
||||
}usb_device_id;
|
||||
|
||||
#define USB_ID_COUNT 2
|
||||
|
||||
usb_device_id list[USB_ID_COUNT]={
|
||||
{0x046d,0xc077},//usb vendor,usb product, add your device to array and edit USB_ID_COUNT
|
||||
// {0x046d,0xc0ff} //bad device test
|
||||
{0x12c9,0x1017} //new mouse Fury
|
||||
};
|
||||
#endif
|
||||
|
||||
void Downstream_InitStateMachine(void)
|
||||
{
|
||||
if ((DownstreamState != STATE_DEVICE_NOT_READY) ||
|
||||
(ConfiguredDeviceClass != COMMAND_CLASS_INTERFACE))
|
||||
{
|
||||
DOWNSTREAM_STATEMACHINE_FREAKOUT;
|
||||
return;
|
||||
}
|
||||
|
||||
Downstream_InitSPI();
|
||||
|
||||
//Prepare to receive our first packet from Upstream!
|
||||
Downstream_ReceivePacket(Downstream_PacketProcessor);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void Downstream_PacketProcessor(DownstreamPacketTypeDef* receivedPacket)
|
||||
{
|
||||
if (DownstreamState >= STATE_ERROR)
|
||||
{
|
||||
Downstream_ReleasePacket(receivedPacket);
|
||||
return;
|
||||
}
|
||||
|
||||
//Device not connected yet
|
||||
if (DownstreamState != STATE_ACTIVE)
|
||||
{
|
||||
if (receivedPacket->CommandClass == COMMAND_CLASS_INTERFACE)
|
||||
{
|
||||
Downstream_PacketProcessor_Interface(receivedPacket);
|
||||
}
|
||||
else
|
||||
{
|
||||
//If we get a class-specific message when our device is disconnected,
|
||||
//we need to tell Upstream of the fact (and not freak out).
|
||||
Downstream_PacketProcessor_NotifyDisconnectReply(receivedPacket);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
//Device is connected: expect only class-specific messages,
|
||||
//and only to our currently active device class.
|
||||
if ((ConfiguredDeviceClass == COMMAND_CLASS_INTERFACE) ||
|
||||
(ConfiguredDeviceClass != receivedPacket->CommandClass))
|
||||
{
|
||||
DOWNSTREAM_STATEMACHINE_FREAKOUT;
|
||||
return;
|
||||
}
|
||||
|
||||
switch (ConfiguredDeviceClass)
|
||||
{
|
||||
|
||||
#ifdef CONFIG_MASS_STORAGE_ENABLED
|
||||
case COMMAND_CLASS_MASS_STORAGE:
|
||||
Downstream_MSC_PacketProcessor(receivedPacket);
|
||||
break;
|
||||
#endif
|
||||
#ifdef CONFIG_MOUSE_ENABLED
|
||||
case COMMAND_CLASS_HID_MOUSE:
|
||||
Downstream_HID_PacketProcessor(receivedPacket);
|
||||
break;
|
||||
#endif
|
||||
#ifdef CONFIG_KEYBOARD_ENABLED
|
||||
case COMMAND_CLASS_HID_KEYBOARD:
|
||||
Downstream_HID_PacketProcessor(receivedPacket);
|
||||
break;
|
||||
#endif
|
||||
|
||||
//Add other classes here...
|
||||
|
||||
default:
|
||||
DOWNSTREAM_STATEMACHINE_FREAKOUT;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
//Used by downstream class interfaces, and SPI interface
|
||||
void Downstream_PacketProcessor_FreakOut(void)
|
||||
{
|
||||
DOWNSTREAM_STATEMACHINE_FREAKOUT;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void Downstream_PacketProcessor_Interface(DownstreamPacketTypeDef* receivedPacket)
|
||||
{
|
||||
switch (receivedPacket->Command)
|
||||
{
|
||||
case COMMAND_INTERFACE_ECHO:
|
||||
Downstream_TransmitPacket(receivedPacket);
|
||||
Downstream_ReceivePacket(Downstream_PacketProcessor);
|
||||
break;
|
||||
|
||||
case COMMAND_INTERFACE_NOTIFY_DEVICE:
|
||||
if (DownstreamState == STATE_DEVICE_READY)
|
||||
{
|
||||
Downstream_PacketProcessor_Interface_ReplyNotifyDevice(receivedPacket);
|
||||
return;
|
||||
}
|
||||
|
||||
if (DownstreamState == STATE_DEVICE_NOT_READY)
|
||||
{
|
||||
DownstreamState = STATE_WAIT_DEVICE_READY;
|
||||
Downstream_ReleasePacket(receivedPacket);
|
||||
return;
|
||||
}
|
||||
DOWNSTREAM_STATEMACHINE_FREAKOUT;
|
||||
break;
|
||||
|
||||
|
||||
default:
|
||||
DOWNSTREAM_STATEMACHINE_FREAKOUT;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Downstream_PacketProcessor_Interface_ReplyNotifyDevice(DownstreamPacketTypeDef* replyPacket)
|
||||
{
|
||||
replyPacket->Length16 = DOWNSTREAM_PACKET_HEADER_LEN_16 + 1;
|
||||
replyPacket->CommandClass = COMMAND_CLASS_INTERFACE;
|
||||
replyPacket->Command = COMMAND_INTERFACE_NOTIFY_DEVICE;
|
||||
replyPacket->Data[0] = ConfiguredDeviceClass;
|
||||
|
||||
if (Downstream_TransmitPacket(replyPacket) == HAL_OK)
|
||||
{
|
||||
DownstreamState = STATE_ACTIVE;
|
||||
Downstream_ReceivePacket(Downstream_PacketProcessor);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Downstream_PacketProcessor_GenericErrorReply(DownstreamPacketTypeDef* replyPacket)
|
||||
{
|
||||
replyPacket->Length16 = DOWNSTREAM_PACKET_HEADER_LEN_16;
|
||||
replyPacket->CommandClass = COMMAND_CLASS_ERROR;
|
||||
replyPacket->Command = COMMAND_ERROR_GENERIC;
|
||||
|
||||
Downstream_TransmitPacket(replyPacket);
|
||||
Downstream_ReceivePacket(Downstream_PacketProcessor);
|
||||
NotifyDisconnectReply = 0;
|
||||
}
|
||||
|
||||
|
||||
void Downstream_PacketProcessor_ClassReply(DownstreamPacketTypeDef* replyPacket)
|
||||
{
|
||||
Downstream_TransmitPacket(replyPacket);
|
||||
Downstream_ReceivePacket(Downstream_PacketProcessor);
|
||||
NotifyDisconnectReply = 0;
|
||||
}
|
||||
|
||||
|
||||
void Downstream_PacketProcessor_NotifyDisconnectReplyRequired(void)
|
||||
{
|
||||
NotifyDisconnectReply = 1;
|
||||
}
|
||||
|
||||
|
||||
void Downstream_PacketProcessor_CheckNotifyDisconnectReply(void)
|
||||
{
|
||||
if (NotifyDisconnectReply == 2)
|
||||
{
|
||||
Downstream_GetFreePacket(Downstream_PacketProcessor_NotifyDisconnectReply);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Downstream_PacketProcessor_NotifyDisconnectReply(DownstreamPacketTypeDef* packetToSend)
|
||||
{
|
||||
packetToSend->Length16 = DOWNSTREAM_PACKET_HEADER_LEN_16;
|
||||
packetToSend->CommandClass = COMMAND_CLASS_ERROR;
|
||||
packetToSend->Command = COMMAND_ERROR_DEVICE_DISCONNECTED;
|
||||
Downstream_PacketProcessor_ClassReply(packetToSend);
|
||||
}
|
||||
|
||||
|
||||
//This callback receives various event ids from the host stack,
|
||||
//either at INT_PRIORITY_OTG_FS or from main().
|
||||
void Downstream_HostUserCallback(USBH_HandleTypeDef *phost, uint8_t id)
|
||||
{
|
||||
InterfaceCommandClassTypeDef newActiveClass = COMMAND_CLASS_INTERFACE;
|
||||
|
||||
if (DownstreamState >= STATE_ERROR)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
//Called from USB interrupt.
|
||||
//Simple function shouldn't need to worry about preempting anything important.
|
||||
if (id == HOST_USER_DISCONNECTION)
|
||||
{
|
||||
DownstreamState = STATE_DEVICE_NOT_READY;
|
||||
if (NotifyDisconnectReply == 1)
|
||||
{
|
||||
NotifyDisconnectReply = 2; //Request a 'device disconnected' reply when we get back to main()
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
//Called from main()
|
||||
if (id == HOST_USER_CLASS_ACTIVE)
|
||||
{
|
||||
#ifdef CONFIG_USB_ID_ENABLED
|
||||
//check vendor product id
|
||||
for(int i=0;i<USB_ID_COUNT;i++){
|
||||
if(list[i].vendor==phost->device.DevDesc.idVendor && list[i].product==phost->device.DevDesc.idProduct){
|
||||
break;
|
||||
}else{
|
||||
if(i==(USB_ID_COUNT-1)){//last usb device in list
|
||||
DOWNSTREAM_STATEMACHINE_FREAKOUT;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
switch (phost->pActiveClass->ClassCode)
|
||||
{
|
||||
#ifdef CONFIG_MASS_STORAGE_ENABLED
|
||||
case USB_MSC_CLASS:
|
||||
newActiveClass = Downstream_MSC_ApproveConnectedDevice();
|
||||
break;
|
||||
#endif
|
||||
#if defined (CONFIG_KEYBOARD_ENABLED) || defined (CONFIG_MOUSE_ENABLED)
|
||||
case USB_HID_CLASS:
|
||||
newActiveClass = Downstream_HID_ApproveConnectedDevice();
|
||||
break;
|
||||
#endif
|
||||
|
||||
//Add other classes here...
|
||||
|
||||
|
||||
}
|
||||
|
||||
//Unsupported device classes will cause a slow fault flash.
|
||||
//This is distinct from the fast freakout flash caused by internal errors or attacks.
|
||||
//We consider supported classes that fail their approval checks to also be unsupported devices.
|
||||
if (newActiveClass == COMMAND_CLASS_INTERFACE)
|
||||
{
|
||||
USB_Host_Disconnect();
|
||||
LED_SetState(LED_STATUS_FLASH_UNSUPPORTED);
|
||||
DownstreamState = STATE_ERROR;
|
||||
return;
|
||||
}
|
||||
|
||||
//If we already configured a device class, we cannot change to a different one without rebooting.
|
||||
//This blocks 'hidden device' BadUSB attacks.
|
||||
if ((ConfiguredDeviceClass != COMMAND_CLASS_INTERFACE) &&
|
||||
(ConfiguredDeviceClass != newActiveClass))
|
||||
{
|
||||
DOWNSTREAM_STATEMACHINE_FREAKOUT;
|
||||
return;
|
||||
}
|
||||
ConfiguredDeviceClass = newActiveClass;
|
||||
|
||||
if (DownstreamState == STATE_WAIT_DEVICE_READY)
|
||||
{
|
||||
Downstream_GetFreePacket(Downstream_PacketProcessor_Interface_ReplyNotifyDevice);
|
||||
return;
|
||||
}
|
||||
|
||||
if (DownstreamState == STATE_DEVICE_NOT_READY)
|
||||
{
|
||||
DownstreamState = STATE_DEVICE_READY;
|
||||
return;
|
||||
}
|
||||
|
||||
DOWNSTREAM_STATEMACHINE_FREAKOUT;
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
//Called from main():
|
||||
if ((id == HOST_USER_CLASS_FAILED) ||
|
||||
(id == HOST_USER_UNRECOVERED_ERROR)) //Probably due to a crappy device that won't enumerate!
|
||||
{
|
||||
//Unsupported device classes will cause a slow fault flash.
|
||||
//This is distinct from the fast freakout flash caused by internal errors or attacks.
|
||||
USB_Host_Disconnect();
|
||||
LED_SetState(LED_STATUS_FLASH_UNSUPPORTED);
|
||||
DownstreamState = STATE_ERROR;
|
||||
return;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -0,0 +1,163 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* File Name : stm32f4xx_hal_msp.c
|
||||
* Description : This file provides code for the MSP Initialization
|
||||
* and de-Initialization codes.
|
||||
******************************************************************************
|
||||
*
|
||||
* COPYRIGHT(c) 2015 STMicroelectronics
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* 2. 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.
|
||||
* 3. Neither the name of STMicroelectronics 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.
|
||||
*
|
||||
******************************************************************************
|
||||
*
|
||||
* Modifications by Robert Fisk
|
||||
*/
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include "stm32f4xx_hal.h"
|
||||
#include "interrupts.h"
|
||||
#include "board_config.h"
|
||||
|
||||
|
||||
DMA_HandleTypeDef hdma_spi1_rx;
|
||||
DMA_HandleTypeDef hdma_spi1_tx;
|
||||
|
||||
|
||||
|
||||
void HAL_MspInit(void)
|
||||
{
|
||||
|
||||
HAL_NVIC_SetPriority(SysTick_IRQn, INT_PRIORITY_SYSTICK, 0);
|
||||
}
|
||||
|
||||
|
||||
uint32_t HAL_GetHSECrystalFreqMHz(void)
|
||||
{
|
||||
if ((BOARD_REV_ID_PORT->IDR & BOARD_REV_PIN_MASK) < BOARD_REV_1_0_BETA_3)
|
||||
{
|
||||
return BOARD_REV_1_0_BETA_FREQ;
|
||||
}
|
||||
else
|
||||
{
|
||||
return BOARD_REV_1_0_BETA_3_FREQ;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void HAL_SPI_MspInit(SPI_HandleTypeDef* hspi)
|
||||
{
|
||||
GPIO_InitTypeDef GPIO_InitStruct;
|
||||
|
||||
if(hspi->Instance==SPI1)
|
||||
{
|
||||
__SPI1_CLK_ENABLE();
|
||||
__DMA2_CLK_ENABLE();
|
||||
|
||||
/**SPI1 GPIO Configuration
|
||||
PA4 ------> SPI_NSS
|
||||
PA5 ------> SPI1_SCK
|
||||
PA6 ------> SPI1_MISO
|
||||
PA7 ------> SPI1_MOSI
|
||||
*/
|
||||
GPIO_InitStruct.Pin = GPIO_PIN_4; //NSS is active low so pull up
|
||||
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
|
||||
GPIO_InitStruct.Pull = GPIO_PULLUP;
|
||||
GPIO_InitStruct.Speed = GPIO_SPEED_MEDIUM;
|
||||
GPIO_InitStruct.Alternate = GPIO_AF5_SPI1;
|
||||
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
|
||||
|
||||
GPIO_InitStruct.Pin = GPIO_PIN_5|GPIO_PIN_6|GPIO_PIN_7; //SCK & data are active high so pull down
|
||||
GPIO_InitStruct.Pull = GPIO_PULLDOWN;
|
||||
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
|
||||
|
||||
UPSTREAM_TX_REQUEST_DEASSERT;
|
||||
GPIO_InitStruct.Pin = UPSTREAM_TX_REQUEST_PIN;
|
||||
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
|
||||
GPIO_InitStruct.Pull = GPIO_NOPULL;
|
||||
HAL_GPIO_Init(UPSTREAM_TX_REQUEST_PORT, &GPIO_InitStruct);
|
||||
|
||||
/* Peripheral DMA init*/
|
||||
hdma_spi1_rx.Instance = DMA2_Stream2;
|
||||
hdma_spi1_rx.Init.Channel = DMA_CHANNEL_3;
|
||||
hdma_spi1_rx.Init.Direction = DMA_PERIPH_TO_MEMORY;
|
||||
hdma_spi1_rx.Init.PeriphInc = DMA_PINC_DISABLE;
|
||||
hdma_spi1_rx.Init.MemInc = DMA_MINC_ENABLE;
|
||||
hdma_spi1_rx.Init.PeriphDataAlignment = DMA_PDATAALIGN_HALFWORD;
|
||||
hdma_spi1_rx.Init.MemDataAlignment = DMA_MDATAALIGN_HALFWORD;
|
||||
hdma_spi1_rx.Init.Mode = DMA_NORMAL;
|
||||
hdma_spi1_rx.Init.Priority = DMA_PRIORITY_MEDIUM;
|
||||
hdma_spi1_rx.Init.FIFOMode = DMA_FIFOMODE_DISABLE;
|
||||
HAL_DMA_Init(&hdma_spi1_rx);
|
||||
__HAL_LINKDMA(hspi,hdmarx,hdma_spi1_rx);
|
||||
|
||||
hdma_spi1_tx.Instance = DMA2_Stream3;
|
||||
hdma_spi1_tx.Init.Channel = DMA_CHANNEL_3;
|
||||
hdma_spi1_tx.Init.Direction = DMA_MEMORY_TO_PERIPH;
|
||||
hdma_spi1_tx.Init.PeriphInc = DMA_PINC_DISABLE;
|
||||
hdma_spi1_tx.Init.MemInc = DMA_MINC_ENABLE;
|
||||
hdma_spi1_tx.Init.PeriphDataAlignment = DMA_PDATAALIGN_HALFWORD;
|
||||
hdma_spi1_tx.Init.MemDataAlignment = DMA_MDATAALIGN_HALFWORD;
|
||||
hdma_spi1_tx.Init.Mode = DMA_NORMAL;
|
||||
hdma_spi1_tx.Init.Priority = DMA_PRIORITY_MEDIUM;
|
||||
hdma_spi1_tx.Init.FIFOMode = DMA_FIFOMODE_DISABLE;
|
||||
HAL_DMA_Init(&hdma_spi1_tx);
|
||||
__HAL_LINKDMA(hspi,hdmatx,hdma_spi1_tx);
|
||||
|
||||
/* DMA interrupt init */
|
||||
HAL_NVIC_SetPriority(DMA2_Stream2_IRQn, INT_PRIORITY_SPI_DMA, 0);
|
||||
HAL_NVIC_EnableIRQ(DMA2_Stream2_IRQn);
|
||||
HAL_NVIC_SetPriority(DMA2_Stream3_IRQn, INT_PRIORITY_SPI_DMA, 0);
|
||||
HAL_NVIC_EnableIRQ(DMA2_Stream3_IRQn);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void HAL_SPI_MspDeInit(SPI_HandleTypeDef* hspi)
|
||||
{
|
||||
|
||||
if(hspi->Instance==SPI1)
|
||||
{
|
||||
__SPI1_CLK_DISABLE();
|
||||
|
||||
/**SPI1 GPIO Configuration
|
||||
PA5 ------> SPI1_SCK
|
||||
PA6 ------> SPI1_MISO
|
||||
PA7 ------> SPI1_MOSI
|
||||
*/
|
||||
HAL_GPIO_DeInit(GPIOA, GPIO_PIN_5|GPIO_PIN_6|GPIO_PIN_7);
|
||||
|
||||
/* Peripheral DMA DeInit*/
|
||||
HAL_DMA_DeInit(hspi->hdmarx);
|
||||
HAL_DMA_DeInit(hspi->hdmatx);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
|
@ -0,0 +1,117 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file stm32f4xx_it.c
|
||||
* @brief Interrupt Service Routines.
|
||||
******************************************************************************
|
||||
*
|
||||
* COPYRIGHT(c) 2015 STMicroelectronics
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* 2. 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.
|
||||
* 3. Neither the name of STMicroelectronics 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.
|
||||
*
|
||||
******************************************************************************
|
||||
*
|
||||
* Modifications by Robert Fisk
|
||||
*/
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include "stm32f4xx_hal.h"
|
||||
#include "stm32f4xx.h"
|
||||
#include "interrupts.h"
|
||||
#include "led.h"
|
||||
#include "board_config.h"
|
||||
|
||||
|
||||
/* External variables --------------------------------------------------------*/
|
||||
extern HCD_HandleTypeDef hhcd_USB_OTG_FS;
|
||||
extern DMA_HandleTypeDef hdma_spi1_rx;
|
||||
extern DMA_HandleTypeDef hdma_spi1_tx;
|
||||
|
||||
extern volatile uint8_t UsbInterruptHasHappened;
|
||||
|
||||
uint8_t BusFaultAllowed = 0;
|
||||
|
||||
|
||||
/******************************************************************************/
|
||||
/* Cortex-M4 Processor Interruption and Exception Handlers */
|
||||
/******************************************************************************/
|
||||
|
||||
/**
|
||||
* @brief This function handles System tick timer.
|
||||
*/
|
||||
void SysTick_Handler(void)
|
||||
{
|
||||
HAL_IncTick();
|
||||
LED_Tick();
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
/* STM32F4xx Peripheral Interrupt Handlers */
|
||||
/* Add here the Interrupt Handlers for the used peripherals. */
|
||||
/* For the available peripheral interrupt handler names, */
|
||||
/* please refer to the startup file (startup_stm32f4xx.s). */
|
||||
/******************************************************************************/
|
||||
|
||||
|
||||
|
||||
void DMA2_Stream2_IRQHandler(void)
|
||||
{
|
||||
HAL_DMA_IRQHandler(&hdma_spi1_rx);
|
||||
}
|
||||
|
||||
void DMA2_Stream3_IRQHandler(void)
|
||||
{
|
||||
HAL_DMA_IRQHandler(&hdma_spi1_tx);
|
||||
}
|
||||
|
||||
void OTG_FS_IRQHandler(void)
|
||||
{
|
||||
HAL_HCD_IRQHandler(&hhcd_USB_OTG_FS);
|
||||
UsbInterruptHasHappened = 1;
|
||||
}
|
||||
|
||||
|
||||
//This weird stuff is required when disabling flash writes.
|
||||
//The deliberate flash lockout will cause a bus fault that we need to process.
|
||||
void EnableOneBusFault(void)
|
||||
{
|
||||
//It should not be enabled already!
|
||||
if (BusFaultAllowed)
|
||||
{
|
||||
while (1);
|
||||
}
|
||||
SCB->SHCSR = SCB_SHCSR_BUSFAULTENA_Msk;
|
||||
BusFaultAllowed = 1;
|
||||
}
|
||||
|
||||
void BusFault_Handler(void)
|
||||
{
|
||||
if (BusFaultAllowed)
|
||||
{
|
||||
BusFaultAllowed = 0;
|
||||
return;
|
||||
}
|
||||
while (1);
|
||||
}
|
||||
|
||||
|
||||
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
|
@ -0,0 +1,142 @@
|
||||
/*
|
||||
* led.c
|
||||
*
|
||||
* Created on: 19/08/2015
|
||||
* Author: Robert Fisk
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
|
||||
#include "led.h"
|
||||
#include "board_config.h"
|
||||
#include "build_config.h"
|
||||
|
||||
uint32_t FaultLedCounter;
|
||||
uint32_t ReadWriteFlashEndTime;
|
||||
|
||||
LedStatusTypeDef FaultLedState;
|
||||
uint16_t FaultLedOnMs;
|
||||
uint16_t FaultLedOffMs;
|
||||
uint8_t FaultLedBlinkCount;
|
||||
|
||||
uint8_t FaultLedBlinkCountState;
|
||||
uint8_t FaultLedOutputState;
|
||||
|
||||
|
||||
void LED_Init(void)
|
||||
{
|
||||
FAULT_LED_ON;
|
||||
ReadWriteFlashEndTime = 0;
|
||||
FaultLedState = LED_STATUS_STARTUP;
|
||||
}
|
||||
|
||||
|
||||
void LED_SetState(LedStatusTypeDef newState)
|
||||
{
|
||||
switch (newState)
|
||||
{
|
||||
case LED_STATUS_OFF:
|
||||
FaultLedCounter = UINT32_MAX;
|
||||
FaultLedBlinkCountState = 0;
|
||||
FaultLedOutputState = 0;
|
||||
FAULT_LED_OFF;
|
||||
break;
|
||||
|
||||
case LED_STATUS_FLASH_UNSUPPORTED:
|
||||
FaultLedOnMs = LED_UNSUPPORTED_BLINK_MS;
|
||||
FaultLedOffMs = LED_UNSUPPORTED_BLINK_MS;
|
||||
FaultLedBlinkCount = 1;
|
||||
break;
|
||||
|
||||
case LED_STATUS_FLASH_BOTDETECT:
|
||||
FaultLedOnMs = LED_BOTDETECT_ON_MS;
|
||||
FaultLedOffMs = LED_BOTDETECT_OFF_MS;
|
||||
FaultLedBlinkCount = 2;
|
||||
break;
|
||||
|
||||
case LED_STATUS_FLASH_READWRITE:
|
||||
#ifdef CONFIG_READ_FLASH_TIME_MS
|
||||
if (FaultLedState == LED_STATUS_OFF)
|
||||
{
|
||||
FaultLedOnMs = LED_READWRITE_ON_MS;
|
||||
FaultLedOffMs = LED_READWRITE_OFF_MS;
|
||||
FaultLedBlinkCount = 1;
|
||||
ReadWriteFlashEndTime = HAL_GetTick() + CONFIG_READ_FLASH_TIME_MS;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
newState = FaultLedState; //Don't override other active states
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
FaultLedOnMs = LED_ERROR_BLINK_MS; //Everything else is LED_STATUS_ERROR
|
||||
FaultLedOffMs = LED_ERROR_BLINK_MS;
|
||||
FaultLedBlinkCount = 1;
|
||||
}
|
||||
|
||||
FaultLedState = newState;
|
||||
}
|
||||
|
||||
|
||||
void LED_Tick(void)
|
||||
{
|
||||
if (FaultLedState == LED_STATUS_OFF) return;
|
||||
|
||||
if (FaultLedState == LED_STATUS_STARTUP)
|
||||
{
|
||||
if (HAL_GetTick() >= STARTUP_FLASH_DELAY_MS)
|
||||
{
|
||||
LED_SetState(LED_STATUS_OFF);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_READ_FLASH_TIME_MS
|
||||
if (FaultLedState == LED_STATUS_FLASH_READWRITE)
|
||||
{
|
||||
if ((int32_t)(HAL_GetTick() - ReadWriteFlashEndTime) > 0)
|
||||
{
|
||||
LED_SetState(LED_STATUS_OFF);
|
||||
return;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if (FaultLedOutputState)
|
||||
{
|
||||
if (FaultLedCounter++ >= FaultLedOnMs) //Check to turn LED off
|
||||
{
|
||||
FaultLedBlinkCountState++;
|
||||
FaultLedCounter = 0;
|
||||
FaultLedOutputState = 0;
|
||||
FAULT_LED_OFF;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (FaultLedBlinkCountState >= FaultLedBlinkCount) //Checks to turn LED on...
|
||||
{
|
||||
if (FaultLedCounter++ >= FaultLedOffMs) //Last flash may have longer off-time
|
||||
{
|
||||
FaultLedBlinkCountState = 0;
|
||||
FaultLedCounter = 0;
|
||||
FaultLedOutputState = 1;
|
||||
FAULT_LED_ON;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (FaultLedCounter++ >= FaultLedOnMs) //Flash sequence uses on-time as intermediate off-time
|
||||
{
|
||||
FaultLedCounter = 0;
|
||||
FaultLedOutputState = 1;
|
||||
FAULT_LED_ON;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,286 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* File Name : main.c
|
||||
* Description : Main program body
|
||||
******************************************************************************
|
||||
*
|
||||
* COPYRIGHT(c) 2015 STMicroelectronics
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* 2. 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.
|
||||
* 3. Neither the name of STMicroelectronics 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.
|
||||
*
|
||||
******************************************************************************
|
||||
*
|
||||
* Modifications by Robert Fisk
|
||||
*/
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include "stm32f4xx_hal.h"
|
||||
#include "usb_host.h"
|
||||
#include "board_config.h"
|
||||
#include "downstream_statemachine.h"
|
||||
#include "downstream_spi.h"
|
||||
#include "led.h"
|
||||
#include "interrupts.h"
|
||||
#include "build_config.h"
|
||||
|
||||
|
||||
|
||||
/* Private function prototypes -----------------------------------------------*/
|
||||
static void SystemClock_Config(void);
|
||||
static void GPIO_Init(void);
|
||||
static void DisableFlashWrites(void);
|
||||
static void CheckFirmwareMatchesHardware(void);
|
||||
static void SetRDPlevel(void);
|
||||
|
||||
FLASH_OBProgramInitTypeDef flash_OBinit;
|
||||
|
||||
volatile uint8_t UsbInterruptHasHappened = 0;
|
||||
uint8_t IterationCount = 0;
|
||||
|
||||
|
||||
int main(void)
|
||||
{
|
||||
//First things first!
|
||||
// DisableFlashWrites();
|
||||
CheckFirmwareMatchesHardware();
|
||||
|
||||
/* Reset of all peripherals, Initializes the Flash interface and the Systick. */
|
||||
HAL_Init();
|
||||
|
||||
#ifdef CONFIG_FLASH_RDP_ENABLE
|
||||
SetRDPlevel();
|
||||
#endif
|
||||
|
||||
/* Configure the system clock */
|
||||
SystemClock_Config();
|
||||
|
||||
/* Initialize all configured peripherals */
|
||||
GPIO_Init();
|
||||
LED_Init();
|
||||
USB_Host_Init();
|
||||
|
||||
Downstream_InitStateMachine();
|
||||
|
||||
while (1)
|
||||
{
|
||||
USB_Host_Process();
|
||||
Downstream_SPIProcess();
|
||||
Downstream_PacketProcessor_CheckNotifyDisconnectReply();
|
||||
|
||||
//Count number of main loops since last USB interrupt
|
||||
if (UsbInterruptHasHappened)
|
||||
{
|
||||
UsbInterruptHasHappened = 0;
|
||||
IterationCount = 0;
|
||||
}
|
||||
|
||||
//Some USB host state transitions take 3 iterations to fully apply.
|
||||
//We'll be generous and give it 5 before sleeping.
|
||||
if (IterationCount++ > 4)
|
||||
{
|
||||
__WFI(); //sleep time!
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void SetRDPlevel(void)
|
||||
{
|
||||
HAL_FLASH_Unlock();
|
||||
HAL_FLASH_OB_Unlock();
|
||||
flash_OBinit.OptionType=OPTIONBYTE_RDP;
|
||||
flash_OBinit.RDPLevel=OB_RDP_LEVEL_1;
|
||||
HAL_FLASHEx_OBProgram(&flash_OBinit);
|
||||
HAL_FLASH_OB_Launch();
|
||||
HAL_FLASH_OB_Lock();
|
||||
HAL_FLASH_Lock();
|
||||
|
||||
}
|
||||
|
||||
void DisableFlashWrites(void)
|
||||
{
|
||||
//Disable flash writes until the next reset
|
||||
//This will cause a bus fault interrupt, so allow one now.
|
||||
EnableOneBusFault();
|
||||
FLASH->KEYR = 999;
|
||||
|
||||
//Confirm that flash cannot be unlocked
|
||||
//This unlock attempt will also cause two bus faults.
|
||||
if ((FLASH->CR & FLASH_CR_LOCK) == 0) while(1);
|
||||
EnableOneBusFault();
|
||||
FLASH->KEYR = FLASH_KEY1;
|
||||
EnableOneBusFault();
|
||||
FLASH->KEYR = FLASH_KEY2;
|
||||
if ((FLASH->CR & FLASH_CR_LOCK) == 0) while(1);
|
||||
}
|
||||
|
||||
|
||||
void CheckFirmwareMatchesHardware(void)
|
||||
{
|
||||
//Check we are running on the expected hardware:
|
||||
//STM32F401RC on USG v1.0 beta
|
||||
|
||||
GPIO_InitTypeDef GPIO_InitStruct;
|
||||
|
||||
__HAL_RCC_GPIOB_CLK_ENABLE();
|
||||
|
||||
if ((*(uint32_t*)DBGMCU_BASE & DBGMCU_IDCODE_DEV_ID) == DBGMCU_IDCODE_DEV_ID_401xB_xC)
|
||||
{
|
||||
//Read in board revision and ID on port C
|
||||
GPIO_InitStruct.Pin = BOARD_REV_PIN_MASK | BOARD_ID_PIN_MASK;
|
||||
GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
|
||||
GPIO_InitStruct.Pull = GPIO_PULLUP;
|
||||
GPIO_InitStruct.Speed = GPIO_SPEED_LOW;
|
||||
GPIO_InitStruct.Alternate = 0;
|
||||
HAL_GPIO_Init(BOARD_REV_ID_PORT, &GPIO_InitStruct);
|
||||
|
||||
//Correct board revision?
|
||||
if ((BOARD_REV_ID_PORT->IDR & BOARD_REV_PIN_MASK) <= BOARD_REV_1_0_BETA_3)
|
||||
{
|
||||
//Correct board ID: downstream?
|
||||
if (!(BOARD_REV_ID_PORT->IDR & BOARD_ID_PIN_MASK))
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//This is not the hardware we expected, so turn on our fault LED(s) and die in a heap.
|
||||
GPIO_InitStruct.Pin = FAULT_LED_PIN | H405_FAULT_LED_PIN;
|
||||
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
|
||||
GPIO_InitStruct.Pull = GPIO_NOPULL;
|
||||
HAL_GPIO_Init(FAULT_LED_PORT, &GPIO_InitStruct);
|
||||
FAULT_LED_ON;
|
||||
H405_FAULT_LED_ON;
|
||||
while (1);
|
||||
}
|
||||
|
||||
|
||||
/** System Clock Configuration
|
||||
*/
|
||||
void SystemClock_Config(void)
|
||||
{
|
||||
|
||||
RCC_OscInitTypeDef RCC_OscInitStruct;
|
||||
RCC_ClkInitTypeDef RCC_ClkInitStruct;
|
||||
|
||||
__PWR_CLK_ENABLE();
|
||||
|
||||
__HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE2);
|
||||
|
||||
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
|
||||
RCC_OscInitStruct.HSEState = RCC_HSE_ON;
|
||||
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
|
||||
RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
|
||||
RCC_OscInitStruct.PLL.PLLM = (HAL_GetHSECrystalFreqMHz() / 2); //PLL input frequency = 2MHz
|
||||
RCC_OscInitStruct.PLL.PLLN = 168;
|
||||
RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV4;
|
||||
RCC_OscInitStruct.PLL.PLLQ = 7;
|
||||
if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK) while (1);
|
||||
|
||||
RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_SYSCLK |
|
||||
RCC_CLOCKTYPE_HCLK |
|
||||
RCC_CLOCKTYPE_PCLK1 |
|
||||
RCC_CLOCKTYPE_PCLK2;
|
||||
RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
|
||||
RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
|
||||
RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV4;
|
||||
RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV2;
|
||||
if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK) while (1);
|
||||
|
||||
HAL_SYSTICK_CLKSourceConfig(SYSTICK_CLKSOURCE_HCLK);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void GPIO_Init(void)
|
||||
{
|
||||
GPIO_InitTypeDef GPIO_InitStruct;
|
||||
|
||||
|
||||
/* GPIO Ports Clock Enable */
|
||||
//__GPIOH_CLK_ENABLE();
|
||||
__HAL_RCC_GPIOA_CLK_ENABLE();
|
||||
__HAL_RCC_GPIOB_CLK_ENABLE();
|
||||
__HAL_RCC_GPIOC_CLK_ENABLE();
|
||||
__HAL_RCC_GPIOD_CLK_ENABLE();
|
||||
|
||||
//Bulk initialise all ports as inputs with pullups active,
|
||||
//excluding JTAG pins which must remain as AF0!
|
||||
GPIO_InitStruct.Pin = (GPIO_PIN_All & ~(PA_JTMS | PA_JTCK | PA_JTDI));
|
||||
GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
|
||||
GPIO_InitStruct.Pull = GPIO_PULLUP;
|
||||
GPIO_InitStruct.Speed = GPIO_SPEED_LOW;
|
||||
GPIO_InitStruct.Alternate = 0;
|
||||
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
|
||||
GPIO_InitStruct.Pin = (GPIO_PIN_All & ~(PB_JTDO | PB_NJTRST));
|
||||
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
|
||||
GPIO_InitStruct.Pin = GPIO_PIN_All;
|
||||
HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
|
||||
HAL_GPIO_Init(GPIOD, &GPIO_InitStruct);
|
||||
|
||||
//Fault LED is output
|
||||
GPIO_InitStruct.Pin = FAULT_LED_PIN;
|
||||
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
|
||||
GPIO_InitStruct.Pull = GPIO_NOPULL;
|
||||
HAL_GPIO_Init(FAULT_LED_PORT, &GPIO_InitStruct);
|
||||
FAULT_LED_OFF;
|
||||
|
||||
// //SPI_INT_ACTIVE indicator
|
||||
// GPIO_InitStruct.Pin = INT_ACTIVE_PIN;
|
||||
// HAL_GPIO_Init(INT_ACTIVE_PORT, &GPIO_InitStruct);
|
||||
// INT_ACTIVE_OFF;
|
||||
}
|
||||
|
||||
|
||||
|
||||
#ifdef USE_FULL_ASSERT
|
||||
|
||||
/**
|
||||
* @brief Reports the name of the source file and the source line number
|
||||
* where the assert_param error has occurred.
|
||||
* @param file: pointer to the source file name
|
||||
* @param line: assert_param error line source number
|
||||
* @retval None
|
||||
*/
|
||||
void assert_failed(uint8_t* file, uint32_t line)
|
||||
{
|
||||
/* USER CODE BEGIN 6 */
|
||||
/* User can add his own implementation to report the file name and line number,
|
||||
ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
|
||||
/* USER CODE END 6 */
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
|
@ -0,0 +1,88 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file : USB_HOST
|
||||
* @version : v1.0_Cube
|
||||
* @brief : This file implements the USB Host
|
||||
******************************************************************************
|
||||
* COPYRIGHT(c) 2015 STMicroelectronics
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* 2. 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.
|
||||
* 3. Neither the name of STMicroelectronics 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.
|
||||
*
|
||||
******************************************************************************
|
||||
*
|
||||
* Modifications by Robert Fisk
|
||||
*/
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
|
||||
#include "usb_host.h"
|
||||
#include "usbh_core.h"
|
||||
#include "usbh_msc.h"
|
||||
#include "usbh_hid.h"
|
||||
#include "downstream_statemachine.h"
|
||||
#include "build_config.h"
|
||||
|
||||
|
||||
/* USB Host Core handle declaration */
|
||||
USBH_HandleTypeDef hUsbHostFS;
|
||||
|
||||
|
||||
/* init function */
|
||||
void USB_Host_Init(void)
|
||||
{
|
||||
/* Init Host Library,Add Supported Class and Start the library*/
|
||||
USBH_Init(&hUsbHostFS, Downstream_HostUserCallback, HOST_FS);
|
||||
|
||||
#ifdef CONFIG_MASS_STORAGE_ENABLED
|
||||
USBH_RegisterClass(&hUsbHostFS, USBH_MSC_CLASS);
|
||||
#endif
|
||||
#if defined (CONFIG_KEYBOARD_ENABLED) || defined (CONFIG_MOUSE_ENABLED)
|
||||
USBH_RegisterClass(&hUsbHostFS, USBH_HID_CLASS);
|
||||
#endif
|
||||
|
||||
USBH_Start(&hUsbHostFS);
|
||||
}
|
||||
|
||||
/*
|
||||
* Background task
|
||||
*/
|
||||
void USB_Host_Process()
|
||||
{
|
||||
/* USB Host Background task */
|
||||
USBH_Process(&hUsbHostFS);
|
||||
|
||||
}
|
||||
|
||||
|
||||
//Called when Downstream Statemachine or SPI freaks out.
|
||||
void USB_Host_Disconnect()
|
||||
{
|
||||
USBH_DeInit(&hUsbHostFS);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
|
@ -0,0 +1,470 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file : usbh_conf.c
|
||||
* @version : v1.0_Cube
|
||||
* @brief : This file implements the board support package for the USB host library
|
||||
******************************************************************************
|
||||
* COPYRIGHT(c) 2015 STMicroelectronics
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* 2. 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.
|
||||
* 3. Neither the name of STMicroelectronics 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.
|
||||
*
|
||||
******************************************************************************
|
||||
*
|
||||
* Modifications by Robert Fisk
|
||||
*/
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include "usbh_core.h"
|
||||
#include "interrupts.h"
|
||||
|
||||
|
||||
HCD_HandleTypeDef hhcd_USB_OTG_FS;
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
LL Driver Callbacks (HCD -> USB Host Library)
|
||||
*******************************************************************************/
|
||||
/* MSP Init */
|
||||
|
||||
void HAL_HCD_MspInit(HCD_HandleTypeDef* hhcd)
|
||||
{
|
||||
GPIO_InitTypeDef GPIO_InitStruct;
|
||||
|
||||
if(hhcd->Instance==USB_OTG_FS)
|
||||
{
|
||||
/**USB_OTG_FS GPIO Configuration
|
||||
PA11 ------> USB_OTG_FS_DM
|
||||
PA12 ------> USB_OTG_FS_DP
|
||||
*/
|
||||
GPIO_InitStruct.Pin = GPIO_PIN_11|GPIO_PIN_12;
|
||||
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
|
||||
GPIO_InitStruct.Pull = GPIO_NOPULL;
|
||||
GPIO_InitStruct.Speed = GPIO_SPEED_HIGH;
|
||||
GPIO_InitStruct.Alternate = GPIO_AF10_OTG_FS;
|
||||
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
|
||||
|
||||
/* Peripheral clock enable */
|
||||
__USB_OTG_FS_CLK_ENABLE();
|
||||
|
||||
/* Peripheral interrupt init*/
|
||||
HAL_NVIC_SetPriority(OTG_FS_IRQn, INT_PRIORITY_USB, 0);
|
||||
HAL_NVIC_EnableIRQ(OTG_FS_IRQn);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void HAL_HCD_MspDeInit(HCD_HandleTypeDef* hhcd)
|
||||
{
|
||||
if(hhcd->Instance==USB_OTG_FS)
|
||||
{
|
||||
/* Peripheral clock disable */
|
||||
__USB_OTG_FS_CLK_DISABLE();
|
||||
|
||||
/**USB_OTG_FS GPIO Configuration
|
||||
PA9 ------> USB_OTG_FS_VBUS
|
||||
PA11 ------> USB_OTG_FS_DM
|
||||
PA12 ------> USB_OTG_FS_DP
|
||||
*/
|
||||
//HAL_GPIO_DeInit(GPIOA, GPIO_PIN_11|GPIO_PIN_12);
|
||||
|
||||
/* Peripheral interrupt Deinit*/
|
||||
HAL_NVIC_DisableIRQ(OTG_FS_IRQn);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief SOF callback.
|
||||
* @param hhcd: HCD handle
|
||||
* @retval None
|
||||
*/
|
||||
void HAL_HCD_SOF_Callback(HCD_HandleTypeDef *hhcd)
|
||||
{
|
||||
USBH_LL_IncTimer (hhcd->pData);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief SOF callback.
|
||||
* @param hhcd: HCD handle
|
||||
* @retval None
|
||||
*/
|
||||
void HAL_HCD_Connect_Callback(HCD_HandleTypeDef *hhcd)
|
||||
{
|
||||
USBH_LL_Connect(hhcd->pData);
|
||||
}
|
||||
|
||||
|
||||
void HAL_HCD_PortEnabled_Callback(HCD_HandleTypeDef *hhcd)
|
||||
{
|
||||
USBH_LL_PortEnabled(hhcd->pData);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief SOF callback.
|
||||
* @param hhcd: HCD handle
|
||||
* @retval None
|
||||
*/
|
||||
HAL_StatusTypeDef HAL_HCD_Disconnect_Callback(HCD_HandleTypeDef *hhcd)
|
||||
{
|
||||
if (USBH_LL_Disconnect(hhcd->pData) == USBH_OK)
|
||||
{
|
||||
return HAL_OK;
|
||||
}
|
||||
return HAL_ERROR;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Notify URB state change callback.
|
||||
* @param hhcd: HCD handle
|
||||
* @retval None
|
||||
*/
|
||||
void HAL_HCD_HC_NotifyURBChange_Callback(HCD_HandleTypeDef *hhcd, uint8_t chnum, HCD_URBStateTypeDef urb_state)
|
||||
{
|
||||
/* To be used with OS to sync URB state with the global state machine */
|
||||
#if (USBH_USE_OS == 1)
|
||||
USBH_LL_NotifyURBChange(hhcd->pData);
|
||||
#endif
|
||||
}
|
||||
/*******************************************************************************
|
||||
LL Driver Interface (USB Host Library --> HCD)
|
||||
*******************************************************************************/
|
||||
/**
|
||||
* @brief USBH_LL_Init
|
||||
* Initialize the Low Level portion of the Host driver.
|
||||
* @param phost: Host handle
|
||||
* @retval USBH Status
|
||||
*/
|
||||
USBH_StatusTypeDef USBH_LL_Init (USBH_HandleTypeDef *phost)
|
||||
{
|
||||
/* Init USB_IP */
|
||||
if (phost->id == HOST_FS) {
|
||||
/* Link The driver to the stack */
|
||||
hhcd_USB_OTG_FS.pData = phost;
|
||||
phost->pData = &hhcd_USB_OTG_FS;
|
||||
|
||||
hhcd_USB_OTG_FS.Instance = USB_OTG_FS;
|
||||
hhcd_USB_OTG_FS.Init.Host_channels = 8;
|
||||
hhcd_USB_OTG_FS.Init.speed = HCD_SPEED_FULL;
|
||||
hhcd_USB_OTG_FS.Init.dma_enable = DISABLE;
|
||||
hhcd_USB_OTG_FS.Init.phy_itface = HCD_PHY_EMBEDDED;
|
||||
hhcd_USB_OTG_FS.Init.Sof_enable = DISABLE;
|
||||
HAL_HCD_Init(&hhcd_USB_OTG_FS);
|
||||
|
||||
USBH_LL_SetTimer (phost, HAL_HCD_GetCurrentFrame(&hhcd_USB_OTG_FS));
|
||||
}
|
||||
return USBH_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief USBH_LL_DeInit
|
||||
* De-Initialize the Low Level portion of the Host driver.
|
||||
* @param phost: Host handle
|
||||
* @retval USBH Status
|
||||
*/
|
||||
USBH_StatusTypeDef USBH_LL_DeInit (USBH_HandleTypeDef *phost)
|
||||
{
|
||||
HAL_HCD_DeInit(phost->pData);
|
||||
return USBH_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief USBH_LL_Start
|
||||
* Start the Low Level portion of the Host driver.
|
||||
* @param phost: Host handle
|
||||
* @retval USBH Status
|
||||
*/
|
||||
USBH_StatusTypeDef USBH_LL_Start(USBH_HandleTypeDef *phost)
|
||||
{
|
||||
HAL_HCD_Start(phost->pData);
|
||||
return USBH_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief USBH_LL_Stop
|
||||
* Stop the Low Level portion of the Host driver.
|
||||
* @param phost: Host handle
|
||||
* @retval USBH Status
|
||||
*/
|
||||
USBH_StatusTypeDef USBH_LL_Stop (USBH_HandleTypeDef *phost)
|
||||
{
|
||||
HAL_HCD_Stop(phost->pData);
|
||||
return USBH_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief USBH_LL_GetSpeed
|
||||
* Return the USB Host Speed from the Low Level Driver.
|
||||
* @param phost: Host handle
|
||||
* @retval USBH Speeds
|
||||
*/
|
||||
USBH_SpeedTypeDef USBH_LL_GetSpeed (USBH_HandleTypeDef *phost)
|
||||
{
|
||||
USBH_SpeedTypeDef speed = USBH_SPEED_FULL;
|
||||
|
||||
switch (HAL_HCD_GetCurrentSpeed(phost->pData))
|
||||
{
|
||||
case 0 :
|
||||
speed = USBH_SPEED_HIGH;
|
||||
break;
|
||||
|
||||
// case 1 :
|
||||
// speed = USBH_SPEED_FULL;
|
||||
// break;
|
||||
|
||||
case 2 :
|
||||
speed = USBH_SPEED_LOW;
|
||||
break;
|
||||
|
||||
// default:
|
||||
// speed = USBH_SPEED_FULL;
|
||||
// break;
|
||||
}
|
||||
return speed;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief USBH_LL_ResetPort
|
||||
* Reset the Host Port of the Low Level Driver.
|
||||
* @param phost: Host handle
|
||||
* @retval USBH Status
|
||||
*/
|
||||
USBH_StatusTypeDef USBH_LL_ResetPort (USBH_HandleTypeDef *phost)
|
||||
{
|
||||
HAL_HCD_ResetPort(phost->pData);
|
||||
return USBH_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief USBH_LL_GetLastXferSize
|
||||
* Return the last transfered packet size.
|
||||
* @param phost: Host handle
|
||||
* @param pipe: Pipe index
|
||||
* @retval Packet Size
|
||||
*/
|
||||
uint32_t USBH_LL_GetLastXferSize (USBH_HandleTypeDef *phost, uint8_t pipe)
|
||||
{
|
||||
return HAL_HCD_HC_GetXferCount(phost->pData, pipe);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief USBH_LL_OpenPipe
|
||||
* Open a pipe of the Low Level Driver.
|
||||
* @param phost: Host handle
|
||||
* @param pipe_num: Pipe index
|
||||
* @param epnum: Endpoint Number
|
||||
* @param dev_address: Device USB address
|
||||
* @param speed: Device Speed
|
||||
* @param ep_type: Endpoint Type
|
||||
* @param mps: Endpoint Max Packet Size
|
||||
* @retval USBH Status
|
||||
*/
|
||||
USBH_StatusTypeDef USBH_LL_OpenPipe (USBH_HandleTypeDef *phost,
|
||||
uint8_t pipe_num,
|
||||
uint8_t epnum,
|
||||
uint8_t dev_address,
|
||||
uint8_t speed,
|
||||
uint8_t ep_type,
|
||||
uint16_t mps)
|
||||
{
|
||||
HAL_HCD_HC_Init(phost->pData,
|
||||
pipe_num,
|
||||
epnum,
|
||||
dev_address,
|
||||
speed,
|
||||
ep_type,
|
||||
mps);
|
||||
return USBH_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief USBH_LL_ClosePipe
|
||||
* Close a pipe of the Low Level Driver.
|
||||
* @param phost: Host handle
|
||||
* @param pipe_num: Pipe index
|
||||
* @retval USBH Status
|
||||
*/
|
||||
USBH_StatusTypeDef USBH_LL_ClosePipe (USBH_HandleTypeDef *phost, uint8_t pipe)
|
||||
{
|
||||
HAL_HCD_HC_Halt(phost->pData, pipe);
|
||||
return USBH_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief USBH_LL_SubmitURB
|
||||
* Submit a new URB to the low level driver.
|
||||
* @param phost: Host handle
|
||||
* @param pipe: Pipe index
|
||||
* This parameter can be a value from 1 to 15
|
||||
* @param direction : Channel number
|
||||
* This parameter can be one of the these values:
|
||||
* 0 : Output
|
||||
* 1 : Input
|
||||
* @param ep_type : Endpoint Type
|
||||
* This parameter can be one of the these values:
|
||||
* @arg EP_TYPE_CTRL: Control type
|
||||
* @arg EP_TYPE_ISOC: Isochrounous type
|
||||
* @arg EP_TYPE_BULK: Bulk type
|
||||
* @arg EP_TYPE_INTR: Interrupt type
|
||||
* @param token : Endpoint Type
|
||||
* This parameter can be one of the these values:
|
||||
* @arg 0: PID_SETUP
|
||||
* @arg 1: PID_DATA
|
||||
* @param pbuff : pointer to URB data
|
||||
* @param length : Length of URB data
|
||||
* @param do_ping : activate do ping protocol (for high speed only)
|
||||
* This parameter can be one of the these values:
|
||||
* 0 : do ping inactive
|
||||
* 1 : do ping active
|
||||
* @retval Status
|
||||
*/
|
||||
|
||||
USBH_StatusTypeDef USBH_LL_SubmitURB (USBH_HandleTypeDef *phost,
|
||||
uint8_t pipe,
|
||||
uint8_t direction ,
|
||||
uint8_t ep_type,
|
||||
uint8_t token,
|
||||
uint8_t* pbuff,
|
||||
uint16_t length,
|
||||
uint8_t do_ping )
|
||||
{
|
||||
HAL_HCD_HC_SubmitRequest (phost->pData,
|
||||
pipe,
|
||||
direction ,
|
||||
ep_type,
|
||||
token,
|
||||
pbuff,
|
||||
length,
|
||||
do_ping);
|
||||
return USBH_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief USBH_LL_GetURBState
|
||||
* Get a URB state from the low level driver.
|
||||
* @param phost: Host handle
|
||||
* @param pipe: Pipe index
|
||||
* This parameter can be a value from 1 to 15
|
||||
* @retval URB state
|
||||
* This parameter can be one of the these values:
|
||||
* @arg URB_IDLE
|
||||
* @arg URB_DONE
|
||||
* @arg URB_NOTREADY
|
||||
* @arg URB_NYET
|
||||
* @arg URB_ERROR
|
||||
* @arg URB_STALL
|
||||
*/
|
||||
USBH_URBStateTypeDef USBH_LL_GetURBState (USBH_HandleTypeDef *phost, uint8_t pipe)
|
||||
{
|
||||
return (USBH_URBStateTypeDef)HAL_HCD_HC_GetURBState (phost->pData, pipe);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief USBH_LL_DriverVBUS
|
||||
* Drive VBUS.
|
||||
* @param phost: Host handle
|
||||
* @param state : VBUS state
|
||||
* This parameter can be one of the these values:
|
||||
* 0 : VBUS Active
|
||||
* 1 : VBUS Inactive
|
||||
* @retval Status
|
||||
*/
|
||||
USBH_StatusTypeDef USBH_LL_DriverVBUS (USBH_HandleTypeDef *phost, uint8_t state)
|
||||
{
|
||||
//Our VBUS is permanently on, so don't bother with this...
|
||||
|
||||
// if (phost->id == HOST_FS)
|
||||
// {
|
||||
// if(state == 0)
|
||||
// {
|
||||
// //VBUS off
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// //VBUS on
|
||||
// }
|
||||
// }
|
||||
// HAL_Delay(200);
|
||||
return USBH_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief USBH_LL_SetToggle
|
||||
* Set toggle for a pipe.
|
||||
* @param phost: Host handle
|
||||
* @param pipe: Pipe index
|
||||
* @param pipe_num: Pipe index
|
||||
* @param toggle: toggle (0/1)
|
||||
* @retval Status
|
||||
*/
|
||||
USBH_StatusTypeDef USBH_LL_SetToggle (USBH_HandleTypeDef *phost, uint8_t pipe, uint8_t toggle)
|
||||
{
|
||||
HCD_HandleTypeDef *pHandle;
|
||||
pHandle = phost->pData;
|
||||
|
||||
if(pHandle->hc[pipe].ep_is_in)
|
||||
{
|
||||
pHandle->hc[pipe].toggle_in = toggle;
|
||||
}
|
||||
else
|
||||
{
|
||||
pHandle->hc[pipe].toggle_out = toggle;
|
||||
}
|
||||
|
||||
return USBH_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief USBH_LL_GetToggle
|
||||
* Return the current toggle of a pipe.
|
||||
* @param phost: Host handle
|
||||
* @param pipe: Pipe index
|
||||
* @retval toggle (0/1)
|
||||
*/
|
||||
uint8_t USBH_LL_GetToggle (USBH_HandleTypeDef *phost, uint8_t pipe)
|
||||
{
|
||||
uint8_t toggle = 0;
|
||||
HCD_HandleTypeDef *pHandle;
|
||||
pHandle = phost->pData;
|
||||
|
||||
if(pHandle->hc[pipe].ep_is_in)
|
||||
{
|
||||
toggle = pHandle->hc[pipe].toggle_in;
|
||||
}
|
||||
else
|
||||
{
|
||||
toggle = pHandle->hc[pipe].toggle_out;
|
||||
}
|
||||
return toggle;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief USBH_Delay
|
||||
* Delay routine for the USB Host Library
|
||||
* @param Delay: Delay in ms
|
||||
* @retval None
|
||||
*/
|
||||
void USBH_Delay (uint32_t Delay)
|
||||
{
|
||||
HAL_Delay(Delay);
|
||||
}
|
||||
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
|
@ -0,0 +1,115 @@
|
||||
/* Linker script to configure memory regions. */
|
||||
MEMORY
|
||||
{
|
||||
FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 256K
|
||||
SRAM1 (xrw) : ORIGIN = 0x20000000, LENGTH = 64K
|
||||
|
||||
}
|
||||
|
||||
/* Library configurations */
|
||||
GROUP(libgcc.a libc.a libm.a libnosys.a)
|
||||
|
||||
/* Linker script to place sections and symbol values. Should be used together
|
||||
* with other linker script that defines memory regions FLASH and RAM.
|
||||
* It references following symbols, which must be defined in code:
|
||||
* Reset_Handler : Entry of reset handler
|
||||
*
|
||||
* It defines following symbols, which code can use without definition:
|
||||
* __exidx_start
|
||||
* __exidx_end
|
||||
* __copy_table_start__
|
||||
* __copy_table_end__
|
||||
* __zero_table_start__
|
||||
* __zero_table_end__
|
||||
* __etext
|
||||
* __data_start__
|
||||
* __preinit_array_start
|
||||
* __preinit_array_end
|
||||
* __init_array_start
|
||||
* __init_array_end
|
||||
* __fini_array_start
|
||||
* __fini_array_end
|
||||
* __data_end__
|
||||
* __bss_start__
|
||||
* __bss_end__
|
||||
* __end__
|
||||
* end
|
||||
* __HeapLimit
|
||||
* __StackLimit
|
||||
* __StackTop
|
||||
* __stack
|
||||
* __Vectors_End
|
||||
* __Vectors_Size
|
||||
*/
|
||||
ENTRY(Reset_Handler)
|
||||
|
||||
SECTIONS
|
||||
{
|
||||
.text :
|
||||
{
|
||||
KEEP(*(.vectors))
|
||||
__Vectors_End = .;
|
||||
__Vectors_Size = __Vectors_End - __Vectors;
|
||||
__end__ = .;
|
||||
|
||||
*(.text*)
|
||||
|
||||
KEEP(*(.init))
|
||||
KEEP(*(.fini))
|
||||
|
||||
|
||||
*(.rodata*)
|
||||
|
||||
KEEP(*(.eh_frame*))
|
||||
} > FLASH
|
||||
|
||||
__etext = .;
|
||||
|
||||
.data : AT (__etext)
|
||||
{
|
||||
__data_start__ = .;
|
||||
*(vtable)
|
||||
*(.data*)
|
||||
|
||||
/* All data end */
|
||||
__data_end__ = .;
|
||||
|
||||
} > SRAM1
|
||||
|
||||
.bss :
|
||||
{
|
||||
. = ALIGN(4);
|
||||
__bss_start__ = .;
|
||||
*(.bss*)
|
||||
*(COMMON)
|
||||
. = ALIGN(4);
|
||||
__bss_end__ = .;
|
||||
} > SRAM1
|
||||
|
||||
.heap (COPY):
|
||||
{
|
||||
__HeapBase = .;
|
||||
__end__ = .;
|
||||
end = __end__;
|
||||
KEEP(*(.heap*))
|
||||
__HeapLimit = .;
|
||||
} > SRAM1
|
||||
|
||||
/* .stack_dummy section doesn't contains any symbols. It is only
|
||||
* used for linker to calculate size of stack sections, and assign
|
||||
* values to stack symbols later */
|
||||
.stack_dummy (COPY):
|
||||
{
|
||||
KEEP(*(.stack*))
|
||||
} > SRAM1
|
||||
|
||||
/* Set stack top to end of RAM, and stack limit move down by
|
||||
* size of stack_dummy section */
|
||||
__StackTop = ORIGIN(SRAM1) + LENGTH(SRAM1);
|
||||
__StackLimit = __StackTop - SIZEOF(.stack_dummy);
|
||||
PROVIDE(__stack = __StackTop);
|
||||
|
||||
/* Check if data + heap + stack exceeds RAM limit */
|
||||
ASSERT(__StackLimit >= __HeapLimit, "region RAM overflowed with stack")
|
||||
|
||||
}
|
Loading…
Reference in new issue