move things around and add efm8 and efm32 builds

This commit is contained in:
Conor Patrick
2018-06-27 21:39:19 -04:00
parent e446e29318
commit fb9a592d50
84 changed files with 22289 additions and 419 deletions

188
efm8/.cproject Normal file
View File

@@ -0,0 +1,188 @@
<?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="com.silabs.ss.tool.ide.c8051.toolchain.keil.cdt.debug#com.silabs.ss.tool.ide.c8051.toolchain.keil.cdt:9.53.0">
<storageModule buildSystemId="org.eclipse.cdt.managedbuilder.core.configurationDataProvider" id="com.silabs.ss.tool.ide.c8051.toolchain.keil.cdt.debug#com.silabs.ss.tool.ide.c8051.toolchain.keil.cdt:9.53.0" moduleId="org.eclipse.cdt.core.settings" name="Keil 8051 v9.53 - Debug">
<macros>
<stringMacro name="StudioSdkPath" type="VALUE_PATH_DIR" value="${StudioSdkPathFromID:com.silabs.sdk.8051:4.1.1._-963069327}"/>
<stringMacro name="StudioToolchainPath" type="VALUE_PATH_DIR" value="${StudioToolchainPathFromID:com.silabs.ss.tool.ide.c8051.toolchain.keil.cdt:9.53.0}"/>
</macros>
<externalSettings/>
<extensions>
<extension id="com.silabs.ss.framework.debugger.core.HEX" point="org.eclipse.cdt.core.BinaryParser"/>
<extension id="com.silabs.ss.tool.ide.c8051.debug.OMF2" point="org.eclipse.cdt.core.BinaryParser"/>
<extension id="com.silabs.ss.framework.debugger.core.EBL" point="org.eclipse.cdt.core.BinaryParser"/>
<extension id="com.silabs.ss.framework.debugger.core.GBL" point="org.eclipse.cdt.core.BinaryParser"/>
<extension id="com.silabs.ss.tool.ide.c8051.debug.OMF" point="org.eclipse.cdt.core.BinaryParser"/>
<extension id="com.silabs.ss.framework.debugger.core.BIN" point="org.eclipse.cdt.core.BinaryParser"/>
<extension id="com.silabs.ss.framework.debugger.core.S37" point="org.eclipse.cdt.core.BinaryParser"/>
<extension id="org.eclipse.cdt.core.GmakeErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
<extension id="com.silabs.ss.tool.ide.c8051.toolchain.keil.cdt.KeilErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
<extension id="org.eclipse.cdt.core.CWDLocator" point="org.eclipse.cdt.core.ErrorParser"/>
</extensions>
</storageModule>
<storageModule buildConfig.stockConfigId="com.silabs.ss.tool.ide.c8051.toolchain.keil.cdt.debug#com.silabs.ss.tool.ide.c8051.toolchain.keil.cdt:9.53.0" cppBuildConfig.builtinIncludes="studio:/sdk/Lib/efm8_usb/inc/ studio:/sdk/Lib/efm8_assert/ studio:/sdk/Device/EFM8UB1/peripheral_driver/inc/ studio:/sdk/Device/shared/si8051base/ studio:/sdk/Device/EFM8UB1/inc/ studio:/sdk/Lib/efm8_usbc/lib_kernel/inc/ studio:/sdk/Lib/efm8_usbc/lib_usbc_pd/inc/ studio:/sdk/Lib/efm8_usb/inc/ studio:/sdk/Lib/efm8_assert/ studio:/sdk/Device/EFM8UB1/peripheral_driver/inc/ studio:/sdk/Device/shared/si8051base/ studio:/sdk/Device/EFM8UB1/inc/ studio:/sdk/Lib/efm8_usbc/lib_kernel/inc/ studio:/sdk/Lib/efm8_usbc/lib_usbc_pd/inc/" cppBuildConfig.builtinLibraryFiles="" cppBuildConfig.builtinLibraryNames="" cppBuildConfig.builtinLibraryObjects="" cppBuildConfig.builtinLibraryPaths="" cppBuildConfig.builtinMacros="" moduleId="com.silabs.ss.framework.ide.project.core.cpp" projectCommon.boardIds="brd5000a:0.0.0.A02" projectCommon.partId="mcu.8051.efm8.ub1.efm8ub10f16g-b-qfn28" projectCommon.referencedModules="[{&quot;builtinExcludes&quot;:[],&quot;builtinSources&quot;:[&quot;lib/efm8ub1/peripheralDrivers/src/usb_0.c&quot;,&quot;lib/efm8ub1/peripheralDrivers/inc/usb_0.h&quot;],&quot;builtin&quot;:true,&quot;module&quot;:&quot;&lt;project:MModule xmlns:project=\&quot;http://www.silabs.com/ss/Project.ecore\&quot; builtin=\&quot;true\&quot; id=\&quot;com.silabs.sdk.si8051.external.efm8PeripheralDriver.usb0\&quot;/&gt;&quot;},{&quot;builtinExcludes&quot;:[],&quot;builtinSources&quot;:[&quot;lib/efm8_assert/assert.c&quot;,&quot;lib/efm8_assert/assert.h&quot;],&quot;builtin&quot;:true,&quot;module&quot;:&quot;&lt;project:MModule xmlns:project=\&quot;http://www.silabs.com/ss/Project.ecore\&quot; builtin=\&quot;true\&quot; id=\&quot;com.silabs.sdk.si8051.external.efm8Library.assert\&quot;/&gt;&quot;},{&quot;builtinExcludes&quot;:[],&quot;builtinSources&quot;:[&quot;lib/efm8_usb/inc/efm8_usb.h&quot;,&quot;lib/efm8_usb/src/efm8_usbd.c&quot;,&quot;lib/efm8_usb/src/efm8_usbdch9.c&quot;,&quot;lib/efm8_usb/src/efm8_usbdep.c&quot;,&quot;lib/efm8_usb/src/efm8_usbdint.c&quot;,&quot;lib/efm8_usb/Readme.txt&quot;],&quot;builtin&quot;:true,&quot;module&quot;:&quot;&lt;project:MModule xmlns:project=\&quot;http://www.silabs.com/ss/Project.ecore\&quot; builtin=\&quot;true\&quot; id=\&quot;com.silabs.sdk.si8051.external.efm8Library.usb\&quot;/&gt;&quot;},{&quot;builtinExcludes&quot;:[],&quot;builtinSources&quot;:[&quot;src/SILABS_STARTUP.A51&quot;],&quot;builtin&quot;:true,&quot;module&quot;:&quot;&lt;project:MModule xmlns:project=\&quot;http://www.silabs.com/ss/Project.ecore\&quot; builtin=\&quot;true\&quot; id=\&quot;com.silabs.sdk.si8051.shared\&quot;/&gt;&quot;},{&quot;builtinExcludes&quot;:[],&quot;builtinSources&quot;:[],&quot;builtin&quot;:true,&quot;module&quot;:&quot;&lt;project:MModule xmlns:project=\&quot;http://www.silabs.com/ss/Project.ecore\&quot; builtin=\&quot;true\&quot; id=\&quot;com.silabs.sdk.si8051.external.efm8Library.usbc\&quot;/&gt;&quot;}]" projectCommon.sdkId="com.silabs.sdk.8051:4.1.1._-963069327" projectCommon.toolchainId="com.silabs.ss.tool.ide.c8051.toolchain.keil.cdt:9.53.0"/>
<storageModule moduleId="cdtBuildSystem" version="4.0.0">
<configuration artifactExtension="omf" artifactName="${ProjName}" buildArtefactType="org.eclipse.cdt.build.core.buildArtefactType.exe" buildProperties="org.eclipse.cdt.build.core.buildArtefactType=org.eclipse.cdt.build.core.buildArtefactType.exe" cleanCommand="rm -rf" description="" id="com.silabs.ss.tool.ide.c8051.toolchain.keil.cdt.debug#com.silabs.ss.tool.ide.c8051.toolchain.keil.cdt:9.53.0" name="Keil 8051 v9.53 - Debug" parent="com.silabs.ide.si8051.keil.exe.default">
<folderInfo id="com.silabs.ss.tool.ide.c8051.toolchain.keil.cdt.debug#com.silabs.ss.tool.ide.c8051.toolchain.keil.cdt:9.53.0." name="/" resourcePath="">
<toolChain id="com.silabs.ide.si8051.keil.toolchain.exe.default.803196567" name="Keil 8051" superClass="com.silabs.ide.si8051.keil.toolchain.exe.default">
<option id="com.silabs.ide.si8051.keil.toolchain.category.general.debug.1285835962" name="Generate debug information" superClass="com.silabs.ide.si8051.keil.toolchain.category.general.debug" value="true" valueType="boolean"/>
<option id="com.silabs.ide.si8051.keil.toolchain.category.general.extended_assembler.1124669083" name="Use Extended Assembler (AX51) instead of A51" superClass="com.silabs.ide.si8051.keil.toolchain.category.general.extended_assembler" value="true" valueType="boolean"/>
<option id="com.silabs.ide.si8051.keil.toolchain.category.general.extended_linker.1220060828" name="Use Extended Linker (LX51) instead of BL51" superClass="com.silabs.ide.si8051.keil.toolchain.category.general.extended_linker" value="true" valueType="boolean"/>
<option id="com.silabs.ide.si8051.keil.toolchain.category.general.memory_model.923432818" name="Memory model" superClass="com.silabs.ide.si8051.keil.toolchain.category.general.memory_model" value="com.silabs.ide.si8051.keil.toolchain.category.general.memory_model.large" valueType="enumerated"/>
<targetPlatform binaryParser="com.silabs.ss.tool.ide.c8051.debug.OMF;com.silabs.ss.tool.ide.c8051.debug.OMF2;com.silabs.ss.framework.debugger.core.BIN;com.silabs.ss.framework.debugger.core.HEX;com.silabs.ss.framework.debugger.core.S37;com.silabs.ss.framework.debugger.core.EBL;com.silabs.ss.framework.debugger.core.GBL" id="com.silabs.ide.si8051.keil.targetplatform.1736873507" isAbstract="false" superClass="com.silabs.ide.si8051.keil.targetplatform"/>
<builder buildPath="${workspace_loc:/efm8}/Keil 8051 v9.53 - Debug" id="com.silabs.ide.si8051.keil.builder.699981897" keepEnvironmentInBuildfile="false" managedBuildOn="true" name="Keil Builder" parallelBuildOn="false" superClass="com.silabs.ide.si8051.keil.builder"/>
<tool id="com.silabs.ide.si8051.keil.toolchain.compiler.161237451" name="Keil 8051 Compiler" superClass="com.silabs.ide.si8051.keil.toolchain.compiler">
<option id="com.silabs.ide.si8051.keil.compiler.category.symbols.def.1394396371" name="Defined symbols (DEFINE(...))" superClass="com.silabs.ide.si8051.keil.compiler.category.symbols.def" valueType="definedSymbols">
<listOptionValue builtIn="false" value="DEBUG=1"/>
</option>
<option id="com.silabs.ide.si8051.keil.compiler.category.optimization.level.816863969" name="Level" superClass="com.silabs.ide.si8051.keil.compiler.category.optimization.level" value="com.silabs.ide.si8051.keil.compiler.category.optimization.level.9" valueType="enumerated"/>
<option id="com.silabs.ide.si8051.keil.compiler.category.optimization.emphasis.628030751" name="Emphasis" superClass="com.silabs.ide.si8051.keil.compiler.category.optimization.emphasis" value="com.silabs.ide.si8051.keil.compiler.category.optimization.emphasis.speed" valueType="enumerated"/>
<option id="com.silabs.ide.si8051.keil.compiler.category.includes.paths.1243816580" name="Include paths (INCDIR(...))" superClass="com.silabs.ide.si8051.keil.compiler.category.includes.paths" valueType="includePath">
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/inc}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/inc/config}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${StudioSdkPath}/Lib/efm8_usb/inc&quot;"/>
<listOptionValue builtIn="false" value="&quot;${StudioSdkPath}/Lib/efm8_assert&quot;"/>
<listOptionValue builtIn="false" value="&quot;${StudioSdkPath}/Device/EFM8UB1/peripheral_driver/inc&quot;"/>
<listOptionValue builtIn="false" value="&quot;${StudioSdkPath}/Device/shared/si8051base&quot;"/>
<listOptionValue builtIn="false" value="&quot;${StudioSdkPath}/Device/EFM8UB1/inc&quot;"/>
<listOptionValue builtIn="false" value="&quot;${StudioSdkPath}/Lib/efm8_usbc/lib_kernel/inc&quot;"/>
<listOptionValue builtIn="false" value="&quot;${StudioSdkPath}/Lib/efm8_usbc/lib_usbc_pd/inc&quot;"/>
</option>
<option id="com.silabs.ide.si8051.keil.compiler.category.misc.extraflags.1584403236" name="Additional Flags" superClass="com.silabs.ide.si8051.keil.compiler.category.misc.extraflags" value="OA" valueType="string"/>
<option id="com.silabs.ide.si8051.keil.compiler.category.general.code.1474638890" name="Code size" superClass="com.silabs.ide.si8051.keil.compiler.category.general.code" value="com.silabs.ide.si8051.keil.compiler.category.general.code.small" valueType="enumerated"/>
<inputType id="com.silabs.ide.si8051.keil.compiler.inputType.1048026013" superClass="com.silabs.ide.si8051.keil.compiler.inputType"/>
</tool>
<tool command="AX51" id="com.silabs.ide.si8051.keil.toolchain.assembler.683449334" name="Keil 8051 Assembler" superClass="com.silabs.ide.si8051.keil.toolchain.assembler">
<option id="com.silabs.ide.si8051.keil.assembler.category.symbols.def.677208820" name="Defined symbols (SET(...))" superClass="com.silabs.ide.si8051.keil.assembler.category.symbols.def"/>
<option id="com.silabs.ide.si8051.keil.assembler.category.includes.paths.1772111840" name="Include paths (INCDIR(...))" superClass="com.silabs.ide.si8051.keil.assembler.category.includes.paths" valueType="includePath">
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/inc}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/inc/config}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${StudioSdkPath}/Lib/efm8_usb/inc&quot;"/>
<listOptionValue builtIn="false" value="&quot;${StudioSdkPath}/Lib/efm8_assert&quot;"/>
<listOptionValue builtIn="false" value="&quot;${StudioSdkPath}/Device/EFM8UB1/peripheral_driver/inc&quot;"/>
<listOptionValue builtIn="false" value="&quot;${StudioSdkPath}/Device/shared/si8051base&quot;"/>
<listOptionValue builtIn="false" value="&quot;${StudioSdkPath}/Device/EFM8UB1/inc&quot;"/>
<listOptionValue builtIn="false" value="&quot;${StudioSdkPath}/Lib/efm8_usbc/lib_kernel/inc&quot;"/>
<listOptionValue builtIn="false" value="&quot;${StudioSdkPath}/Lib/efm8_usbc/lib_usbc_pd/inc&quot;"/>
</option>
<inputType id="com.silabs.ide.si8051.keil.assembler.inputType.1712887970" superClass="com.silabs.ide.si8051.keil.assembler.inputType"/>
</tool>
<tool command="LX51" id="com.silabs.ide.si8051.keil.toolchain.linker.367126547" name="Keil 8051 Linker" superClass="com.silabs.ide.si8051.keil.toolchain.linker">
<option id="com.silabs.ide.si8051.keil.linker.category.general.use_control_file.117123054" name="Use linker control file" superClass="com.silabs.ide.si8051.keil.linker.category.general.use_control_file" value="false" valueType="boolean"/>
<option id="com.silabs.ide.si8051.keil.linker.category.ordering.selection.1520457668" name="Linker input ordering" superClass="com.silabs.ide.si8051.keil.linker.category.ordering.selection" value="./src/InitDevice.OBJ;./src/SILABS_STARTUP.OBJ;./src/callback.OBJ;./src/descriptors.OBJ;./src/main.OBJ;./src/printing.OBJ;./lib/efm8ub1/peripheralDrivers/src/usb_0.OBJ;./lib/efm8_usb/src/efm8_usbd.OBJ;./lib/efm8_usb/src/efm8_usbdch9.OBJ;./lib/efm8_usb/src/efm8_usbdep.OBJ;./lib/efm8_usb/src/efm8_usbdint.OBJ;./lib/efm8_assert/assert.OBJ" valueType="string"/>
<inputType id="com.silabs.ide.si8051.keil.linker.inputType.320881486" superClass="com.silabs.ide.si8051.keil.linker.inputType"/>
</tool>
<tool id="com.silabs.ide.si8051.keil.toolchain.librarian.1238681544" name="Keil 8051 Library Manager" superClass="com.silabs.ide.si8051.keil.toolchain.librarian"/>
</toolChain>
</folderInfo>
<sourceEntries>
<entry excluding=".git/objects/info|.git/objects/pack|.git/refs/tags|lib/c8051f320|lib/c8051f326|lib/c8051f340|lib/c8051f380|lib/efm8ub2|lib/efm8ub3|lib/efm8ub4|src" flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name=""/>
<entry flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="src"/>
</sourceEntries>
</configuration>
</storageModule>
<storageModule moduleId="org.eclipse.cdt.core.externalSettings"/>
</cconfiguration>
<cconfiguration id="com.silabs.ss.tool.ide.c8051.toolchain.keil.cdt.release#com.silabs.ss.tool.ide.c8051.toolchain.keil.cdt:9.53.0">
<storageModule buildSystemId="org.eclipse.cdt.managedbuilder.core.configurationDataProvider" id="com.silabs.ss.tool.ide.c8051.toolchain.keil.cdt.release#com.silabs.ss.tool.ide.c8051.toolchain.keil.cdt:9.53.0" moduleId="org.eclipse.cdt.core.settings" name="Keil 8051 v9.53 - Release">
<macros>
<stringMacro name="StudioSdkPath" type="VALUE_PATH_DIR" value="${StudioSdkPathFromID:com.silabs.sdk.8051:4.1.1._-963069327}"/>
<stringMacro name="StudioToolchainPath" type="VALUE_PATH_DIR" value="${StudioToolchainPathFromID:com.silabs.ss.tool.ide.c8051.toolchain.keil.cdt:9.53.0}"/>
</macros>
<externalSettings/>
<extensions>
<extension id="com.silabs.ss.framework.debugger.core.HEX" point="org.eclipse.cdt.core.BinaryParser"/>
<extension id="com.silabs.ss.tool.ide.c8051.debug.OMF2" point="org.eclipse.cdt.core.BinaryParser"/>
<extension id="com.silabs.ss.framework.debugger.core.EBL" point="org.eclipse.cdt.core.BinaryParser"/>
<extension id="com.silabs.ss.framework.debugger.core.GBL" point="org.eclipse.cdt.core.BinaryParser"/>
<extension id="com.silabs.ss.tool.ide.c8051.debug.OMF" point="org.eclipse.cdt.core.BinaryParser"/>
<extension id="com.silabs.ss.framework.debugger.core.BIN" point="org.eclipse.cdt.core.BinaryParser"/>
<extension id="com.silabs.ss.framework.debugger.core.S37" point="org.eclipse.cdt.core.BinaryParser"/>
<extension id="org.eclipse.cdt.core.GmakeErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
<extension id="com.silabs.ss.tool.ide.c8051.toolchain.keil.cdt.KeilErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
<extension id="org.eclipse.cdt.core.CWDLocator" point="org.eclipse.cdt.core.ErrorParser"/>
</extensions>
</storageModule>
<storageModule buildConfig.stockConfigId="com.silabs.ss.tool.ide.c8051.toolchain.keil.cdt.release#com.silabs.ss.tool.ide.c8051.toolchain.keil.cdt:9.53.0" cppBuildConfig.builtinIncludes="studio:/sdk/Lib/efm8_usb/inc/ studio:/sdk/Lib/efm8_assert/ studio:/sdk/Device/EFM8UB1/peripheral_driver/inc/ studio:/sdk/Device/shared/si8051base/ studio:/sdk/Device/EFM8UB1/inc/ studio:/sdk/Lib/efm8_usbc/lib_kernel/inc/ studio:/sdk/Lib/efm8_usbc/lib_usbc_pd/inc/ studio:/sdk/Lib/efm8_usb/inc/ studio:/sdk/Lib/efm8_assert/ studio:/sdk/Device/EFM8UB1/peripheral_driver/inc/ studio:/sdk/Device/shared/si8051base/ studio:/sdk/Device/EFM8UB1/inc/ studio:/sdk/Lib/efm8_usbc/lib_kernel/inc/ studio:/sdk/Lib/efm8_usbc/lib_usbc_pd/inc/" cppBuildConfig.builtinLibraryFiles="" cppBuildConfig.builtinLibraryNames="" cppBuildConfig.builtinLibraryObjects="" cppBuildConfig.builtinLibraryPaths="" cppBuildConfig.builtinMacros="" moduleId="com.silabs.ss.framework.ide.project.core.cpp" projectCommon.referencedModules="[{&quot;builtinExcludes&quot;:[],&quot;builtinSources&quot;:[],&quot;builtin&quot;:true,&quot;module&quot;:&quot;&lt;project:MModule xmlns:project=\&quot;http://www.silabs.com/ss/Project.ecore\&quot; builtin=\&quot;true\&quot; id=\&quot;com.silabs.sdk.si8051.external.efm8Library.usbc\&quot;/&gt;&quot;},{&quot;builtinExcludes&quot;:[],&quot;builtinSources&quot;:[&quot;lib/efm8ub1/peripheralDrivers/src/usb_0.c&quot;,&quot;lib/efm8ub1/peripheralDrivers/inc/usb_0.h&quot;],&quot;builtin&quot;:true,&quot;module&quot;:&quot;&lt;project:MModule xmlns:project=\&quot;http://www.silabs.com/ss/Project.ecore\&quot; builtin=\&quot;true\&quot; id=\&quot;com.silabs.sdk.si8051.external.efm8PeripheralDriver.usb0\&quot;/&gt;&quot;},{&quot;builtinExcludes&quot;:[],&quot;builtinSources&quot;:[&quot;lib/efm8_usb/inc/efm8_usb.h&quot;,&quot;lib/efm8_usb/src/efm8_usbd.c&quot;,&quot;lib/efm8_usb/src/efm8_usbdch9.c&quot;,&quot;lib/efm8_usb/src/efm8_usbdep.c&quot;,&quot;lib/efm8_usb/src/efm8_usbdint.c&quot;,&quot;lib/efm8_usb/Readme.txt&quot;],&quot;builtin&quot;:true,&quot;module&quot;:&quot;&lt;project:MModule xmlns:project=\&quot;http://www.silabs.com/ss/Project.ecore\&quot; builtin=\&quot;true\&quot; id=\&quot;com.silabs.sdk.si8051.external.efm8Library.usb\&quot;/&gt;&quot;},{&quot;builtinExcludes&quot;:[],&quot;builtinSources&quot;:[&quot;lib/efm8_assert/assert.c&quot;,&quot;lib/efm8_assert/assert.h&quot;],&quot;builtin&quot;:true,&quot;module&quot;:&quot;&lt;project:MModule xmlns:project=\&quot;http://www.silabs.com/ss/Project.ecore\&quot; builtin=\&quot;true\&quot; id=\&quot;com.silabs.sdk.si8051.external.efm8Library.assert\&quot;/&gt;&quot;},{&quot;builtinExcludes&quot;:[],&quot;builtinSources&quot;:[&quot;src/SILABS_STARTUP.A51&quot;],&quot;builtin&quot;:true,&quot;module&quot;:&quot;&lt;project:MModule xmlns:project=\&quot;http://www.silabs.com/ss/Project.ecore\&quot; builtin=\&quot;true\&quot; id=\&quot;com.silabs.sdk.si8051.shared\&quot;/&gt;&quot;}]" projectCommon.toolchainId="com.silabs.ss.tool.ide.c8051.toolchain.keil.cdt:9.53.0"/>
<storageModule moduleId="cdtBuildSystem" version="4.0.0">
<configuration artifactExtension="omf" artifactName="${ProjName}" buildArtefactType="org.eclipse.cdt.build.core.buildArtefactType.exe" buildProperties="org.eclipse.cdt.build.core.buildArtefactType=org.eclipse.cdt.build.core.buildArtefactType.exe" cleanCommand="rm -rf" description="" id="com.silabs.ss.tool.ide.c8051.toolchain.keil.cdt.release#com.silabs.ss.tool.ide.c8051.toolchain.keil.cdt:9.53.0" name="Keil 8051 v9.53 - Release" parent="com.silabs.ide.si8051.keil.exe.default">
<folderInfo id="com.silabs.ss.tool.ide.c8051.toolchain.keil.cdt.release#com.silabs.ss.tool.ide.c8051.toolchain.keil.cdt:9.53.0." name="/" resourcePath="">
<toolChain id="com.silabs.ide.si8051.keil.toolchain.exe.default.2049529147" name="Keil 8051" superClass="com.silabs.ide.si8051.keil.toolchain.exe.default">
<option id="com.silabs.ide.si8051.keil.toolchain.category.general.debug.498309818" name="Generate debug information" superClass="com.silabs.ide.si8051.keil.toolchain.category.general.debug" value="true" valueType="boolean"/>
<option id="com.silabs.ide.si8051.keil.toolchain.category.general.extended_assembler.1283846940" name="Use Extended Assembler (AX51) instead of A51" superClass="com.silabs.ide.si8051.keil.toolchain.category.general.extended_assembler" value="true" valueType="boolean"/>
<option id="com.silabs.ide.si8051.keil.toolchain.category.general.extended_linker.146017776" name="Use Extended Linker (LX51) instead of BL51" superClass="com.silabs.ide.si8051.keil.toolchain.category.general.extended_linker" value="true" valueType="boolean"/>
<option id="com.silabs.ide.si8051.keil.toolchain.category.general.memory_model.640114993" name="Memory model" superClass="com.silabs.ide.si8051.keil.toolchain.category.general.memory_model" value="com.silabs.ide.si8051.keil.toolchain.category.general.memory_model.small" valueType="enumerated"/>
<targetPlatform binaryParser="com.silabs.ss.tool.ide.c8051.debug.OMF;com.silabs.ss.tool.ide.c8051.debug.OMF2;com.silabs.ss.framework.debugger.core.BIN;com.silabs.ss.framework.debugger.core.HEX;com.silabs.ss.framework.debugger.core.S37;com.silabs.ss.framework.debugger.core.EBL;com.silabs.ss.framework.debugger.core.GBL" id="com.silabs.ide.si8051.keil.targetplatform.690223176" isAbstract="false" superClass="com.silabs.ide.si8051.keil.targetplatform"/>
<builder buildPath="${workspace_loc:/efm8}/Keil 8051 v9.53 - Release" id="com.silabs.ide.si8051.keil.builder.1329230955" keepEnvironmentInBuildfile="false" managedBuildOn="true" name="Keil Builder" parallelBuildOn="false" superClass="com.silabs.ide.si8051.keil.builder"/>
<tool id="com.silabs.ide.si8051.keil.toolchain.compiler.1966285955" name="Keil 8051 Compiler" superClass="com.silabs.ide.si8051.keil.toolchain.compiler">
<option id="com.silabs.ide.si8051.keil.compiler.category.optimization.level.851586321" name="Level" superClass="com.silabs.ide.si8051.keil.compiler.category.optimization.level" value="com.silabs.ide.si8051.keil.compiler.category.optimization.level.9" valueType="enumerated"/>
<option id="com.silabs.ide.si8051.keil.compiler.category.symbols.def.497293805" name="Defined symbols (DEFINE(...))" superClass="com.silabs.ide.si8051.keil.compiler.category.symbols.def" valueType="definedSymbols">
<listOptionValue builtIn="false" value="NDEBUG=1"/>
</option>
<option id="com.silabs.ide.si8051.keil.compiler.category.optimization.coloring.2036986310" name="Global register coloring" superClass="com.silabs.ide.si8051.keil.compiler.category.optimization.coloring" value="true" valueType="boolean"/>
<option id="com.silabs.ide.si8051.keil.compiler.category.optimization.emphasis.777114717" name="Emphasis" superClass="com.silabs.ide.si8051.keil.compiler.category.optimization.emphasis" value="com.silabs.ide.si8051.keil.compiler.category.optimization.emphasis.speed" valueType="enumerated"/>
<option id="com.silabs.ide.si8051.keil.compiler.category.includes.paths.882106026" name="Include paths (INCDIR(...))" superClass="com.silabs.ide.si8051.keil.compiler.category.includes.paths" valueType="includePath">
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/inc}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/inc/config}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${StudioSdkPath}/Lib/efm8_usb/inc&quot;"/>
<listOptionValue builtIn="false" value="&quot;${StudioSdkPath}/Lib/efm8_assert&quot;"/>
<listOptionValue builtIn="false" value="&quot;${StudioSdkPath}/Device/EFM8UB1/peripheral_driver/inc&quot;"/>
<listOptionValue builtIn="false" value="&quot;${StudioSdkPath}/Device/shared/si8051base&quot;"/>
<listOptionValue builtIn="false" value="&quot;${StudioSdkPath}/Device/EFM8UB1/inc&quot;"/>
<listOptionValue builtIn="false" value="&quot;${StudioSdkPath}/Lib/efm8_usbc/lib_kernel/inc&quot;"/>
<listOptionValue builtIn="false" value="&quot;${StudioSdkPath}/Lib/efm8_usbc/lib_usbc_pd/inc&quot;"/>
</option>
<option id="com.silabs.ide.si8051.keil.compiler.category.misc.extraflags.1520964257" name="Additional Flags" superClass="com.silabs.ide.si8051.keil.compiler.category.misc.extraflags" value="OA" valueType="string"/>
<option id="com.silabs.ide.si8051.keil.compiler.category.general.code.1101784529" name="Code size" superClass="com.silabs.ide.si8051.keil.compiler.category.general.code" value="com.silabs.ide.si8051.keil.compiler.category.general.code.large" valueType="enumerated"/>
<inputType id="com.silabs.ide.si8051.keil.compiler.inputType.1366062481" superClass="com.silabs.ide.si8051.keil.compiler.inputType"/>
</tool>
<tool command="AX51" id="com.silabs.ide.si8051.keil.toolchain.assembler.862226894" name="Keil 8051 Assembler" superClass="com.silabs.ide.si8051.keil.toolchain.assembler">
<option id="com.silabs.ide.si8051.keil.assembler.category.symbols.def.1379136974" name="Defined symbols (SET(...))" superClass="com.silabs.ide.si8051.keil.assembler.category.symbols.def" valueType="stringList">
<listOptionValue builtIn="false" value="SILABS_STARTUP=1"/>
</option>
<option id="com.silabs.ide.si8051.keil.assembler.category.includes.paths.2327129" name="Include paths (INCDIR(...))" superClass="com.silabs.ide.si8051.keil.assembler.category.includes.paths" valueType="includePath">
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/inc}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/inc/config}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${StudioSdkPath}/Lib/efm8_usb/inc&quot;"/>
<listOptionValue builtIn="false" value="&quot;${StudioSdkPath}/Lib/efm8_assert&quot;"/>
<listOptionValue builtIn="false" value="&quot;${StudioSdkPath}/Device/EFM8UB1/peripheral_driver/inc&quot;"/>
<listOptionValue builtIn="false" value="&quot;${StudioSdkPath}/Device/shared/si8051base&quot;"/>
<listOptionValue builtIn="false" value="&quot;${StudioSdkPath}/Device/EFM8UB1/inc&quot;"/>
<listOptionValue builtIn="false" value="&quot;${StudioSdkPath}/Lib/efm8_usbc/lib_kernel/inc&quot;"/>
<listOptionValue builtIn="false" value="&quot;${StudioSdkPath}/Lib/efm8_usbc/lib_usbc_pd/inc&quot;"/>
</option>
<inputType id="com.silabs.ide.si8051.keil.assembler.inputType.1906467347" superClass="com.silabs.ide.si8051.keil.assembler.inputType"/>
</tool>
<tool command="LX51" id="com.silabs.ide.si8051.keil.toolchain.linker.1259644704" name="Keil 8051 Linker" superClass="com.silabs.ide.si8051.keil.toolchain.linker">
<option id="com.silabs.ide.si8051.keil.linker.category.general.use_control_file.1886409616" name="Use linker control file" superClass="com.silabs.ide.si8051.keil.linker.category.general.use_control_file" value="true" valueType="boolean"/>
<inputType id="com.silabs.ide.si8051.keil.linker.inputType.1526176751" superClass="com.silabs.ide.si8051.keil.linker.inputType"/>
</tool>
<tool id="com.silabs.ide.si8051.keil.toolchain.librarian.1609353969" name="Keil 8051 Library Manager" superClass="com.silabs.ide.si8051.keil.toolchain.librarian"/>
</toolChain>
</folderInfo>
<sourceEntries>
<entry excluding=".git/objects/info|.git/objects/pack|.git/refs/tags|lib/c8051f320|lib/c8051f326|lib/c8051f340|lib/c8051f380|lib/efm8ub2|lib/efm8ub3|lib/efm8ub4|src" flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name=""/>
<entry flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="src"/>
</sourceEntries>
</configuration>
</storageModule>
<storageModule moduleId="org.eclipse.cdt.core.externalSettings"/>
</cconfiguration>
</storageModule>
<storageModule moduleId="com.silabs.ss.framework.ide.project.core.cpp" project.generation="41" projectCommon.boardIds="brd5000a:0.0.0.A02" projectCommon.buildArtifactType="EXE" projectCommon.importModeId="COPY" projectCommon.partId="mcu.8051.efm8.ub1.efm8ub10f16g-b-qfn28" projectCommon.sdkId="com.silabs.sdk.8051:4.1.1._-963069327"/>
<storageModule moduleId="cdtBuildSystem" version="4.0.0">
<project id="efm8.com.silabs.ss.framework.ide.project.core.cdt.cdtMbsProjectType.972220390" name="SLS CDT Project" projectType="com.silabs.ss.framework.ide.project.core.cdt.cdtMbsProjectType"/>
</storageModule>
<storageModule moduleId="org.eclipse.cdt.core.LanguageSettingsProviders"/>
<storageModule moduleId="scannerConfiguration">
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
<scannerConfigBuildInfo instanceId="com.silabs.ss.tool.ide.c8051.toolchain.keil.cdt.debug#com.silabs.ss.tool.ide.c8051.toolchain.keil.cdt:9.53.0;com.silabs.ss.tool.ide.c8051.toolchain.keil.cdt.debug#com.silabs.ss.tool.ide.c8051.toolchain.keil.cdt:9.53.0.">
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId="com.silabs.ide.si8051.keil.KeilScannerInfoCollector"/>
</scannerConfigBuildInfo>
<scannerConfigBuildInfo instanceId="com.silabs.ss.tool.ide.c8051.toolchain.keil.cdt.release#com.silabs.ss.tool.ide.c8051.toolchain.keil.cdt:9.53.0;com.silabs.ss.tool.ide.c8051.toolchain.keil.cdt.release#com.silabs.ss.tool.ide.c8051.toolchain.keil.cdt:9.53.0.">
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId="com.silabs.ide.si8051.keil.KeilScannerInfoCollector"/>
</scannerConfigBuildInfo>
</storageModule>
<storageModule moduleId="refreshScope"/>
</cproject>

27
efm8/.project Normal file
View File

@@ -0,0 +1,27 @@
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>efm8</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>com.silabs.ss.framework.ide.project.sls.core.SLSProjectNature</nature>
<nature>org.eclipse.cdt.managedbuilder.core.managedBuildNature</nature>
<nature>org.eclipse.cdt.managedbuilder.core.ScannerConfigNature</nature>
</natures>
</projectDescription>

View File

@@ -0,0 +1,2 @@
copiedFilesOriginState={}
eclipse.preferences.version=1

View File

@@ -0,0 +1,2 @@
eclipse.preferences.version=1
org.eclipse.ltk.core.refactoring.enable.project.refactoring.history=false

71
efm8/efm8.hwconf Normal file
View File

@@ -0,0 +1,71 @@
<?xml version="1.0" encoding="ASCII"?>
<device:XMLDevice xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:device="http://www.silabs.com/ss/hwconfig/document/device.ecore" name="EFM8UB10F16G-B-QFN28" partId="mcu.8051.efm8.ub1.efm8ub10f16g-b-qfn28" version="4.0.1" contextId="%DEFAULT%">
<mode name="DefaultMode">
<property object="CIP51_0" propertyId="ABPeripheral.included" value="true"/>
<property object="CIP51_0" propertyId="cip51.prefetchenginecontrol.enableprefetch" value="Enabled"/>
<property object="CIP51_0" propertyId="cip51.prefetchenginecontrol.flashreadtiming" value="SYSCLK is below 50 MHz"/>
<property object="CLOCK_0" propertyId="ABPeripheral.included" value="true"/>
<property object="CLOCK_0" propertyId="clock.clockselect.clocksourcedivider" value="SYSCLK / 1"/>
<property object="CLOCK_0" propertyId="clock.clockselect.selectclocksource" value="Internal High Frequency Oscillator 1"/>
<property object="CROSSBAR0" propertyId="xbar0.uart1.data" value="Enabled"/>
<property object="DefaultMode" propertyId="mode.diagramLocation" value="100, 100"/>
<property object="INTERRUPT_0" propertyId="ABPeripheral.included" value="true"/>
<property object="INTERRUPT_0" propertyId="interrupt.interruptenable.enableallinterrupts" value="Enabled"/>
<property object="P0.0" propertyId="ports.settings.iomode" value="Digital Push-Pull Output"/>
<property object="P0.0" propertyId="ports.settings.outputmode" value="Push-pull"/>
<property object="PBCFG_0" propertyId="pbcfg.settings.enablecrossbar" value="Enabled"/>
<property object="TIMER01_0" propertyId="ABPeripheral.included" value="true"/>
<property object="TIMER16_2" propertyId="ABPeripheral.included" value="true"/>
<property object="TIMER16_2" propertyId="timer16.control.clocksource" value="SYSCLK"/>
<property object="TIMER16_2" propertyId="timer16.control.runcontrol" value="Start"/>
<property object="TIMER16_2" propertyId="timer16.control.timerrunningstate" value="Timer is Running"/>
<property object="TIMER16_2" propertyId="timer16.initandreloadvalue.targetoverflowfrequency" value="1000"/>
<property object="TIMER16_2" propertyId="timer16.initandreloadvalue.timerreloadvalue" value="17536"/>
<property object="TIMER16_2" propertyId="timer16.reloadhighbyte.reloadhighbyte" value="68"/>
<property object="TIMER16_2" propertyId="timer16.reloadlowbyte.reloadlowbyte" value="128"/>
<property object="TIMER16_3" propertyId="ABPeripheral.included" value="true"/>
<property object="TIMER16_3" propertyId="timer16.control.clocksource" value="SYSCLK"/>
<property object="TIMER16_4" propertyId="ABPeripheral.included" value="true"/>
<property object="TIMER_SETUP_0" propertyId="ABPeripheral.included" value="true"/>
<property object="TIMER_SETUP_0" propertyId="timer_setup.clockcontrol.timer2lowbyteclockselect" value="Use SYSCLK"/>
<property object="TIMER_SETUP_0" propertyId="timer_setup.clockcontrol.timer3lowbyteclockselect" value="Use SYSCLK"/>
<property object="UARTE_1" propertyId="ABPeripheral.included" value="true"/>
<property object="UARTE_1" propertyId="uarte.baudrategeneratorcontrol.actualbaudrate" value="115384"/>
<property object="UARTE_1" propertyId="uarte.baudrategeneratorcontrol.baudrateprescaler" value="Divide by 1"/>
<property object="UARTE_1" propertyId="uarte.baudrategeneratorcontrol.baudratereloadhigh" value="255"/>
<property object="UARTE_1" propertyId="uarte.baudrategeneratorcontrol.baudratereloadlow" value="48"/>
<property object="UARTE_1" propertyId="uarte.baudrategeneratorcontrol.enablebaudrategenerator" value="Enabled"/>
<property object="UARTE_1" propertyId="uarte.baudrategeneratorcontrol.expectedbaudrate" value="115200"/>
<property object="UARTE_1" propertyId="uarte.serialportcontrol.enablereceive" value="Enabled"/>
<property object="UART_0" propertyId="uart.serialportcontrol.actualbaudrate" value="93750 Baud"/>
<property object="UART_0" propertyId="uart.serialportcontrol.timer1overflowfrequency" value="187.500 kHz"/>
<property object="USBLIB_0" propertyId="ABPeripheral.included" value="true"/>
<property object="USBLIB_0" propertyId="configuration.configurationparameters.configurationstring" value="conf"/>
<property object="USBLIB_0" propertyId="configuration.configurationparameters.devicepower" value="Bus-Powered"/>
<property object="USBLIB_0" propertyId="device.deviceproperties.bmaxpacketsize" value="64"/>
<property object="USBLIB_0" propertyId="device.deviceproperties.productidpid" value="35535"/>
<property object="USBLIB_0" propertyId="device.deviceproperties.productstring" value="EOS Wallet"/>
<property object="USBLIB_0" propertyId="endpoints.endpoint1in.bulkmaxpacketsizebytes" value="64"/>
<property object="USBLIB_0" propertyId="endpoints.endpoint1in.endpoint1in" value="Enabled"/>
<property object="USBLIB_0" propertyId="endpoints.endpoint1in.maxpacketsizebytes" value="64"/>
<property object="USBLIB_0" propertyId="endpoints.endpoint1in.pollingintervalms" value="5"/>
<property object="USBLIB_0" propertyId="endpoints.endpoint1in.transfertype" value="Interrupt"/>
<property object="USBLIB_0" propertyId="endpoints.endpoint1out.endpoint1out" value="Enabled"/>
<property object="USBLIB_0" propertyId="endpoints.endpoint1out.maxpacketsizebytes" value="64"/>
<property object="USBLIB_0" propertyId="endpoints.endpoint1out.pollingintervalms" value="5"/>
<property object="USBLIB_0" propertyId="endpoints.endpoint1out.transfertype" value="Interrupt"/>
<property object="USBLIB_0" propertyId="interfaces.interface0.interfaceclass" value="HID (Human Interface Device)"/>
<property object="USBLIB_0" propertyId="library.callbackfunctions.resetcallback" value="Enabled"/>
<property object="USBLIB_0" propertyId="library.callbackfunctions.selfpoweredcallback" value="Enabled"/>
<property object="USBLIB_0" propertyId="library.callbackfunctions.setupcommandcallback" value="Enabled"/>
<property object="USBLIB_0" propertyId="library.callbackfunctions.statechangecallback" value="Enabled"/>
<property object="USBLIB_0" propertyId="library.libraryconfiguration.clockrecovery" value="Enabled"/>
<property object="VREG_0" propertyId="ABPeripheral.included" value="true"/>
<property object="WDT_0" propertyId="ABPeripheral.included" value="true"/>
<property object="WDT_0" propertyId="wdt.watchdogcontrol.wdtenable" value="Disable"/>
</mode>
<modeTransition>
<property object="RESET &#x2192; DefaultMode" propertyId="modeTransition.source" value="RESET"/>
<property object="RESET &#x2192; DefaultMode" propertyId="modeTransition.target" value="DefaultMode"/>
</modeTransition>
</device:XMLDevice>

33
efm8/inc/InitDevice.h Normal file
View File

@@ -0,0 +1,33 @@
//=========================================================
// inc/InitDevice.h: generated by Hardware Configurator
//
// This file will be regenerated when saving a document.
// leave the sections inside the "$[...]" comment tags alone
// or they will be overwritten!
//=========================================================
#ifndef __INIT_DEVICE_H__
#define __INIT_DEVICE_H__
// USER CONSTANTS
// USER PROTOTYPES
// $[Mode Transition Prototypes]
extern void enter_DefaultMode_from_RESET(void);
// [Mode Transition Prototypes]$
// $[Config(Per-Module Mode)Transition Prototypes]
extern void WDT_0_enter_DefaultMode_from_RESET(void);
extern void PORTS_0_enter_DefaultMode_from_RESET(void);
extern void PBCFG_0_enter_DefaultMode_from_RESET(void);
extern void CIP51_0_enter_DefaultMode_from_RESET(void);
extern void CLOCK_0_enter_DefaultMode_from_RESET(void);
extern void TIMER16_2_enter_DefaultMode_from_RESET(void);
extern void TIMER16_3_enter_DefaultMode_from_RESET(void);
extern void TIMER_SETUP_0_enter_DefaultMode_from_RESET(void);
extern void UARTE_1_enter_DefaultMode_from_RESET(void);
extern void INTERRUPT_0_enter_DefaultMode_from_RESET(void);
extern void USBLIB_0_enter_DefaultMode_from_RESET(void);
// [Config(Per-Module Mode)Transition Prototypes]$
#endif

13
efm8/inc/app.h Normal file
View File

@@ -0,0 +1,13 @@
/*
* app.h
*
* Created on: Jun 25, 2018
* Author: conor
*/
#ifndef INC_APP_H_
#define INC_APP_H_
#define USE_PRINTING
#endif /* INC_APP_H_ */

157
efm8/inc/config/usbconfig.h Normal file
View File

@@ -0,0 +1,157 @@
/*******************************************************************************
* @file usbconfig.h
* @brief USB protocol stack library, application supplied configuration options.
*******************************************************************************/
//=============================================================================
// inc/config/usbconfig.h: generated by Hardware Configurator
//
// This file will be regenerated when saving a document. leave the sections
// inside the "$[...]" comment tags alone or they will be overwritten!
//=============================================================================
#ifndef __SILICON_LABS_USBCONFIG_H
#define __SILICON_LABS_USBCONFIG_H
// -----------------------------------------------------------------------------
// Specify bus- or self-powered
// -----------------------------------------------------------------------------
// $[Device Power]
#define SLAB_USB_BUS_POWERED 1
// [Device Power]$
// -----------------------------------------------------------------------------
// Specify USB speed
// -----------------------------------------------------------------------------
// $[USB Speed]
#define SLAB_USB_FULL_SPEED 1
// [USB Speed]$
// -----------------------------------------------------------------------------
// Enable or disable the clock recovery
// -----------------------------------------------------------------------------
// $[Clock Recovery]
#define SLAB_USB_CLOCK_RECOVERY_ENABLED 1
// [Clock Recovery]$
// -----------------------------------------------------------------------------
// Enable or disable remote wakeup
// -----------------------------------------------------------------------------
// $[Remote Wake-up]
#define SLAB_USB_REMOTE_WAKEUP_ENABLED 0
// [Remote Wake-up]$
// -----------------------------------------------------------------------------
// Specify number of interfaces and whether any interfaces support alternate
// settings
// -----------------------------------------------------------------------------
// $[Number of Interfaces]
#define SLAB_USB_NUM_INTERFACES 1
#define SLAB_USB_SUPPORT_ALT_INTERFACES 0
// [Number of Interfaces]$
// -----------------------------------------------------------------------------
// Enable or disable each endpoint
// -----------------------------------------------------------------------------
// $[Endpoints Used]
#define SLAB_USB_EP1IN_USED 1
#define SLAB_USB_EP1OUT_USED 1
#define SLAB_USB_EP2IN_USED 0
#define SLAB_USB_EP2OUT_USED 0
#define SLAB_USB_EP3IN_USED 0
#define SLAB_USB_EP3OUT_USED 0
// [Endpoints Used]$
// -----------------------------------------------------------------------------
// Specify maximum packet size for each endpoint
// -----------------------------------------------------------------------------
// $[Endpoint Max Packet Size]
#define SLAB_USB_EP1IN_MAX_PACKET_SIZE 64
#define SLAB_USB_EP1OUT_MAX_PACKET_SIZE 64
#define SLAB_USB_EP2IN_MAX_PACKET_SIZE 1
#define SLAB_USB_EP2OUT_MAX_PACKET_SIZE 1
#define SLAB_USB_EP3IN_MAX_PACKET_SIZE 1
#define SLAB_USB_EP3OUT_MAX_PACKET_SIZE 1
// [Endpoint Max Packet Size]$
// -----------------------------------------------------------------------------
// Specify transfer type of each endpoint
// -----------------------------------------------------------------------------
// $[Endpoint Transfer Type]
#define SLAB_USB_EP1IN_TRANSFER_TYPE USB_EPTYPE_INTR
#define SLAB_USB_EP1OUT_TRANSFER_TYPE USB_EPTYPE_INTR
#define SLAB_USB_EP2IN_TRANSFER_TYPE USB_EPTYPE_BULK
#define SLAB_USB_EP2OUT_TRANSFER_TYPE USB_EPTYPE_BULK
#define SLAB_USB_EP3IN_TRANSFER_TYPE USB_EPTYPE_ISOC
#define SLAB_USB_EP3OUT_TRANSFER_TYPE USB_EPTYPE_ISOC
// [Endpoint Transfer Type]$
// -----------------------------------------------------------------------------
// Enable or disable callback functions
// -----------------------------------------------------------------------------
// $[Callback Functions]
#define SLAB_USB_HANDLER_CB 0
#define SLAB_USB_IS_SELF_POWERED_CB 1
#define SLAB_USB_RESET_CB 1
#define SLAB_USB_SETUP_CMD_CB 1
#define SLAB_USB_SOF_CB 0
#define SLAB_USB_STATE_CHANGE_CB 1
// [Callback Functions]$
// -----------------------------------------------------------------------------
// Specify number of languages supported by string descriptors.
// -----------------------------------------------------------------------------
// $[Number of Languages]
#define SLAB_USB_NUM_LANGUAGES 1
// [Number of Languages]$
// -----------------------------------------------------------------------------
// If only one descriptor language is supported, specify that language here.
// If multiple descriptor languages are supported, this value is ignored and
// the supported languages must listed in the
// myUsbStringTableLanguageIDsDescriptor structure.
// -----------------------------------------------------------------------------
// $[USB Language]
#define SLAB_USB_LANGUAGE USB_LANGID_ENUS
// [USB Language]$
// -----------------------------------------------------------------------------
//
// Set the power saving mode
//
// SLAB_USB_PWRSAVE_MODE configures when the device will automatically enter
// the USB power-save mode. It is a bitmask constant with bit values:
// USB_PWRSAVE_MODE_OFF - No energy saving mode selected
// USB_PWRSAVE_MODE_ONSUSPEND - Enter USB power-save mode on USB suspend
// USB_PWRSAVE_MODE_ONVBUSOFF - Enter USB power-save mode when not attached
// to the USB host.
// USB_PWRSAVE_MODE_FASTWAKE - Exit USB power-save mode more quickly, but
// consume more power while in USB power-save
// mode.
// While the device is in USB power-save mode
// (typically during USB suspend), the
// internal voltage regulator stays in normal
// power mode instead of entering suspend
// power mode.
// This is an advanced feature that may be
// useful in certain applications that support
// remote wakeup.
//
// -----------------------------------------------------------------------------
// $[Power Save Mode]
#define SLAB_USB_PWRSAVE_MODE USB_PWRSAVE_MODE_OFF
// [Power Save Mode]$
// -----------------------------------------------------------------------------
// Enable or disable polled mode
//
// When enabled, the application must call USBD_Run() periodically to process
// USB events.
// When disabled, USB events will be handled automatically by an interrupt
// handler.
// -----------------------------------------------------------------------------
// $[Polled Mode]
#define SLAB_USB_POLLED_MODE 0
// [Polled Mode]$
#endif // __SILICON_LABS_USBCONFIG_H

60
efm8/inc/descriptors.h Normal file
View File

@@ -0,0 +1,60 @@
/*******************************************************************************
* @file descriptors.h
* @brief USB descriptors header file.
*******************************************************************************/
//=============================================================================
// inc/descriptors.h: generated by Hardware Configurator
//
// This file will be regenerated when saving a document. leave the sections
// inside the "$[...]" comment tags alone or they will be overwritten!
//=============================================================================
#ifndef __SILICON_LABS_DESCRIPTORS_H
#define __SILICON_LABS_DESCRIPTORS_H
//-----------------------------------------------------------------------------
// Includes
//-----------------------------------------------------------------------------
#include <si_toolchain.h>
#include <endian.h>
#include <stdlib.h>
#include <string.h>
#include <efm8_usb.h>
#ifdef __cplusplus
extern "C" {
#endif
// -------------------- USB Identification ------------------------------------
//
// **********
// NOTE: YOU MUST PROVIDE YOUR OWN USB VID/PID (below)
// **********
//
// Following are the definition of the USB VID and PID. These are, by default,
// values that are assigned to Silicon Labs. These values are provided merely
// as an example. You may not use the Silicon Labs VID/PID values in your
// product. You must provide your own assigned VID and PID values.
//-----------------------------------------------------------------------------
// $[Vendor ID]
#define USB_VENDOR_ID htole16(0x10c4)
// [Vendor ID]$
// $[Product ID]
#define USB_PRODUCT_ID htole16(0x8acf)
// [Product ID]$
extern SI_SEGMENT_VARIABLE(ReportDescriptor0[34], const uint8_t, SI_SEG_CODE);
extern SI_SEGMENT_VARIABLE(deviceDesc[], const USB_DeviceDescriptor_TypeDef, SI_SEG_CODE);
extern SI_SEGMENT_VARIABLE(configDesc[], const uint8_t, SI_SEG_CODE);
extern SI_SEGMENT_VARIABLE(initstruct, const USBD_Init_TypeDef, SI_SEG_CODE);
#define HID_PACKET_SIZE 64
#ifdef __cplusplus
}
#endif
#endif // __SILICON_LABS_DESCRIPTORS_H

85
efm8/inc/printing.h Normal file
View File

@@ -0,0 +1,85 @@
/*
* Copyright (c) 2016, Conor Patrick
* All rights reserved.
*
* 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.
*
* 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 OWNER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef PRINTING_H_
#define PRINTING_H_
#include <SI_EFM8UB1_Register_Enums.h>
#include <efm8_usb.h>
#include <stdint.h>
#include "app.h"
#define watchdog() (WDTCN = 0xA5)
#define reboot() (RSTSRC = 1 << 4)
void u2f_delay(uint32_t ms);
void usb_write(uint8_t* buf, uint8_t len);
#ifdef USE_PRINTING
void dump_hex(uint8_t* hex, uint8_t len);
void cputd(uint32_t i);
void cputx(uint32_t i);
#define cputb(x) cputx((uint8_t) (x))
#define cputl(x) cputd((uint32_t) (x))
#define cputlx(x) cputx((uint32_t) (x))
void cprints(const char * str);
void cprintb(const char * tag, uint8_t c, ...);
void cprintd(const char * tag, uint8_t c, ...);
void cprintx(const char * tag, uint8_t c, ...);
void cprintl(const char * tag, uint8_t c, ...);
void cprintlx(const char * tag, uint8_t c, ...);
#else
#define cprintx(x)
#define cprintb(x)
#define cprintlx(x)
#define cprintl(x)
#define cprintd(x)
#define cprints(x)
#define cputx(x)
#define cputb(x)
#define cputl(x)
#define cputlx(x)
#define putf(x)
#define dump_hex(x)
#endif
#endif /* BSP_H_ */

View File

@@ -0,0 +1,12 @@
/**************************************************************************//**
* Copyright (c) 2015 by Silicon Laboratories Inc. All rights reserved.
*
* http://developer.silabs.com/legal/version/v11/Silicon_Labs_Software_License_Agreement.txt
*****************************************************************************/
#ifndef NDEBUG
void slab_Assert()
{
while ( 1 );
}
#endif

View File

@@ -0,0 +1,60 @@
/******************************************************************************
* Copyright (c) 2014 by Silicon Laboratories Inc. All rights reserved.
*
* http://developer.silabs.com/legal/version/v11/Silicon_Labs_Software_License_Agreement.txt
*****************************************************************************/
#ifndef __ASSERT_H__
#include "efm8_config.h"
/**************************************************************************//**
* @addtogroup efm8_assert
* @{
*
* @brief Runtime assert for EFM8
*
* This module contains a runtime assert macro. It can be compiled out by setting
* the NDEBUG flag.
*
*****************************************************************************/
/**************************************************************************//**
* @def NDEBUG
* @brief Controls if the asserts are present.
*
* Asserts are removed if this symbol is defined
*
*****************************************************************************/
/**************************************************************************//**
* @def USER_ASSERT
* @brief User implemented assert function.
*
* When asserts are enabled the default handler can be be replaced with a user defined
* function of the form 'void userAssertName( const char * file, int line )' by setting
* the value of USER_ASSERT to the userAssertName.
*
*****************************************************************************/
/**************************************************************************//**
* @def SLAB_ASSERT(expr)
* @brief default implementation of assert_failed.
*
* This function can be replaced by a user defined assert function by setting the USER_ASSERT flag
*****************************************************************************/
#ifdef NDEBUG
#define SLAB_ASSERT(expr)
#else
#ifdef USER_ASSERT
#define SLAB_ASSERT(expr) ((expr) ? ((void)0) : USER_ASSERT( __FILE__, __LINE__ ))
#else
void slab_Assert();
//Yes this is smaller than if(!expr){assert}
#define SLAB_ASSERT(expr) if(expr){}else{slab_Assert();}
#endif
#endif
#endif //!__ASSERT_H__

View File

@@ -0,0 +1,63 @@
-------------------------------------------------------------------------------
Readme.txt
-------------------------------------------------------------------------------
Copyright 2014 Silicon Laboratories, Inc.
http://developer.silabs.com/legal/version/v11/Silicon_Labs_Software_License_Agreement.txt
Program Description:
-------------------
This is the generic EFM8 USB Firmware Library. Please see the EFM8 Libraries
Documentation for more information (/doc/EFM8/software/Lib/index.html).
Known Issues and Limitations:
----------------------------
1) The library does not reset its Data Toggle after receiving a SET_INTERFACE
request.
Target and Tool Chain Information:
---------------------------------
Target: EFM8UB1, EFM8UB2, EFM8UB3, EFM8UB4, C8051F320/1, C8051F326/7, C8051F34x, C8051F38x
Tool chain: Keil
File List:
---------
/inc/efm8_usb.h
/src/efm8_usbd.c
/src/efm8_usbdch9.c
/src/efm8_usbdep.c
/src/efm8_usbdint.c
Release Information:
-------------------
Version 1.0.0
- Initial release.
Version 1.0.1
- Fixed bug in logic of remote wakeup feature where the device would
attempt to wake the host before enabling its USB transceiver.
- Fixed bug where the device would stall the Data Phase instead of the
Setup Phase when sending a procedural stall on Endpoint 0.
- Fixed bug where a bus-powered device would look at VBUS after a USB Reset
to determine if it should enter the Default or Attached State. VBUS is
always present on a bus-powered device, so it should automatically enter
the Default State.
- Removed code that generated a compiler warning when
USB_PWRSAVE_MODE_FASTWAKE was enabled.
- Improved documentation of USB_PWRSAVE_MODE_FASTWAKE feature.
Version 1.0.2
- Added ability to detect short OUT packet in Isochronous mode and
stuff the buffer with zeroes to keep isochronous stream in sync.
Version 1.0.3
- Added support for EFM8UB3 and EFM8UB4 devices.
-------------------------------------------------------------------------------
End Of File
-------------------------------------------------------------------------------

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,780 @@
/**************************************************************************//**
* Copyright (c) 2015 by Silicon Laboratories Inc. All rights reserved.
*
* http://developer.silabs.com/legal/version/v11/Silicon_Labs_Software_License_Agreement.txt
*****************************************************************************/
#include "si_toolchain.h"
#include "efm8_usb.h"
#include "assert.h"
#include <stdint.h>
// -----------------------------------------------------------------------------
// Global Variables
/// Tracks the state of the USB device and endpoints and contains pointers
/// to all descriptors.
SI_SEGMENT_VARIABLE(myUsbDevice, USBD_Device_TypeDef, MEM_MODEL_SEG);
// -----------------------------------------------------------------------------
// Macros
/// Returns the requested endpoint object of type USBD_Ep_TypeDef
/// This macro does not check that epAddr is valid, so the calling function
/// should verify epAddr before using the macro.
#define GetEp(epAddr) (&myUsbDevice.ep0 + epAddr)
#if SLAB_USB_POLLED_MODE
#define DISABLE_USB_INTS {}
#define ENABLE_USB_INTS {}
#else
/// Saves the current state of the USB Interrupt Enable to a variable called
/// usbIntsEnabled, then disables USB interrupts.
#define DISABLE_USB_INTS { usbIntsEnabled = USB_GetIntsEnabled(); USB_DisableInts(); }
/// Sets the USB Interrupt Enable bit to the value of usbIntsEnabled.
/// @ref DISABLE_USB_INTS must be used before this macro is used.
#define ENABLE_USB_INTS { if (usbIntsEnabled) {USB_EnableInts(); } }
#endif // SLAB_USB_POLLED_MODE
// Function in efm8_usbdint.c to force load the module for libraries
extern void forceModuleLoad_usbint(void);
// -----------------------------------------------------------------------------
// USB API Functions
void USBD_AbortAllTransfers(void)
{
uint8_t i;
bool usbIntsEnabled;
USB_SaveSfrPage();
DISABLE_USB_INTS;
// Call USBD_AbortTransfer() for each endpoint
for (i = 1; i < SLAB_USB_NUM_EPS_USED; i++)
{
USBD_AbortTransfer(i);
}
ENABLE_USB_INTS;
USB_RestoreSfrPage();
}
int8_t USBD_AbortTransfer(uint8_t epAddr)
{
SI_VARIABLE_SEGMENT_POINTER(ep, USBD_Ep_TypeDef, MEM_MODEL_SEG);
int8_t retVal = USB_STATUS_OK;
bool usbIntsEnabled;
USB_SaveSfrPage();
// Verify this is a valid endpoint address and is not Endpoint 0.
if ((epAddr == EP0) || (epAddr >= SLAB_USB_NUM_EPS_USED))
{
SLAB_ASSERT(false);
retVal = USB_STATUS_ILLEGAL;
}
else
{
DISABLE_USB_INTS;
ep = GetEp(epAddr);
// If the state of the endpoint is already idle, there is not need to abort
// a transfer
if (ep->state != D_EP_IDLE)
{
switch (epAddr)
{
#if SLAB_USB_EP1IN_USED
case EP1IN:
USB_AbortInEp(1);
break;
#endif
#if SLAB_USB_EP2IN_USED
case EP2IN:
USB_AbortInEp(2);
break;
#endif
#if SLAB_USB_EP3IN_USED
case EP3IN:
USB_AbortInEp(3);
break;
#endif
#if SLAB_USB_EP1OUT_USED
case EP1OUT:
USB_AbortOutEp(1);
break;
#endif
#if SLAB_USB_EP2OUT_USED
case EP2OUT:
USB_AbortOutEp(2);
break;
#endif
#if SLAB_USB_EP3OUT_USED
case EP3OUT:
USB_AbortOutEp(3);
break;
#endif
}
// Set the endpoint state to idle and clear out endpoint state variables
ep->state = D_EP_IDLE;
ep->misc.c = 0;
}
}
ENABLE_USB_INTS;
USB_RestoreSfrPage();
return retVal;
}
void USBD_Connect(void)
{
USB_SaveSfrPage();
myUsbDevice.ep0.state = D_EP_IDLE;
USB_EnablePullUpResistor();
USB_EnableTransceiver();
USB_RestoreSfrPage();
}
void USBD_Disconnect(void)
{
USB_SaveSfrPage();
USB_DisablePullUpResistor();
USB_RestoreSfrPage();
}
bool USBD_EpIsBusy(uint8_t epAddr)
{
SI_VARIABLE_SEGMENT_POINTER(ep, USBD_Ep_TypeDef, MEM_MODEL_SEG);
// Verify this is a valid endpoint address
if (epAddr >= SLAB_USB_NUM_EPS_USED)
{
SLAB_ASSERT(false);
return true;
}
ep = GetEp(epAddr);
if (ep->state == D_EP_IDLE)
{
return false;
}
return true;
}
USBD_State_TypeDef USBD_GetUsbState(void)
{
return myUsbDevice.state;
}
int8_t USBD_Init(SI_VARIABLE_SEGMENT_POINTER(p, const USBD_Init_TypeDef, SI_SEG_GENERIC))
{
uint8_t i;
USB_SaveSfrPage();
USB_DisableInts();
// This forces the liner to bring in the contents efm8_usbdint
// It is place here since all users MUST call this function
// for the library to work properly
forceModuleLoad_usbint();
// Zero out the myUsbDevice struct, then initialize all non-zero members
for (i = 0; i < sizeof(myUsbDevice); i++)
{
*((SI_VARIABLE_SEGMENT_POINTER(, uint8_t, MEM_MODEL_SEG))&myUsbDevice + i) = 0;
}
// Get the USB descriptors from p
myUsbDevice.deviceDescriptor = p->deviceDescriptor;
myUsbDevice.configDescriptor = p->configDescriptor;
myUsbDevice.stringDescriptors = p->stringDescriptors;
myUsbDevice.numberOfStrings = p->numberOfStrings;
// Enable USB clock
#if SLAB_USB_FULL_SPEED
USB_SetClockIntOsc();
USB_SelectFullSpeed();
#else
USB_SetClockIntOscDiv8();
USB_SelectLowSpeed();
#endif // SLAB_USB_FULL_SPEED
// Enable or disable VBUS detection
#if SLAB_USB_BUS_POWERED
USB_VbusDetectDisable();
#else
USB_VbusDetectEnable();
#endif
USB_ForceReset();
USB_EnableDeviceInts();
USBD_Connect();
// If VBUS is present, the state should be Default.
// Otherwise, it is Attached.
#if SLAB_USB_BUS_POWERED
myUsbDevice.state = USBD_STATE_DEFAULT;
#else
if (USB_IsVbusOn())
{
myUsbDevice.state = USBD_STATE_DEFAULT;
}
else
{
myUsbDevice.state = USBD_STATE_ATTACHED;
}
#endif
// Only enable USB interrupts when not in polled mode
#if (SLAB_USB_POLLED_MODE == 0)
USB_EnableInts();
#endif
USB_RestoreSfrPage();
USB_DisableInhibit();
return USB_STATUS_OK;
}
int8_t USBD_Read(uint8_t epAddr,
SI_VARIABLE_SEGMENT_POINTER(dat, uint8_t, SI_SEG_GENERIC),
uint16_t byteCount,
bool callback)
{
bool usbIntsEnabled;
SI_VARIABLE_SEGMENT_POINTER(ep, USBD_Ep_TypeDef, MEM_MODEL_SEG);
USB_SaveSfrPage();
// Verify the endpoint address is valid.
switch (epAddr)
{
case EP0:
#if SLAB_USB_EP1OUT_USED
case EP1OUT:
#endif
#if SLAB_USB_EP2OUT_USED
case EP2OUT:
#endif
#if SLAB_USB_EP3OUT_USED
case EP3OUT:
#endif
break;
#if SLAB_USB_EP1IN_USED
case EP1IN:
#endif
#if SLAB_USB_EP2IN_USED
case EP2IN:
#endif
#if SLAB_USB_EP3IN_USED
case EP3IN:
#endif
default:
SLAB_ASSERT(false);
return USB_STATUS_ILLEGAL;
}
// If the device has not been configured, we cannot start a transfer.
if ((epAddr != EP0) && (myUsbDevice.state != USBD_STATE_CONFIGURED))
{
return USB_STATUS_DEVICE_UNCONFIGURED;
}
ep = GetEp(epAddr);
// If the endpoint is not idle, we cannot start a new transfer.
// Return the appropriate error code.
if (ep->state != D_EP_IDLE)
{
if (ep->state == D_EP_STALL)
{
return USB_STATUS_EP_STALLED;
}
else
{
return USB_STATUS_EP_BUSY;
}
}
DISABLE_USB_INTS;
ep->buf = dat;
ep->remaining = byteCount;
ep->state = D_EP_RECEIVING;
ep->misc.bits.callback = callback;
ep->misc.bits.waitForRead = false;
// If isochronous, set the buffer index to 0
#if ((SLAB_USB_EP3OUT_USED) && (SLAB_USB_EP3OUT_TRANSFER_TYPE == USB_EPTYPE_ISOC))
if (epAddr == EP3OUT)
{
myUsbDevice.ep3outIsoIdx = 0;
}
#endif
ENABLE_USB_INTS;
USB_RestoreSfrPage();
return USB_STATUS_OK;
}
#if SLAB_USB_REMOTE_WAKEUP_ENABLED
int8_t USBD_RemoteWakeup(void)
{
// The device must be suspended and Remote Wakeup must have been previously
// configured with a SET_FEATURE (Remote Wakeup) command.
if ((myUsbDevice.state != USBD_STATE_SUSPENDED) ||
(myUsbDevice.remoteWakeupEnabled == false))
{
return USB_STATUS_ILLEGAL;
}
USB_ForceResume();
USBD_RemoteWakeupDelay(); // Application will provide the delay between
// starting and stopping the resume signal.
USB_ClearResume();
return USB_STATUS_OK;
}
#endif // SLAB_USB_REMOTE_WAKEUP_ENABLED
#if SLAB_USB_POLLED_MODE
void USBD_Run(void)
{
usbIrqHandler();
}
#endif // SLAB_USB_POLLED_MODE
int8_t USBD_StallEp(uint8_t epAddr)
{
bool usbIntsEnabled;
USB_SaveSfrPage();
// Verify the endpoint address is valid and not Endpoint 0.
if ((epAddr == EP0) || (epAddr >= SLAB_USB_NUM_EPS_USED))
{
SLAB_ASSERT(false);
return USB_STATUS_ILLEGAL;
}
DISABLE_USB_INTS;
// Halt the appropriate endpoint by sending a stall and setting the endpoint
// state to Halted (D_EP_HALT).
switch (epAddr)
{
#if SLAB_USB_EP1IN_USED
case (EP1IN):
myUsbDevice.ep1in.state = D_EP_HALT;
USB_SetIndex(1);
USB_EpnInStall();
break;
#endif
#if SLAB_USB_EP2IN_USED
case (EP2IN):
myUsbDevice.ep2in.state = D_EP_HALT;
USB_SetIndex(2);
USB_EpnInStall();
break;
#endif
#if SLAB_USB_EP3IN_USED
case (EP3IN):
myUsbDevice.ep3in.state = D_EP_HALT;
USB_SetIndex(3);
USB_EpnInStall();
break;
#endif
#if SLAB_USB_EP1OUT_USED
case (EP1OUT):
myUsbDevice.ep1out.state = D_EP_HALT;
USB_SetIndex(1);
USB_EpnOutStall();
break;
#endif
#if SLAB_USB_EP2OUT_USED
case (EP2OUT):
myUsbDevice.ep2out.state = D_EP_HALT;
USB_SetIndex(2);
USB_EpnOutStall();
break;
#endif
#if SLAB_USB_EP3OUT_USED
case (EP3OUT):
myUsbDevice.ep3out.state = D_EP_HALT;
USB_SetIndex(3);
USB_EpnOutStall();
break;
#endif
}
ENABLE_USB_INTS;
USB_RestoreSfrPage();
return USB_STATUS_OK;
}
void USBD_Stop(void)
{
USB_DisableInts();
USBD_Disconnect();
USBD_SetUsbState(USBD_STATE_NONE);
}
void USBD_Suspend(void)
{
#if (!(SLAB_USB_PWRSAVE_MODE & USB_PWRSAVE_MODE_FASTWAKE))
uint8_t i;
#endif
bool regulatorEnabled, prefetchEnabled;
#if SLAB_USB_REMOTE_WAKEUP_ENABLED
bool remoteWakeup = false;
#endif
USB_SaveSfrPage();
// If the USB_PWRSAVE_MODE_ONVBUSOFF is enabled, we can enter suspend if VBUS
// is not present even if the USB has not detected a suspend event.
#if ((!(SLAB_USB_PWRSAVE_MODE & USB_PWRSAVE_MODE_ONVBUSOFF)) || \
(SLAB_USB_BUS_POWERED))
if (USB_IsSuspended() == true)
#else
if ((USB_IsSuspended() == true) || (USB_IsVbusOn() == false))
#endif
{
USB_SuspendTransceiver();
#if SLAB_USB_FULL_SPEED
USB_SetSuspendClock();
#endif
// Get the state of the prefetch engine enable bit and disable the prefetch
// engine
prefetchEnabled = USB_IsPrefetchEnabled();
USB_DisablePrefetch();
// Get the state of the internal regulator before suspending it.
if (USB_IsRegulatorEnabled() == true)
{
regulatorEnabled = true;
#if (SLAB_USB_PWRSAVE_MODE & USB_PWRSAVE_MODE_FASTWAKE)
USB_SuspendRegulatorFastWake();
#else
USB_SuspendRegulator();
// Wait at least 12 clock instructions before halting the internal oscillator
for (i = 0; i < 3; i++)
{
}
#endif
}
else
{
regulatorEnabled = false;
}
do
{
USB_SuspendOscillator();
// When we arrive here, the device has waked from suspend mode.
#if SLAB_USB_REMOTE_WAKEUP_ENABLED
// If remote wakeup is enabled, query the application if the remote
// wakeup event occurred. If so, exit USBD_Suspend().
if (USB_IsSuspended() == true)
{
remoteWakeup = USBD_RemoteWakeupCb();
if (remoteWakeup == true)
{
break;
}
}
#endif
#if ((!(SLAB_USB_PWRSAVE_MODE & USB_PWRSAVE_MODE_ONVBUSOFF)) && \
(SLAB_USB_BUS_POWERED == 0))
// If the USB_PWRSAVE_MODE_ONVBUSOFF mode is disabled, VBUS has been
// removed, so exit USBD_Suspend().
if (USB_IsVbusOn() == false)
{
break;
}
#endif
#if ((!(SLAB_USB_PWRSAVE_MODE & USB_PWRSAVE_MODE_ONVBUSOFF)) || \
(SLAB_USB_BUS_POWERED))
} while (USB_IsSuspended() == true);
#else
} while ((USB_IsSuspended() == true) || (USB_IsVbusOn() == false));
#endif
// Restore the internal regulator
if (regulatorEnabled == true)
{
USB_UnsuspendRegulator();
}
// Restore the prefetch engine
if (prefetchEnabled == true)
{
USB_EnablePrefetch();
}
#if SLAB_USB_FULL_SPEED
// Restore the clock
USB_SetNormalClock();
#endif
USB_EnableTransceiver();
#if SLAB_USB_REMOTE_WAKEUP_ENABLED
// If the device woke from suspend due to a remote wakeup source, call
// USBD_RemoteWakeup() here to wake up the host.
if (remoteWakeup == true)
{
// Wake up the host
if (USBD_RemoteWakeup() == USB_STATUS_OK)
{
// If the remote wakeup succeeded, transition out of USB suspend state
USBD_SetUsbState(myUsbDevice.savedState);
}
}
#endif
}
USB_RestoreSfrPage();
}
int8_t USBD_UnStallEp(uint8_t epAddr)
{
bool usbIntsEnabled;
USB_SaveSfrPage();
// Verify the endpoint address is valid and not Endpoint 0.
if ((epAddr == EP0) || (epAddr >= SLAB_USB_NUM_EPS_USED))
{
SLAB_ASSERT(false);
return USB_STATUS_ILLEGAL;
}
else
{
DISABLE_USB_INTS;
// End the stall condition and set the endpoint state to idle.
switch (epAddr)
{
#if SLAB_USB_EP1IN_USED
case (EP1IN):
myUsbDevice.ep1in.state = D_EP_IDLE;
USB_SetIndex(1);
USB_EpnInEndStall();
break;
#endif
#if SLAB_USB_EP2IN_USED
case (EP2IN):
myUsbDevice.ep2in.state = D_EP_IDLE;
USB_SetIndex(2);
USB_EpnInEndStall();
break;
#endif
#if SLAB_USB_EP3IN_USED
case (EP3IN):
myUsbDevice.ep3in.state = D_EP_IDLE;
USB_SetIndex(3);
USB_EpnInEndStall();
break;
#endif
#if SLAB_USB_EP1OUT_USED
case (EP1OUT):
myUsbDevice.ep1out.state = D_EP_IDLE;
USB_SetIndex(1);
USB_EpnOutEndStall();
break;
#endif
#if SLAB_USB_EP2OUT_USED
case (EP2OUT):
myUsbDevice.ep2out.state = D_EP_IDLE;
USB_SetIndex(2);
USB_EpnOutEndStall();
break;
#endif
#if SLAB_USB_EP3OUT_USED
case (EP3OUT):
myUsbDevice.ep3out.state = D_EP_IDLE;
USB_SetIndex(3);
USB_EpnOutEndStall();
break;
#endif
}
ENABLE_USB_INTS;
USB_RestoreSfrPage();
}
return USB_STATUS_OK;
}
int8_t USBD_Write(uint8_t epAddr,
SI_VARIABLE_SEGMENT_POINTER(dat, uint8_t, SI_SEG_GENERIC),
uint16_t byteCount,
bool callback)
{
bool usbIntsEnabled;
SI_VARIABLE_SEGMENT_POINTER(ep, USBD_Ep_TypeDef, MEM_MODEL_SEG);
USB_SaveSfrPage();
// Verify the endpoint address is valid.
switch (epAddr)
{
case EP0:
#if SLAB_USB_EP1IN_USED
case EP1IN:
#endif
#if SLAB_USB_EP2IN_USED
case EP2IN:
#endif
#if SLAB_USB_EP3IN_USED
case EP3IN:
#endif
break;
#if SLAB_USB_EP1OUT_USED
case EP1OUT:
#endif
#if SLAB_USB_EP2OUT_USED
case EP2OUT:
#endif
#if SLAB_USB_EP3OUT_USED
case EP3OUT:
#endif
default:
SLAB_ASSERT(false);
return USB_STATUS_ILLEGAL;
}
// If the device is not configured and it is not Endpoint 0, we cannot begin
// a transfer.
if ((epAddr != EP0) && (myUsbDevice.state != USBD_STATE_CONFIGURED))
{
return USB_STATUS_DEVICE_UNCONFIGURED;
}
ep = GetEp(epAddr);
// If the endpoint is not idle, we cannot start a new transfer.
// Return the appropriate error code.
if (ep->state != D_EP_IDLE)
{
if (ep->state == D_EP_STALL)
{
return USB_STATUS_EP_STALLED;
}
else
{
return USB_STATUS_EP_BUSY;
}
}
DISABLE_USB_INTS;
ep->buf = dat;
ep->remaining = byteCount;
ep->state = D_EP_TRANSMITTING;
ep->misc.bits.callback = callback;
switch (epAddr)
{
// For Endpoint 0, set the inPacketPending flag to true. The USB handler
// will see this on the next SOF and begin the transfer.
case (EP0):
myUsbDevice.ep0.misc.bits.inPacketPending = true;
break;
// For data endpoints, we will call USB_WriteFIFO here to reduce latency
// between the call to USBD_Write() and the first packet being sent.
#if SLAB_USB_EP1IN_USED
case (EP1IN):
USB_WriteFIFO(1,
(byteCount > SLAB_USB_EP1IN_MAX_PACKET_SIZE) ? SLAB_USB_EP1IN_MAX_PACKET_SIZE : byteCount,
myUsbDevice.ep1in.buf,
true);
break;
#endif // SLAB_USB_EP1IN_USED
#if SLAB_USB_EP2IN_USED
case (EP2IN):
USB_WriteFIFO(2,
(byteCount > SLAB_USB_EP2IN_MAX_PACKET_SIZE) ? SLAB_USB_EP2IN_MAX_PACKET_SIZE : byteCount,
myUsbDevice.ep2in.buf,
true);
break;
#endif // SLAB_USB_EP2IN_USED
#if SLAB_USB_EP3IN_USED
case (EP3IN):
#if ((SLAB_USB_EP3IN_TRANSFER_TYPE == USB_EPTYPE_BULK) || (SLAB_USB_EP3IN_TRANSFER_TYPE == USB_EPTYPE_INTR))
USB_WriteFIFO(3,
(byteCount > SLAB_USB_EP3IN_MAX_PACKET_SIZE) ? SLAB_USB_EP3IN_MAX_PACKET_SIZE : byteCount,
myUsbDevice.ep3in.buf,
true);
#elif (SLAB_USB_EP3IN_TRANSFER_TYPE == USB_EPTYPE_ISOC)
myUsbDevice.ep3in.misc.bits.inPacketPending = true;
myUsbDevice.ep3inIsoIdx = 0;
#endif
break;
#endif // SLAB_USB_EP3IN_USED
}
ENABLE_USB_INTS;
USB_RestoreSfrPage();
return USB_STATUS_OK;
}
// -----------------------------------------------------------------------------
// UtilityFunctions
void USBD_SetUsbState(USBD_State_TypeDef newState)
{
#if (SLAB_USB_SUPPORT_ALT_INTERFACES)
uint8_t i;
#endif
USBD_State_TypeDef currentState;
currentState = myUsbDevice.state;
// If the device is un-configuring, disable the data endpoints and clear out
// alternate interface settings
if ((currentState >= USBD_STATE_SUSPENDED)
&& (newState < USBD_STATE_SUSPENDED))
{
USBD_AbortAllTransfers();
#if (SLAB_USB_SUPPORT_ALT_INTERFACES)
for (i = 0; i < SLAB_USB_NUM_INTERFACES; i++)
{
myUsbDevice.interfaceAltSetting[i] = 0;
}
#endif
}
if (newState == USBD_STATE_SUSPENDED)
{
myUsbDevice.savedState = currentState;
}
myUsbDevice.state = newState;
#if SLAB_USB_STATE_CHANGE_CB
if (currentState != newState)
{
USBD_DeviceStateChangeCb(currentState, newState);
}
#endif
}

View File

@@ -0,0 +1,870 @@
/**************************************************************************//**
* Copyright (c) 2015 by Silicon Laboratories Inc. All rights reserved.
*
* http://developer.silabs.com/legal/version/v11/Silicon_Labs_Software_License_Agreement.txt
*****************************************************************************/
#include "si_toolchain.h"
#include "efm8_usb.h"
#include <stdint.h>
#include <endian.h>
// -----------------------------------------------------------------------------
// Function Prototypes
static USB_Status_TypeDef ClearFeature(void);
static USB_Status_TypeDef GetConfiguration(void);
static USB_Status_TypeDef GetDescriptor(void);
static USB_Status_TypeDef GetInterface(void);
static USB_Status_TypeDef GetStatus(void);
static USB_Status_TypeDef SetAddress(void);
static USB_Status_TypeDef SetConfiguration(void);
static USB_Status_TypeDef SetFeature(void);
static USB_Status_TypeDef SetInterface(void);
static void USBD_ActivateAllEps(bool forceIdle);
static void EP0_Write(SI_VARIABLE_SEGMENT_POINTER(dat, uint8_t, SI_SEG_GENERIC), uint16_t numBytes);
// -----------------------------------------------------------------------------
// Global Variables
extern SI_SEGMENT_VARIABLE(myUsbDevice, USBD_Device_TypeDef, MEM_MODEL_SEG);
const SI_SEGMENT_VARIABLE(txZero[2], uint8_t, SI_SEG_CODE);
// -----------------------------------------------------------------------------
// Static Global Variables
static uint16_t pStatus;
// -----------------------------------------------------------------------------
// Chapter 9 Functions
/***************************************************************************//**
* @brief Processes Standard Request (Chapter 9 Command)
* @return Status of request (type @ref USB_Status_TypeDef)
* @note This function takes no parameters, but it uses the setup command
* stored in @ref myUsbDevice.setup.
******************************************************************************/
USB_Status_TypeDef USBDCH9_SetupCmd(void)
{
USB_Status_TypeDef status = USB_STATUS_OK;
switch (myUsbDevice.setup.bRequest)
{
case GET_STATUS:
status = GetStatus();
break;
case CLEAR_FEATURE:
status = ClearFeature();
break;
case SET_FEATURE:
status = SetFeature();
break;
case SET_ADDRESS:
status = SetAddress();
break;
case GET_DESCRIPTOR:
status = GetDescriptor();
break;
case GET_CONFIGURATION:
status = GetConfiguration();
break;
case SET_CONFIGURATION:
status = SetConfiguration();
break;
case GET_INTERFACE:
status = GetInterface();
break;
case SET_INTERFACE:
status = SetInterface();
break;
default:
status = USB_STATUS_REQ_ERR;
break;
}
return status;
}
/***************************************************************************//**
* @brief Clears the requested feature
* @details Supports CLEAR_FEATURE for Remote Wakeup and Endpoint Halt
* @return Status of request (type @ref USB_Status_TypeDef)
* @note This function takes no parameters, but it uses the setup command
* stored in @ref myUsbDevice.setup.
******************************************************************************/
static USB_Status_TypeDef ClearFeature(void)
{
USB_Status_TypeDef retVal = USB_STATUS_REQ_ERR;
if (myUsbDevice.setup.wLength == 0)
{
switch (myUsbDevice.setup.bmRequestType.Recipient)
{
#if SLAB_USB_REMOTE_WAKEUP_ENABLED
case USB_SETUP_RECIPIENT_DEVICE:
if ((myUsbDevice.setup.wIndex == 0)
&& (myUsbDevice.setup.wValue == USB_FEATURE_DEVICE_REMOTE_WAKEUP)
&& (myUsbDevice.state >= USBD_STATE_ADDRESSED))
{
// Remote wakeup feature clear
myUsbDevice.remoteWakeupEnabled = false;
retVal = USB_STATUS_OK;
}
break;
#endif // SLAB_USB_REMOTE_WAKEUP_ENABLED
case USB_SETUP_RECIPIENT_ENDPOINT:
if (myUsbDevice.setup.wValue == USB_FEATURE_ENDPOINT_HALT)
{
// Device does not support halting endpoint 0, but do not return
// an error as this is a valid request
if (((myUsbDevice.setup.wIndex & ~USB_EP_DIR_IN) == 0)
&& (myUsbDevice.state >= USBD_STATE_ADDRESSED))
{
retVal = USB_STATUS_OK;
}
else if (((myUsbDevice.setup.wIndex & ~USB_SETUP_DIR_D2H) < SLAB_USB_NUM_EPS_USED)
&& (myUsbDevice.state == USBD_STATE_CONFIGURED))
{
retVal = USB_STATUS_OK;
USB_SetIndex((myUsbDevice.setup.wIndex & 0xFF) & ~USB_SETUP_DIR_D2H);
#if (SLAB_USB_EP1IN_USED || SLAB_USB_EP2IN_USED || SLAB_USB_EP3IN_USED)
if ((myUsbDevice.setup.wIndex & 0xFF) & USB_EP_DIR_IN)
{
USB_EpnInEndStallAndClearDataToggle();
}
#endif
#if (SLAB_USB_EP1OUT_USED || SLAB_USB_EP2OUT_USED || SLAB_USB_EP3OUT_USED)
if (((myUsbDevice.setup.wIndex & 0xFF) & USB_EP_DIR_IN) == 0)
{
USB_EpnOutEndStallAndClearDataToggle();
}
#endif
switch (myUsbDevice.setup.wIndex & 0xFF)
{
#if SLAB_USB_EP1OUT_USED
case (USB_EP_DIR_OUT | 1):
if (myUsbDevice.ep1out.state != D_EP_RECEIVING)
{
myUsbDevice.ep1out.state = D_EP_IDLE;
}
break;
#endif
#if SLAB_USB_EP2OUT_USED
case (USB_EP_DIR_OUT | 2):
if (myUsbDevice.ep2out.state != D_EP_RECEIVING)
{
myUsbDevice.ep2out.state = D_EP_IDLE;
}
break;
#endif
#if SLAB_USB_EP3OUT_USED
case (USB_EP_DIR_OUT | 3):
if (myUsbDevice.ep3out.state != D_EP_RECEIVING)
{
myUsbDevice.ep3out.state = D_EP_IDLE;
}
break;
#endif
#if SLAB_USB_EP1IN_USED
case (USB_EP_DIR_IN | 1):
if (myUsbDevice.ep1in.state != D_EP_TRANSMITTING)
{
myUsbDevice.ep1in.state = D_EP_IDLE;
}
break;
#endif
#if SLAB_USB_EP2IN_USED
case (USB_EP_DIR_IN | 2):
if (myUsbDevice.ep2in.state != D_EP_TRANSMITTING)
{
myUsbDevice.ep2in.state = D_EP_IDLE;
}
break;
#endif
#if SLAB_USB_EP3IN_USED
case (USB_EP_DIR_IN | 3):
if (myUsbDevice.ep3in.state != D_EP_TRANSMITTING)
{
myUsbDevice.ep3in.state = D_EP_IDLE;
}
break;
#endif
}
}
}
}
}
return retVal;
}
/***************************************************************************//**
* @brief Gets the current configuration value
* @details Zero means the device is not configured, a non-zero value
* is the configuration value of the configured device.
* @return Status of request (type @ref USB_Status_TypeDef)
* @note This function takes no parameters, but it uses the setup command
* stored in @ref myUsbDevice.setup.
******************************************************************************/
static USB_Status_TypeDef GetConfiguration(void)
{
USB_Status_TypeDef retVal = USB_STATUS_REQ_ERR;
if ((myUsbDevice.setup.wIndex == 0)
&& (myUsbDevice.setup.wValue == 0)
&& (myUsbDevice.setup.wLength == 1)
&& (myUsbDevice.setup.bmRequestType.Direction == USB_SETUP_DIR_IN)
&& (myUsbDevice.setup.bmRequestType.Recipient == USB_SETUP_RECIPIENT_DEVICE))
{
if (myUsbDevice.state == USBD_STATE_ADDRESSED)
{
EP0_Write((SI_VARIABLE_SEGMENT_POINTER(, uint8_t, SI_SEG_GENERIC))txZero, 1);
retVal = USB_STATUS_OK;
}
else if (myUsbDevice.state == USBD_STATE_CONFIGURED)
{
EP0_Write(&myUsbDevice.configurationValue, 1);
retVal = USB_STATUS_OK;
}
}
return retVal;
}
/***************************************************************************//**
* @brief Sends the requested USB Descriptor
* @details Supports single or multiple languages (configured by
* @ref SLAB_USB_NUM_LANGUAGES).
* @return Status of request (type @ref USB_Status_TypeDef)
* @note This function takes no parameters, but it uses the setup command
* stored in @ref myUsbDevice.setup.
******************************************************************************/
static USB_Status_TypeDef GetDescriptor(void)
{
#if (SLAB_USB_NUM_LANGUAGES > 1)
bool langSupported;
uint8_t lang;
#endif
uint8_t index;
uint16_t length = 0;
SI_VARIABLE_SEGMENT_POINTER(dat, uint8_t, SI_SEG_GENERIC);
USB_Status_TypeDef retVal = USB_STATUS_REQ_ERR;
if (*((uint8_t *)&myUsbDevice.setup.bmRequestType) ==
(USB_SETUP_DIR_D2H | USB_SETUP_TYPE_STANDARD | USB_SETUP_RECIPIENT_DEVICE))
{
index = myUsbDevice.setup.wValue & 0xFF;
switch (myUsbDevice.setup.wValue >> 8)
{
case USB_DEVICE_DESCRIPTOR:
if (index != 0)
{
break;
}
dat = (SI_VARIABLE_SEGMENT_POINTER(, uint8_t, SI_SEG_GENERIC))myUsbDevice.deviceDescriptor;
length = myUsbDevice.deviceDescriptor->bLength;
break;
case USB_CONFIG_DESCRIPTOR:
if (index != 0)
{
break;
}
dat = (SI_VARIABLE_SEGMENT_POINTER(, uint8_t, SI_SEG_GENERIC))myUsbDevice.configDescriptor;
length = le16toh(myUsbDevice.configDescriptor->wTotalLength);
break;
case USB_STRING_DESCRIPTOR:
#if (SLAB_USB_NUM_LANGUAGES == 1)
dat = (SI_VARIABLE_SEGMENT_POINTER(, uint8_t, SI_SEG_GENERIC))myUsbDevice.stringDescriptors[index];
// Index 0 is the language string. If SLAB_USB_NUM_LANGUAGES == 1, we
// know the length will be 4 and the format will be UTF16LE.
if (index == 0)
{
length = 4;
myUsbDevice.ep0String.encoding.type = USB_STRING_DESCRIPTOR_UTF16LE;
}
// Otherwise, verify the language is correct (either the value set as
// SLAB_USB_LANGUAGE in usbconfig.h, or 0).
else if ((myUsbDevice.setup.wIndex == 0) || (myUsbDevice.setup.wIndex == SLAB_USB_LANGUAGE))
{
// Verify the index is valid
if (index < myUsbDevice.numberOfStrings)
{
length = *(dat + USB_STRING_DESCRIPTOR_LENGTH);
myUsbDevice.ep0String.encoding.type = *(dat + USB_STRING_DESCRIPTOR_ENCODING);
dat += USB_STRING_DESCRIPTOR_LENGTH;
myUsbDevice.ep0String.encoding.init = true;
}
}
#elif (SLAB_USB_NUM_LANGUAGES > 1)
langSupported = false;
// Index 0 is the language.
if (index == 0)
{
dat = ((SI_VARIABLE_SEGMENT_POINTER(, uint8_t, SI_SEG_GENERIC))myUsbDevice.stringDescriptors->languageArray[0][index]);
length = *((uint8_t *)dat);
myUsbDevice.ep0String.encoding.type = USB_STRING_DESCRIPTOR_UTF16LE;
}
else
{
// Otherwise, verify the language is one of the supported languages or 0.
for (lang = 0; lang < SLAB_USB_NUM_LANGUAGES; lang++)
{
if ((myUsbDevice.stringDescriptors->languageIDs[lang] == myUsbDevice.setup.wIndex)
|| (myUsbDevice.stringDescriptors->languageIDs[lang] == 0))
{
langSupported = true;
break;
}
}
if ((langSupported == true) && (index < myUsbDevice.numberOfStrings))
{
dat = ((SI_VARIABLE_SEGMENT_POINTER(, uint8_t, SI_SEG_GENERIC))myUsbDevice.stringDescriptors->languageArray[lang][index]);
length = *(dat + USB_STRING_DESCRIPTOR_LENGTH);
myUsbDevice.ep0String.encoding.type = *(dat + USB_STRING_DESCRIPTOR_ENCODING);
dat += USB_STRING_DESCRIPTOR_LENGTH;
if (myUsbDevice.ep0String.encoding.type == USB_STRING_DESCRIPTOR_UTF16LE_PACKED)
{
myUsbDevice.ep0String.encoding.init = true;
}
else
{
myUsbDevice.ep0String.encoding.init = false;
}
}
}
#endif // ( SLAB_USB_NUM_LANGUAGES == 1 )
}
// If there is a descriptor to send, get the proper length, then call
// EP0_Write() to send.
if (length)
{
if (length > myUsbDevice.setup.wLength)
{
length = myUsbDevice.setup.wLength;
}
EP0_Write(dat, length);
retVal = USB_STATUS_OK;
}
}
return retVal;
}
/***************************************************************************//**
* @brief Sends the current interface alternate setting
* @details Sends 0x0000 if alternate interfaces are not supported.
* @return Status of request (type @ref USB_Status_TypeDef)
* @note This function takes no parameters, but it uses the setup command
* stored in @ref myUsbDevice.setup.
******************************************************************************/
static USB_Status_TypeDef GetInterface(void)
{
uint16_t interface = myUsbDevice.setup.wIndex;
USB_Status_TypeDef retVal = USB_STATUS_REQ_ERR;
if ((interface < SLAB_USB_NUM_INTERFACES)
&& (myUsbDevice.setup.wLength == 1)
&& (myUsbDevice.setup.wValue == 0)
&& (*((uint8_t *)&myUsbDevice.setup.bmRequestType) ==
(USB_SETUP_DIR_D2H | USB_SETUP_TYPE_STANDARD | USB_SETUP_RECIPIENT_INTERFACE)))
{
if (myUsbDevice.state == USBD_STATE_CONFIGURED)
{
#if (SLAB_USB_SUPPORT_ALT_INTERFACES)
// Return the alternate setting for the specified interface
EP0_Write((SI_VARIABLE_SEGMENT_POINTER(, uint8_t, SI_SEG_GENERIC))&myUsbDevice.interfaceAltSetting[interface], 1);
#else
// Alternate interfaces are not supported, so return 0x0000.
EP0_Write((SI_VARIABLE_SEGMENT_POINTER(, uint8_t, SI_SEG_GENERIC))&txZero, 1);
#endif
retVal = USB_STATUS_OK;
}
}
return retVal;
}
/***************************************************************************//**
* @brief Sends the requested Remote Wakeup, Self-Powered, or
* Endpoint Status
* @return Status of request (type @ref USB_Status_TypeDef)
* @note This function takes no parameters, but it uses the setup command
* stored in @ref myUsbDevice.setup.
******************************************************************************/
static USB_Status_TypeDef GetStatus(void)
{
USB_Status_TypeDef retVal = USB_STATUS_REQ_ERR;
if ((myUsbDevice.setup.wLength == 2)
&& (myUsbDevice.setup.wValue == 0)
&& (myUsbDevice.setup.bmRequestType.Direction == USB_SETUP_DIR_IN)
&& (myUsbDevice.state >= USBD_STATE_ADDRESSED))
{
pStatus = htole16(0); // Default return value is 0x0000
switch (myUsbDevice.setup.bmRequestType.Recipient)
{
case USB_SETUP_RECIPIENT_DEVICE:
if (myUsbDevice.setup.wIndex == 0)
{
#if SLAB_USB_REMOTE_WAKEUP_ENABLED
// Remote wakeup feature status
if (myUsbDevice.remoteWakeupEnabled)
{
pStatus |= htole16(REMOTE_WAKEUP_ENABLED);
}
#endif // SLAB_USB_REMOTE_WAKEUP_ENABLED
#if SLAB_USB_IS_SELF_POWERED_CB
// Current self/bus power status
if (USBD_IsSelfPoweredCb())
{
pStatus |= htole16(DEVICE_IS_SELFPOWERED);
}
#elif (SLAB_USB_BUS_POWERED == 0)
pStatus |= htole16(DEVICE_IS_SELFPOWERED);
#endif // SLAB_USB_IS_SELF_POWERED_CB
retVal = USB_STATUS_OK;
}
break;
case USB_SETUP_RECIPIENT_INTERFACE:
if (myUsbDevice.setup.wIndex < SLAB_USB_NUM_INTERFACES)
{
retVal = USB_STATUS_OK;
}
break;
case USB_SETUP_RECIPIENT_ENDPOINT:
// Device does not support halting endpoint 0, but do not give
// an error as this is a valid request
if (((myUsbDevice.setup.wIndex & ~USB_EP_DIR_IN) == 0)
&& (myUsbDevice.state == USBD_STATE_ADDRESSED))
{
retVal = USB_STATUS_OK;
}
else if (myUsbDevice.state == USBD_STATE_CONFIGURED)
{
switch (myUsbDevice.setup.wIndex & 0xFF)
{
#if SLAB_USB_EP1OUT_USED
case (USB_EP_DIR_OUT | 1):
if (myUsbDevice.ep1out.state == D_EP_HALT)
{
pStatus = htole16(1);
}
retVal = USB_STATUS_OK;
break;
#endif
#if SLAB_USB_EP2OUT_USED
case (USB_EP_DIR_OUT | 2):
if (myUsbDevice.ep2out.state == D_EP_HALT)
{
pStatus = htole16(1);
}
retVal = USB_STATUS_OK;
break;
#endif
#if SLAB_USB_EP3OUT_USED
case (USB_EP_DIR_OUT | 3):
if (myUsbDevice.ep3out.state == D_EP_HALT)
{
pStatus = htole16(1);
}
retVal = USB_STATUS_OK;
break;
#endif
#if SLAB_USB_EP1IN_USED
case (USB_EP_DIR_IN | 1):
if (myUsbDevice.ep1in.state == D_EP_HALT)
{
pStatus = htole16(1);
}
retVal = USB_STATUS_OK;
break;
#endif
#if SLAB_USB_EP2IN_USED
case (USB_EP_DIR_IN | 2):
if (myUsbDevice.ep2in.state == D_EP_HALT)
{
pStatus = htole16(1);
}
retVal = USB_STATUS_OK;
break;
#endif
#if SLAB_USB_EP3IN_USED
case (USB_EP_DIR_IN | 3):
if (myUsbDevice.ep3in.state == D_EP_HALT)
{
pStatus = htole16(1);
}
retVal = USB_STATUS_OK;
break;
#endif
}
}
break;
}
// If the command was valid, send the requested status.
if (retVal == USB_STATUS_OK)
{
EP0_Write((SI_VARIABLE_SEGMENT_POINTER(, uint8_t, SI_SEG_GENERIC))&pStatus, 2);
}
}
return retVal;
}
/***************************************************************************//**
* @brief Sets the Address
* @return Status of request (type @ref USB_Status_TypeDef)
* @note This function takes no parameters, but it uses the setup command
* stored in @ref myUsbDevice.setup.
******************************************************************************/
static USB_Status_TypeDef SetAddress(void)
{
USB_Status_TypeDef retVal = USB_STATUS_REQ_ERR;
if ((myUsbDevice.setup.wValue < 128)
&& (myUsbDevice.setup.wLength == 0)
&& (myUsbDevice.setup.bmRequestType.Recipient == USB_SETUP_RECIPIENT_DEVICE)
&& (myUsbDevice.setup.wIndex == 0))
{
// If the device is in the Default state and the address is non-zero, put
// the device in the Addressed state.
if (myUsbDevice.state == USBD_STATE_DEFAULT)
{
if (myUsbDevice.setup.wValue != 0)
{
USBD_SetUsbState(USBD_STATE_ADDRESSED);
}
retVal = USB_STATUS_OK;
}
// If the device is already addressed and the address is zero, put the
// device in the Default state.
else if (myUsbDevice.state == USBD_STATE_ADDRESSED)
{
if (myUsbDevice.setup.wValue == 0)
{
USBD_SetUsbState(USBD_STATE_DEFAULT);
}
retVal = USB_STATUS_OK;
}
// Set the new address if the request was valid.
if (retVal == USB_STATUS_OK)
{
USB_SetAddress(myUsbDevice.setup.wValue);
}
}
return retVal;
}
/***************************************************************************//**
* @brief Sets the Configuration
* @return Status of request (type @ref USB_Status_TypeDef)
* @note This function takes no parameters, but it uses the setup command
* stored in @ref myUsbDevice.setup.
******************************************************************************/
static USB_Status_TypeDef SetConfiguration(void)
{
USB_Status_TypeDef retVal = USB_STATUS_REQ_ERR;
if (((myUsbDevice.setup.wValue >> 8) == 0)
&& (myUsbDevice.setup.bmRequestType.Recipient == USB_SETUP_RECIPIENT_DEVICE)
&& (myUsbDevice.setup.wLength == 0)
&& (myUsbDevice.setup.wIndex == 0))
{
// If the device is in the Addressed state and a valid Configuration value
// was sent, enter the Configured state.
if (myUsbDevice.state == USBD_STATE_ADDRESSED)
{
if ((myUsbDevice.setup.wValue == 0)
|| (myUsbDevice.setup.wValue == myUsbDevice.configDescriptor->bConfigurationValue))
{
myUsbDevice.configurationValue = myUsbDevice.setup.wValue;
if (myUsbDevice.setup.wValue == myUsbDevice.configDescriptor->bConfigurationValue)
{
USBD_ActivateAllEps(true);
USBD_SetUsbState(USBD_STATE_CONFIGURED);
}
retVal = USB_STATUS_OK;
}
}
// If the device is in the Configured state and Configuration zero is sent,
// abort all transfer and enter the Addressed state.
else if (myUsbDevice.state == USBD_STATE_CONFIGURED)
{
if ((myUsbDevice.setup.wValue == 0)
|| (myUsbDevice.setup.wValue == myUsbDevice.configDescriptor->bConfigurationValue))
{
myUsbDevice.configurationValue = myUsbDevice.setup.wValue;
if (myUsbDevice.setup.wValue == 0)
{
USBD_SetUsbState(USBD_STATE_ADDRESSED);
USBD_AbortAllTransfers();
}
else
{
// Reenable device endpoints, will reset data toggles
USBD_ActivateAllEps(false);
}
retVal = USB_STATUS_OK;
}
}
}
return retVal;
}
/***************************************************************************//**
* @brief Sets the Remote Wakeup or Endpoint Halt Feature
* @return Status of request (type @ref USB_Status_TypeDef)
* @note This function takes no parameters, but it uses the setup command
* stored in @ref myUsbDevice.setup.
******************************************************************************/
static USB_Status_TypeDef SetFeature(void)
{
USB_Status_TypeDef retVal = USB_STATUS_REQ_ERR;
if (myUsbDevice.setup.wLength == 0)
{
switch (myUsbDevice.setup.bmRequestType.Recipient)
{
#if SLAB_USB_REMOTE_WAKEUP_ENABLED
case USB_SETUP_RECIPIENT_DEVICE:
if ((myUsbDevice.setup.wIndex == 0) // ITF no. 0
&& (myUsbDevice.setup.wValue == USB_FEATURE_DEVICE_REMOTE_WAKEUP)
&& (myUsbDevice.state == USBD_STATE_CONFIGURED))
{
myUsbDevice.remoteWakeupEnabled = true;
retVal = USB_STATUS_OK;
}
break;
#endif // SLAB_USB_REMOTE_WAKEUP_ENABLED
case USB_SETUP_RECIPIENT_ENDPOINT:
// Device does not support halting endpoint 0, but do not return
// an error as this is a valid request
if (((myUsbDevice.setup.wIndex & ~USB_EP_DIR_IN) == 0)
&& (myUsbDevice.state >= USBD_STATE_ADDRESSED))
{
retVal = USB_STATUS_OK;
}
else if ((((myUsbDevice.setup.wIndex) & ~USB_SETUP_DIR_D2H) < SLAB_USB_NUM_EPS_USED)
&& (myUsbDevice.setup.wValue == USB_FEATURE_ENDPOINT_HALT)
&& (myUsbDevice.state == USBD_STATE_CONFIGURED))
{
retVal = USB_STATUS_OK;
USB_SetIndex((myUsbDevice.setup.wIndex & 0xFF) & ~USB_SETUP_DIR_D2H);
// Enable Stalls on the specified endpoint.
#if (SLAB_USB_EP1IN_USED || SLAB_USB_EP2IN_USED || SLAB_USB_EP3IN_USED)
if ((myUsbDevice.setup.wIndex & 0xFF) & USB_EP_DIR_IN)
{
USB_EpnInStall();
}
#endif
#if (SLAB_USB_EP1OUT_USED || SLAB_USB_EP2OUT_USED || SLAB_USB_EP3OUT_USED)
if (((myUsbDevice.setup.wIndex & 0xFF) & USB_EP_DIR_IN) == 0)
{
USB_EpnOutStall();
}
#endif
// Put the specified endpoint in the Halted state.
switch (myUsbDevice.setup.wIndex & 0xFF)
{
#if SLAB_USB_EP1OUT_USED
case (USB_EP_DIR_OUT | 1):
myUsbDevice.ep1out.state = D_EP_HALT;
break;
#endif
#if SLAB_USB_EP2OUT_USED
case (USB_EP_DIR_OUT | 2):
myUsbDevice.ep2out.state = D_EP_HALT;
break;
#endif
#if SLAB_USB_EP3OUT_USED
case (USB_EP_DIR_OUT | 3):
myUsbDevice.ep3out.state = D_EP_HALT;
break;
#endif
#if SLAB_USB_EP1IN_USED
case (USB_EP_DIR_IN | 1):
myUsbDevice.ep1in.state = D_EP_HALT;
break;
#endif
#if SLAB_USB_EP2IN_USED
case (USB_EP_DIR_IN | 2):
myUsbDevice.ep2in.state = D_EP_HALT;
break;
#endif
#if SLAB_USB_EP3IN_USED
case (USB_EP_DIR_IN | 3):
myUsbDevice.ep3in.state = D_EP_HALT;
break;
#endif
}
}
}
}
return retVal;
}
/***************************************************************************//**
* @brief Sets the Interface and Alternate Interface (if supported)
* @return Status of request (type @ref USB_Status_TypeDef)
* @note This function takes no parameters, but it uses the setup command
* stored in @ref myUsbDevice.setup.
******************************************************************************/
static USB_Status_TypeDef SetInterface(void)
{
USB_Status_TypeDef retVal = USB_STATUS_REQ_ERR;
uint8_t interface = (uint8_t)myUsbDevice.setup.wIndex;
uint8_t altSetting = (uint8_t)myUsbDevice.setup.wValue;
if ((interface < SLAB_USB_NUM_INTERFACES)
&& (myUsbDevice.state == USBD_STATE_CONFIGURED)
&& (myUsbDevice.setup.wLength == 0)
#if (SLAB_USB_SUPPORT_ALT_INTERFACES == 0)
&& (altSetting == 0)
#endif
&& (myUsbDevice.setup.bmRequestType.Recipient == USB_SETUP_RECIPIENT_INTERFACE))
{
#if (SLAB_USB_SUPPORT_ALT_INTERFACES)
if (USBD_SetInterfaceCb(interface, altSetting) == USB_STATUS_OK)
{
myUsbDevice.interfaceAltSetting[interface] = altSetting;
retVal = USB_STATUS_OK;
}
#else
#if (SLAB_USB_NUM_INTERFACES == 1)
// Reset data toggles on EP's
USBD_ActivateAllEps(false);
#endif // ( SLAB_USB_NUM_INTERFACES == 1 )
retVal = USB_STATUS_OK;
#endif // ( SLAB_USB_SUPPORT_ALT_INTERFACES )
}
return retVal;
}
// -----------------------------------------------------------------------------
// Utility Functions
/***************************************************************************//**
* @brief Enables all endpoints for data transfers
* @return Status of request (type @ref USB_Status_TypeDef)
* @note This function takes no parameters, but it uses the setup command
* stored in @ref myUsbDevice.setup.
******************************************************************************/
static void USBD_ActivateAllEps(bool forceIdle)
{
if (forceIdle == true)
{
#if SLAB_USB_EP1IN_USED
myUsbDevice.ep1in.state = D_EP_IDLE;
#endif
#if SLAB_USB_EP2IN_USED
myUsbDevice.ep2in.state = D_EP_IDLE;
#endif
#if SLAB_USB_EP3IN_USED
myUsbDevice.ep3in.state = D_EP_IDLE;
#endif
#if SLAB_USB_EP1OUT_USED
myUsbDevice.ep1out.state = D_EP_IDLE;
#endif
#if SLAB_USB_EP2OUT_USED
myUsbDevice.ep2out.state = D_EP_IDLE;
#endif
#if SLAB_USB_EP3OUT_USED
myUsbDevice.ep3out.state = D_EP_IDLE;
#endif
}
#if SLAB_USB_EP1IN_USED
USB_ActivateEp(1, // ep
SLAB_USB_EP1IN_MAX_PACKET_SIZE, // packetSize
1, // inDir
SLAB_USB_EP1OUT_USED, // splitMode
0); // isoMod
#endif // SLAB_USB_EP1IN_USED
#if SLAB_USB_EP2IN_USED
USB_ActivateEp(2, // ep
SLAB_USB_EP2IN_MAX_PACKET_SIZE, // packetSize
1, // inDir
SLAB_USB_EP2OUT_USED, // splitMode
0); // isoMod
#endif // SLAB_USB_EP2IN_USED
#if SLAB_USB_EP3IN_USED
USB_ActivateEp(3, // ep
SLAB_USB_EP3IN_MAX_PACKET_SIZE, // packetSize
1, // inDir
SLAB_USB_EP3OUT_USED, // splitMode
(SLAB_USB_EP3IN_TRANSFER_TYPE == USB_EPTYPE_ISOC)); // isoMod
#endif // SLAB_USB_EP3IN_USED
#if SLAB_USB_EP1OUT_USED
USB_ActivateEp(1, // ep
SLAB_USB_EP1OUT_MAX_PACKET_SIZE, // packetSize
0, // inDir
SLAB_USB_EP1IN_USED, // splitMode
0); // isoMod
#endif // SLAB_USB_EP1OUT_USED
#if SLAB_USB_EP2OUT_USED
USB_ActivateEp(2, // ep
SLAB_USB_EP2OUT_MAX_PACKET_SIZE, // packetSize
0, // inDir
SLAB_USB_EP2IN_USED, // splitMode
0); // isoMod
#endif // SLAB_USB_EP2OUT_USED
#if SLAB_USB_EP3OUT_USED
USB_ActivateEp(3, // ep
SLAB_USB_EP3OUT_MAX_PACKET_SIZE, // packetSize
0, // inDir
SLAB_USB_EP3IN_USED, // splitMode
(SLAB_USB_EP3OUT_TRANSFER_TYPE == USB_EPTYPE_ISOC)); // isoMod
#endif // SLAB_USB_EP1OUT_USED
}
/***************************************************************************//**
* @brief Sets up an Endpoint 0 Write
* @param dat
* Data to transmit on Endpoint 0
* @param numBytes
* Number of bytes to transmit on Endpoint 0
******************************************************************************/
static void EP0_Write(SI_VARIABLE_SEGMENT_POINTER(dat, uint8_t, SI_SEG_GENERIC), uint16_t numBytes)
{
if (myUsbDevice.ep0.state == D_EP_IDLE)
{
myUsbDevice.ep0.buf = dat;
myUsbDevice.ep0.remaining = numBytes;
myUsbDevice.ep0.state = D_EP_TRANSMITTING;
myUsbDevice.ep0.misc.c = 0;
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,687 @@
/**************************************************************************//**
* Copyright (c) 2015 by Silicon Laboratories Inc. All rights reserved.
*
* http://developer.silabs.com/legal/version/v11/Silicon_Labs_Software_License_Agreement.txt
*****************************************************************************/
#include "si_toolchain.h"
#include "efm8_usb.h"
#include <stdint.h>
#include <endian.h>
// -----------------------------------------------------------------------------
// Global variables
extern SI_SEGMENT_VARIABLE(myUsbDevice, USBD_Device_TypeDef, MEM_MODEL_SEG);
extern SI_SEGMENT_VARIABLE(txZero[2], const uint8_t, SI_SEG_CODE);
// -----------------------------------------------------------------------------
// Function prototypes
static void handleUsbEp0Int(void);
static void handleUsbResetInt(void);
static void handleUsbSuspendInt(void);
static void handleUsbResumeInt(void);
static void handleUsbEp0Tx(void);
static void handleUsbEp0Rx(void);
static void USB_ReadFIFOSetup(void);
#if (SLAB_USB_EP1IN_USED)
void handleUsbIn1Int(void);
#endif // SLAB_USB_EP1IN_USED
#if (SLAB_USB_EP2IN_USED)
void handleUsbIn2Int(void);
#endif // SLAB_USB_EP2IN_USED
#if (SLAB_USB_EP3IN_USED)
void handleUsbIn3Int(void);
#endif // SLAB_USB_EP3IN_USED
#if (SLAB_USB_EP1OUT_USED)
void handleUsbOut1Int(void);
#endif // SLAB_USB_EP1OUT_USED
#if (SLAB_USB_EP2OUT_USED)
void handleUsbOut2Int(void);
#endif // SLAB_USB_EP2OUT_USED
#if (SLAB_USB_EP3OUT_USED)
void handleUsbOut3Int(void);
#endif // SLAB_USB_EP3OUT_USED
void SendEp0Stall(void);
#if SLAB_USB_UTF8_STRINGS == 1
static uint8_t decodeUtf8toUcs2(
const uint8_t *pUtf8in,
SI_VARIABLE_SEGMENT_POINTER(pUcs2out, uint16_t, MEM_MODEL_SEG));
#endif
// -----------------------------------------------------------------------------
// Functions
/***************************************************************************//**
* @brief First-level handler for USB peripheral interrupt
* @details If @ref SLAB_USB_POLLED_MODE is 1, this becomes a regular
* function instead of an ISR and must be called by the application
* periodically.
******************************************************************************/
#if (SLAB_USB_POLLED_MODE == 0)
SI_INTERRUPT(usbIrqHandler, USB0_IRQn)
#else
void usbIrqHandler(void)
#endif
{
uint8_t statusCommon, statusIn, statusOut, indexSave;
#if SLAB_USB_HANDLER_CB
// Callback to user before processing
USBD_EnterHandler();
#endif
// Get the interrupt sources
statusCommon = USB_GetCommonInts();
statusIn = USB_GetInInts();
statusOut = USB_GetOutInts();
#if SLAB_USB_POLLED_MODE
if ((statusCommon == 0) && (statusIn == 0) && (statusOut == 0))
{
return;
}
#endif
// Save the current index
indexSave = USB_GetIndex();
// Check Common USB Interrupts
if (USB_IsSofIntActive(statusCommon))
{
#if SLAB_USB_SOF_CB
USBD_SofCb(USB_GetSofNumber());
#endif // SLAB_USB_SOF_CB
// Check for unhandled USB packets on EP0 and set the corresponding IN or
// OUT interrupt active flag if necessary.
if (((myUsbDevice.ep0.misc.bits.outPacketPending == true) && (myUsbDevice.ep0.state == D_EP_RECEIVING)) ||
((myUsbDevice.ep0.misc.bits.inPacketPending == true) && (myUsbDevice.ep0.state == D_EP_TRANSMITTING)))
{
USB_SetEp0IntActive(statusIn);
}
// Check for unhandled USB OUT packets and set the corresponding OUT
// interrupt active flag if necessary.
#if SLAB_USB_EP1OUT_USED
if ((myUsbDevice.ep1out.misc.bits.outPacketPending == true) && (myUsbDevice.ep1out.state == D_EP_RECEIVING))
{
USB_SetOut1IntActive(statusOut);
}
#endif
#if SLAB_USB_EP2OUT_USED
if ((myUsbDevice.ep2out.misc.bits.outPacketPending == true) && (myUsbDevice.ep2out.state == D_EP_RECEIVING))
{
USB_SetOut2IntActive(statusOut);
}
#endif
#if SLAB_USB_EP3OUT_USED
if ((myUsbDevice.ep3out.misc.bits.outPacketPending == true) && (myUsbDevice.ep3out.state == D_EP_RECEIVING))
{
USB_SetOut3IntActive(statusOut);
}
#endif
#if (SLAB_USB_EP3IN_USED && (SLAB_USB_EP3IN_TRANSFER_TYPE == USB_EPTYPE_ISOC))
if ((myUsbDevice.ep3in.misc.bits.inPacketPending == true) && (myUsbDevice.ep3in.state == D_EP_TRANSMITTING))
{
USB_SetIn3IntActive(statusIn);
}
#endif
}
if (USB_IsResetIntActive(statusCommon))
{
handleUsbResetInt();
// If VBUS is not present on detection of a USB reset, enter suspend mode.
#if (SLAB_USB_PWRSAVE_MODE & USB_PWRSAVE_MODE_ONVBUSOFF)
if (USB_IsVbusOn() == false)
{
USB_SetSuspendIntActive(statusCommon);
}
#endif
}
if (USB_IsResumeIntActive(statusCommon))
{
handleUsbResumeInt();
}
if (USB_IsSuspendIntActive(statusCommon))
{
handleUsbSuspendInt();
}
#if SLAB_USB_EP3IN_USED
if (USB_IsIn3IntActive(statusIn))
{
handleUsbIn3Int();
}
#endif // EP3IN_USED
#if SLAB_USB_EP3OUT_USED
if (USB_IsOut3IntActive(statusOut))
{
handleUsbOut3Int();
}
#endif // EP3OUT_USED
#if SLAB_USB_EP2IN_USED
if (USB_IsIn2IntActive(statusIn))
{
handleUsbIn2Int();
}
#endif // EP2IN_USED
#if SLAB_USB_EP1IN_USED
if (USB_IsIn1IntActive(statusIn))
{
handleUsbIn1Int();
}
#endif // EP1IN_USED
#if SLAB_USB_EP2OUT_USED
if (USB_IsOut2IntActive(statusOut))
{
handleUsbOut2Int();
}
#endif // EP2OUT_USED
#if SLAB_USB_EP1OUT_USED
if (USB_IsOut1IntActive(statusOut))
{
handleUsbOut1Int();
}
#endif // EP1OUT_USED
// Check USB Endpoint 0 Interrupt
if (USB_IsEp0IntActive(statusIn))
{
handleUsbEp0Int();
}
// Restore index
USB_SetIndex(indexSave);
#if SLAB_USB_HANDLER_CB
// Callback to user before exiting
USBD_ExitHandler();
#endif
}
/***************************************************************************//**
* @brief Handles Endpoint 0 transfer interrupt
******************************************************************************/
static void handleUsbEp0Int(void)
{
USB_Status_TypeDef retVal = USB_STATUS_REQ_UNHANDLED;
USB_SetIndex(0);
if (USB_Ep0SentStall() || USB_GetSetupEnd())
{
USB_Ep0ClearSentStall();
USB_ServicedSetupEnd();
myUsbDevice.ep0.state = D_EP_IDLE;
myUsbDevice.ep0.misc.c = 0;
}
if (USB_Ep0OutPacketReady())
{
if (myUsbDevice.ep0.misc.bits.waitForRead == true)
{
myUsbDevice.ep0.misc.bits.outPacketPending = true;
}
else if (myUsbDevice.ep0.state == D_EP_IDLE)
{
myUsbDevice.ep0String.c = USB_STRING_DESCRIPTOR_UTF16LE;
USB_ReadFIFOSetup();
// Vendor unique, Class or Standard setup commands override?
#if SLAB_USB_SETUP_CMD_CB
retVal = USBD_SetupCmdCb(&myUsbDevice.setup);
if (retVal == USB_STATUS_REQ_UNHANDLED)
{
#endif
if (myUsbDevice.setup.bmRequestType.Type == USB_SETUP_TYPE_STANDARD)
{
retVal = USBDCH9_SetupCmd();
}
#if SLAB_USB_SETUP_CMD_CB
}
#endif
// Reset index to 0 in case the call to USBD_SetupCmdCb() or
// USBDCH9_SetupCmd() changed it.
USB_SetIndex(0);
// Put the Enpoint 0 hardware into the correct state here.
if (retVal == USB_STATUS_OK)
{
// If wLength is 0, there is no Data Phase
// Set both the Serviced Out Packet Ready and Data End bits
if (myUsbDevice.setup.wLength == 0)
{
USB_Ep0SetLastOutPacketReady();
}
// If wLength is non-zero, there is a Data Phase.
// Set only the Serviced Out Packet Ready bit.
else
{
USB_Ep0ServicedOutPacketReady();
#if SLAB_USB_SETUP_CMD_CB
// If OUT packet but callback didn't set up a USBD_Read and we are expecting a
// data byte then we need to wait for the read to be setup and NACK packets until
// USBD_Read is called.
if ((myUsbDevice.setup.bmRequestType.Direction == USB_SETUP_DIR_OUT)
&& (myUsbDevice.ep0.state != D_EP_RECEIVING))
{
myUsbDevice.ep0.misc.bits.waitForRead = true;
}
#endif
}
}
// If the setup transaction detected an error, send a stall
else
{
SendEp0Stall();
}
}
else if (myUsbDevice.ep0.state == D_EP_RECEIVING)
{
handleUsbEp0Rx();
}
else
{
myUsbDevice.ep0.misc.bits.outPacketPending = true;
}
}
if ((myUsbDevice.ep0.state == D_EP_TRANSMITTING) && (USB_Ep0InPacketReady() == 0))
{
handleUsbEp0Tx();
}
}
/***************************************************************************//**
* @brief Reads and formats a setup packet
******************************************************************************/
static void USB_ReadFIFOSetup(void)
{
SI_VARIABLE_SEGMENT_POINTER(ptr, uint16_t, MEM_MODEL_SEG) = (SI_VARIABLE_SEGMENT_POINTER(, uint16_t, MEM_MODEL_SEG))&myUsbDevice.setup;
USB_ReadFIFO(0, 8, (SI_VARIABLE_SEGMENT_POINTER(, uint8_t, SI_SEG_GENERIC))ptr);
// Modify for Endian-ness of the compiler
ptr[1] = le16toh(ptr[1]);
ptr[2] = le16toh(ptr[2]);
ptr[3] = le16toh(ptr[3]);
}
/***************************************************************************//**
* @brief Handles USB port reset interrupt
* @details After receiving a USB reset, halt all endpoints except for
* Endpoint 0, set the device state, and configure USB hardware.
******************************************************************************/
static void handleUsbResetInt(void)
{
// Setup EP0 to receive SETUP packets
myUsbDevice.ep0.state = D_EP_IDLE;
// Halt all other endpoints
#if SLAB_USB_EP1IN_USED
myUsbDevice.ep1in.state = D_EP_HALT;
#endif
#if SLAB_USB_EP2IN_USED
myUsbDevice.ep2in.state = D_EP_HALT;
#endif
#if SLAB_USB_EP3IN_USED
myUsbDevice.ep3in.state = D_EP_HALT;
#endif
#if SLAB_USB_EP1OUT_USED
myUsbDevice.ep1out.state = D_EP_HALT;
#endif
#if SLAB_USB_EP2OUT_USED
myUsbDevice.ep2out.state = D_EP_HALT;
#endif
#if SLAB_USB_EP3OUT_USED
myUsbDevice.ep3out.state = D_EP_HALT;
#endif
// After a USB reset, some USB hardware configurations will be reset and must
// be reconfigured.
// Re-enable clock recovery
#if SLAB_USB_CLOCK_RECOVERY_ENABLED
#if SLAB_USB_FULL_SPEED
USB_EnableFullSpeedClockRecovery();
#else
USB_EnableLowSpeedClockRecovery();
#endif
#endif
// Re-enable USB interrupts
USB_EnableSuspendDetection();
USB_EnableDeviceInts();
// If the device is bus-powered, always put it in the Default state.
// If the device is self-powered and VBUS is present, put the device in the
// Default state. Otherwise, put it in the Attached state.
#if (!SLAB_USB_BUS_POWERED) && \
(!(SLAB_USB_PWRSAVE_MODE & USB_PWRSAVE_MODE_ONVBUSOFF))
if (USB_IsVbusOn())
{
USBD_SetUsbState(USBD_STATE_DEFAULT);
}
else
{
USBD_SetUsbState(USBD_STATE_ATTACHED);
}
#else
USBD_SetUsbState(USBD_STATE_DEFAULT);
#endif // (!(SLAB_USB_PWRSAVE_MODE & USB_PWRSAVE_MODE_ONVBUSOFF))
#if SLAB_USB_RESET_CB
// Make the USB Reset Callback
USBD_ResetCb();
#endif
}
/***************************************************************************//**
* @brief Handle USB port suspend interrupt
* @details After receiving a USB reset, set the device state and
* call @ref USBD_Suspend() if configured to do so in
* @ref SLAB_USB_PWRSAVE_MODE
******************************************************************************/
static void handleUsbSuspendInt(void)
{
if (myUsbDevice.state >= USBD_STATE_POWERED)
{
USBD_SetUsbState(USBD_STATE_SUSPENDED);
#if (SLAB_USB_PWRSAVE_MODE & USB_PWRSAVE_MODE_ONSUSPEND)
USBD_Suspend();
#endif
}
}
/***************************************************************************//**
* @brief Handles USB port resume interrupt
* @details Restore the device state to its previous value.
******************************************************************************/
static void handleUsbResumeInt(void)
{
USBD_SetUsbState(myUsbDevice.savedState);
}
/***************************************************************************//**
* @brief Handles transmit data phase on Endpoint 0
******************************************************************************/
static void handleUsbEp0Tx(void)
{
uint8_t count, count_snapshot, i;
bool callback = myUsbDevice.ep0.misc.bits.callback;
// The number of bytes to send in the next packet must be less than or equal
// to the maximum EP0 packet size.
count = (myUsbDevice.ep0.remaining >= USB_EP0_SIZE) ?
USB_EP0_SIZE : myUsbDevice.ep0.remaining;
// Save the packet size for future use.
count_snapshot = count;
// Strings can use the USB_STRING_DESCRIPTOR_UTF16LE_PACKED type to pack
// UTF16LE data without the zero's between each character.
// If the current string is of type USB_STRING_DESCRIPTOR_UTF16LE_PACKED,
// unpack it by inserting a zero between each character in the string.
if ((myUsbDevice.ep0String.encoding.type == USB_STRING_DESCRIPTOR_UTF16LE_PACKED)
#if SLAB_USB_UTF8_STRINGS == 1
|| (myUsbDevice.ep0String.encoding.type == USB_STRING_DESCRIPTOR_UTF8)
#endif
)
{
// If ep0String.encoding.init is true, this is the beginning of the string.
// The first two bytes of the string are the bLength and bDescriptorType
// fields. These are not packed like the reset of the string, so write them
// to the FIFO and set ep0String.encoding.init to false.
if (myUsbDevice.ep0String.encoding.init == true)
{
USB_WriteFIFO(0, 2, myUsbDevice.ep0.buf, false);
myUsbDevice.ep0.buf += 2;
count -= 2;
myUsbDevice.ep0String.encoding.init = false;
}
// Insert a 0x00 between each character of the string.
for (i = 0; i < count / 2; i++)
{
#if SLAB_USB_UTF8_STRINGS == 1
if (myUsbDevice.ep0String.encoding.type == USB_STRING_DESCRIPTOR_UTF8)
{
SI_SEGMENT_VARIABLE(ucs2, uint16_t, MEM_MODEL_SEG);
uint8_t utf8count;
// decode the utf8 into ucs2 for usb string
utf8count = decodeUtf8toUcs2(myUsbDevice.ep0.buf, &ucs2);
// if consumed utf8 bytes is 0, it means either null byte was
// input or bad utf8 byte sequence. Either way its an error and
// there's not much we can do. So just advance the input string
// by one character and keep going until count is expired.
if (utf8count == 0)
{
utf8count = 1;
}
// adjust to next char in utf8 byte sequence
myUsbDevice.ep0.buf += utf8count;
ucs2 = htole16(ucs2); // usb 16-bit chars are little endian
USB_WriteFIFO(0, 2, (SI_VARIABLE_SEGMENT_POINTER(, uint8_t, SI_SEG_GENERIC))&ucs2, false);
}
else
#endif
{
USB_WriteFIFO(0, 1, (SI_VARIABLE_SEGMENT_POINTER(, uint8_t, SI_SEG_GENERIC))myUsbDevice.ep0.buf, false);
myUsbDevice.ep0.buf++;
USB_WriteFIFO(0, 1, (SI_VARIABLE_SEGMENT_POINTER(, uint8_t, SI_SEG_GENERIC))&txZero, false);
}
}
}
// For any data other than USB_STRING_DESCRIPTOR_UTF16LE_PACKED, just send the
// data normally.
else
{
USB_WriteFIFO(0, count, myUsbDevice.ep0.buf, false);
myUsbDevice.ep0.buf += count;
}
myUsbDevice.ep0.misc.bits.inPacketPending = false;
myUsbDevice.ep0.remaining -= count_snapshot;
// If the last packet of the transfer is exactly the maximum EP0 packet size,
// we will have to send a ZLP (zero-length packet) after the last data packet
// to signal to the host that the transfer is complete.
// Check for the ZLP packet case here.
if ((myUsbDevice.ep0.remaining == 0) && (count_snapshot != USB_EP0_SIZE))
{
USB_Ep0SetLastInPacketReady();
myUsbDevice.ep0.state = D_EP_IDLE;
myUsbDevice.ep0String.c = USB_STRING_DESCRIPTOR_UTF16LE;
myUsbDevice.ep0.misc.c = 0;
}
else
{
// Do not call USB_Ep0SetLastInPacketReady() because we still need to send
// the ZLP.
USB_Ep0SetInPacketReady();
}
// Make callback if requested
if (callback == true)
{
USBD_XferCompleteCb(EP0, USB_STATUS_OK, count_snapshot, myUsbDevice.ep0.remaining);
}
}
/***************************************************************************//**
* @brief Handles receive data phase on Endpoint 0
******************************************************************************/
void handleUsbEp0Rx(void)
{
uint8_t count;
USB_Status_TypeDef status;
bool callback = myUsbDevice.ep0.misc.bits.callback;
// Get the number of bytes received
count = USB_Ep0GetCount();
// If the call to USBD_Read() did not give a large enough buffer to hold this
// data, set the outPacketPending flag and signal an RX overrun.
if (myUsbDevice.ep0.remaining < count)
{
myUsbDevice.ep0.state = D_EP_IDLE;
myUsbDevice.ep0.misc.bits.outPacketPending = true;
status = USB_STATUS_EP_RX_BUFFER_OVERRUN;
}
else
{
USB_ReadFIFO(0, count, myUsbDevice.ep0.buf);
myUsbDevice.ep0.buf += count;
myUsbDevice.ep0.remaining -= count;
status = USB_STATUS_OK;
// If the last packet of the transfer is exactly the maximum EP0 packet
// size, we will must wait to receive a ZLP (zero-length packet) after the
// last data packet. This signals that the host has completed the transfer.
// Check for the ZLP packet case here.
if ((myUsbDevice.ep0.remaining == 0) && (count != USB_EP0_SIZE))
{
USB_Ep0SetLastOutPacketReady();
myUsbDevice.ep0.state = D_EP_IDLE;
myUsbDevice.ep0.misc.bits.callback = false;
}
else
{
// Do not call USB_Ep0SetLastOutPacketReady() until we get the ZLP.
USB_Ep0ServicedOutPacketReady();
}
}
// Make callback if requested
if (callback == true)
{
USBD_XferCompleteCb(EP0, status, count, myUsbDevice.ep0.remaining);
}
}
/***************************************************************************//**
* @brief Send a procedural stall on Endpoint 0
******************************************************************************/
void SendEp0Stall(void)
{
USB_SetIndex(0);
myUsbDevice.ep0.state = D_EP_STALL;
USB_Ep0SendStall();
}
#if SLAB_USB_UTF8_STRINGS == 1
/***************************************************************************//**
* Decodes UTF-8 to UCS-2 (16-bit) character encoding that is used
* for USB string descriptors.
*
* @param pUtf8in pointer to next character in UTF-8 string
* @param pUcs2out pointer to location for 16-bit character output
*
* Decodes a UTF-8 byte sequence into a single UCS-2 character. This
* will only decode up to 16-bit code point and will not handle the
* 21-bit case (4 bytes input).
*
* For valid cases, the UTF8 character sequence decoded into a 16-bit
* character and stored at the location pointed at by _pUcs2out_.
* The function will then return the number of input bytes that were
* consumed (1, 2, or 3). The caller can use the return value to find
* the start of the next character sequence in a utf-8 string.
*
* If either of the input pointers are NULL, then 0 is returned.
*
* If the first input character is NULL, then the output 16-bit value
* will be set to NULL and the function will return 0.
*
* If any other invalid sequence is detected, then the 16-bit output
* will be set to the equivalent of the question mark character (0x003F)
* and the return code will be 0.
*
* @return count of UTF8 bytes consumed
******************************************************************************/
static uint8_t decodeUtf8toUcs2(
const uint8_t *pUtf8in,
SI_VARIABLE_SEGMENT_POINTER(pUcs2out, uint16_t, MEM_MODEL_SEG))
{
uint8_t ret = 0;
// check the input pointers
if (!pUtf8in || !pUcs2out)
{
return 0;
}
// set default decode to error '?';
*pUcs2out = '?';
// valid cases:
// 0xxxxxxx (7 bits)
// 110xxxxx 10xxxxxx (11 bits)
// 1110xxxx 10xxxxxx 10xxxxxx (16 bits)
// null input
if (pUtf8in[0] == 0)
{
*pUcs2out = 0;
ret = 0;
}
// 7-bit char
else if (pUtf8in[0] < 128)
{
*pUcs2out = pUtf8in[0];
ret = 1;
}
// 11-bit char
else if ((pUtf8in[0] & 0xE0) == 0xC0)
{
if ((pUtf8in[1] & 0xC0) == 0x80)
{
*pUcs2out = ((pUtf8in[0] & 0x1F) << 6) | (pUtf8in[1] & 0x3F);
ret = 2;
}
}
// 16-bit char
else if ((pUtf8in[0] & 0xF0) == 0xE0)
{
if ((pUtf8in[1] & 0xC0) == 0x80)
{
if ((pUtf8in[2] & 0xC0) == 0x80)
{
*pUcs2out = ((pUtf8in[0] & 0x0F) << 12)
| ((pUtf8in[1] & 0x3F) << 6)
| (pUtf8in[2] & 0x3F);
ret = 3;
}
}
}
return ret;
}
#endif // SLAB_USB_UTF8_STRINGS
// This function is called from USBD_Init(). It forces the user project to pull
// this module from the library so that the declared ISR can be seen and
// included. If this is not done then this entire module by never be included
// and the ISR will not be present.
void forceModuleLoad_usbint(void){}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,238 @@
/**************************************************************************//**
* Copyright (c) 2015 by Silicon Laboratories Inc. All rights reserved.
*
* http://developer.silabs.com/legal/version/v11/Silicon_Labs_Software_License_Agreement.txt
*****************************************************************************/
#include "usb_0.h"
#include <stdbool.h>
#include <stdint.h>
/** @addtogroup usb_0_runtime USB0 Runtime API */
// -----------------------------------------------------------------------------
// Functions
// -------------------------------
// Utility Functions
/**************************************************************************//**
* @brief Reads a 16-bit indirect USB register value
* @param [in] regAddr
* Address of high byte of 16-bit USB indirect register to read
* @return 16-bit register value
*****************************************************************************/
static uint16_t USB_GetShortRegister(uint8_t regAddr)
{
uint16_t retVal;
USB_READ_BYTE(regAddr);
retVal = (USB0DAT << 8);
USB_READ_BYTE((regAddr - 1));
retVal |= USB0DAT;
return retVal;
}
// -------------------------------
// USB0 Peripheral Driver Functions
void USB_SetIndex(uint8_t epsel)
{
USB_WRITE_BYTE(INDEX, epsel);
}
uint8_t USB_GetCommonInts(void)
{
USB_READ_BYTE(CMINT);
return USB0DAT;
}
uint8_t USB_GetInInts(void)
{
USB_READ_BYTE(IN1INT);
return USB0DAT;
}
uint8_t USB_GetOutInts(void)
{
USB_READ_BYTE(OUT1INT);
return USB0DAT;
}
uint8_t USB_GetIndex(void)
{
USB_READ_BYTE(INDEX);
return USB0DAT;
}
bool USB_IsSuspended(void)
{
USB_READ_BYTE(POWER);
return USB0DAT & POWER_SUSMD__SUSPENDED;
}
bool USB_GetSetupEnd(void)
{
USB_READ_BYTE(E0CSR);
return USB0DAT & E0CSR_SUEND__SET;
}
bool USB_Ep0SentStall(void)
{
USB_READ_BYTE(E0CSR);
return USB0DAT & E0CSR_STSTL__SET;
}
bool USB_Ep0OutPacketReady(void)
{
USB_READ_BYTE(E0CSR);
return USB0DAT & E0CSR_OPRDY__SET;
}
bool USB_Ep0InPacketReady(void)
{
USB_READ_BYTE(E0CSR);
return USB0DAT & E0CSR_INPRDY__SET;
}
uint8_t USB_Ep0GetCount(void)
{
USB_READ_BYTE(E0CNT);
return USB0DAT;
}
bool USB_EpnInGetSentStall(void)
{
USB_READ_BYTE(EINCSRL);
return (bool)(USB0DAT & EINCSRL_STSTL__SET);
}
void USB_AbortInEp(uint8_t fifoNum)
{
USB_SetIndex(fifoNum);
USB_EpnInFlush();
USB_EpnInFlush();
}
bool USB_EpnOutGetSentStall(void)
{
USB_READ_BYTE(EOUTCSRL);
return (bool)(USB0DAT & EOUTCSRL_STSTL__SET);
}
bool USB_EpnGetOutPacketReady(void)
{
USB_READ_BYTE(EOUTCSRL);
return (bool)(USB0DAT & EOUTCSRL_OPRDY__SET);
}
bool USB_EpnGetDataError(void)
{
USB_READ_BYTE(EOUTCSRL);
return (bool)(USB0DAT & EOUTCSRL_DATERR__SET);
}
uint16_t USB_EpOutGetCount(void)
{
return USB_GetShortRegister(EOUTCNTH);
}
void USB_AbortOutEp(uint8_t fifoNum)
{
USB_SetIndex(fifoNum);
USB_EpnOutFlush();
USB_EpnOutFlush();
}
void USB_ActivateEp(uint8_t ep,
uint16_t packetSize,
bool inDir,
bool splitMode,
bool isoMode)
{
uint8_t CSRH_mask = 0;
uint16_t fifoSize;
USB_SetIndex(ep);
// Determine the available fifoSize for a given endpoint based on the
// splitMode setting
fifoSize = (splitMode == true) ? (16 << ep) : (32 << ep);
if (packetSize <= fifoSize)
{
CSRH_mask |= EINCSRH_DBIEN__ENABLED;
}
if (isoMode == true)
{
CSRH_mask |= EINCSRH_ISO__ENABLED;
}
if (inDir == true)
{
CSRH_mask |= EINCSRH_DIRSEL__IN;
if (splitMode == true)
{
CSRH_mask |= EINCSRH_SPLIT__ENABLED;
}
USB_WRITE_BYTE(EINCSRL, EINCSRL_CLRDT__BMASK);
USB_WRITE_BYTE(EINCSRH, CSRH_mask);
}
else // OUT
{
USB_WRITE_BYTE(EOUTCSRL, EOUTCSRL_CLRDT__BMASK);
USB_WRITE_BYTE(EOUTCSRH, CSRH_mask);
if (splitMode == false)
{
USB_WRITE_BYTE(EINCSRH, 0);
}
}
}
uint16_t USB_GetSofNumber(void)
{
return USB_GetShortRegister(FRAMEH);
}
bool USB_GetIntsEnabled(void)
{
SFRPAGE = PG2_PAGE;
return (bool)(EIE2 & EIE2_EUSB0__ENABLED);
}
bool USB_IsPrefetchEnabled(void)
{
SFRPAGE = PG2_PAGE;
return (bool)(PFE0CN & PFE0CN_PFEN__ENABLED);
}
bool USB_IsRegulatorEnabled(void)
{
SFRPAGE = PG3_PAGE;
return !(REG1CN & REG1CN_REG1ENB__DISABLED);
}
void USB_SuspendOscillator(void)
{
uint8_t clkSelSave = CLKSEL & 0x7F;
CLKSEL = (CLKSEL_CLKDIV__SYSCLK_DIV_8 | CLKSEL_CLKSL__HFOSC0);
SFRPAGE = LEGACY_PAGE;
PCON1 |= PCON1_SUSPEND__SUSPEND;
CLKSEL = clkSelSave;
// If the target frequency is over 24MHz, our write to CLKSEL will be ignored.
// If this is the case we need to do two writes: one to 24 MHz followed by the
// actual value.
if ((CLKSEL & 0x7F) != clkSelSave)
{
CLKSEL = (CLKSEL_CLKDIV__SYSCLK_DIV_1 | CLKSEL_CLKSL__HFOSC0);
CLKSEL = clkSelSave;
}
}
/** @} (end addtogroup usb_0_runtime USB0 Runtime API) */

366
efm8/src/InitDevice.c Normal file
View File

@@ -0,0 +1,366 @@
//=========================================================
// src/InitDevice.c: generated by Hardware Configurator
//
// This file will be regenerated when saving a document.
// leave the sections inside the "$[...]" comment tags alone
// or they will be overwritten!
//=========================================================
// USER INCLUDES
#include <SI_EFM8UB1_Register_Enums.h>
#include "InitDevice.h"
// USER PROTOTYPES
// USER FUNCTIONS
// $[Library Includes]
#include "efm8_usb.h"
#include "descriptors.h"
#include "usb_0.h"
// [Library Includes]$
//==============================================================================
// enter_DefaultMode_from_RESET
//==============================================================================
extern void enter_DefaultMode_from_RESET(void) {
// $[Config Calls]
// Save the SFRPAGE
uint8_t SFRPAGE_save = SFRPAGE;
WDT_0_enter_DefaultMode_from_RESET();
PORTS_0_enter_DefaultMode_from_RESET();
PBCFG_0_enter_DefaultMode_from_RESET();
CIP51_0_enter_DefaultMode_from_RESET();
CLOCK_0_enter_DefaultMode_from_RESET();
TIMER16_2_enter_DefaultMode_from_RESET();
TIMER16_3_enter_DefaultMode_from_RESET();
TIMER_SETUP_0_enter_DefaultMode_from_RESET();
UARTE_1_enter_DefaultMode_from_RESET();
INTERRUPT_0_enter_DefaultMode_from_RESET();
USBLIB_0_enter_DefaultMode_from_RESET();
// Restore the SFRPAGE
SFRPAGE = SFRPAGE_save;
// [Config Calls]$
}
extern void INTERRUPT_0_enter_DefaultMode_from_RESET(void) {
// $[EIE1 - Extended Interrupt Enable 1]
// [EIE1 - Extended Interrupt Enable 1]$
// $[EIE2 - Extended Interrupt Enable 2]
// [EIE2 - Extended Interrupt Enable 2]$
// $[EIP1H - Extended Interrupt Priority 1 High]
// [EIP1H - Extended Interrupt Priority 1 High]$
// $[EIP1 - Extended Interrupt Priority 1 Low]
// [EIP1 - Extended Interrupt Priority 1 Low]$
// $[EIP2 - Extended Interrupt Priority 2]
// [EIP2 - Extended Interrupt Priority 2]$
// $[EIP2H - Extended Interrupt Priority 2 High]
// [EIP2H - Extended Interrupt Priority 2 High]$
// $[IE - Interrupt Enable]
/***********************************************************************
- Enable each interrupt according to its individual mask setting
- Disable external interrupt 0
- Disable external interrupt 1
- Disable all SPI0 interrupts
- Disable all Timer 0 interrupt
- Disable all Timer 1 interrupt
- Disable Timer 2 interrupt
- Disable UART0 interrupt
***********************************************************************/
SFRPAGE = 0x00;
IE = IE_EA__ENABLED | IE_EX0__DISABLED | IE_EX1__DISABLED
| IE_ESPI0__DISABLED | IE_ET0__DISABLED | IE_ET1__DISABLED
| IE_ET2__DISABLED | IE_ES0__DISABLED;
// [IE - Interrupt Enable]$
// $[IP - Interrupt Priority]
// [IP - Interrupt Priority]$
// $[IPH - Interrupt Priority High]
// [IPH - Interrupt Priority High]$
}
extern void USBLIB_0_enter_DefaultMode_from_RESET(void) {
// $[USBD Init]
USBD_Init (&initstruct);
// [USBD Init]$
}
extern void CLOCK_0_enter_DefaultMode_from_RESET(void) {
// $[HFOSC1 Setup]
// Ensure SYSCLK is > 24 MHz before switching to HFOSC1
SFRPAGE = 0x00;
CLKSEL = CLKSEL_CLKSL__HFOSC0 | CLKSEL_CLKDIV__SYSCLK_DIV_1;
while ((CLKSEL & CLKSEL_DIVRDY__BMASK) == CLKSEL_DIVRDY__NOT_READY)
;
// [HFOSC1 Setup]$
// $[CLKSEL - Clock Select]
/***********************************************************************
- Clock derived from the Internal High Frequency Oscillator 1
- SYSCLK is equal to selected clock source divided by 1
***********************************************************************/
CLKSEL = CLKSEL_CLKSL__HFOSC1 | CLKSEL_CLKDIV__SYSCLK_DIV_1;
while ((CLKSEL & CLKSEL_DIVRDY__BMASK) == CLKSEL_DIVRDY__NOT_READY)
;
// [CLKSEL - Clock Select]$
}
extern void WDT_0_enter_DefaultMode_from_RESET(void) {
// $[WDTCN - Watchdog Timer Control]
SFRPAGE = 0x00;
//Disable Watchdog with key sequence
WDTCN = 0xDE; //First key
WDTCN = 0xAD; //Second key
// [WDTCN - Watchdog Timer Control]$
}
extern void CIP51_0_enter_DefaultMode_from_RESET(void) {
// $[PFE0CN - Prefetch Engine Control]
/***********************************************************************
- Enable the prefetch engine
- SYSCLK < 50 MHz
***********************************************************************/
SFRPAGE = 0x10;
PFE0CN = PFE0CN_PFEN__ENABLED | PFE0CN_FLRT__SYSCLK_BELOW_50_MHZ;
// [PFE0CN - Prefetch Engine Control]$
}
extern void PBCFG_0_enter_DefaultMode_from_RESET(void) {
// $[XBR2 - Port I/O Crossbar 2]
/***********************************************************************
- Weak Pullups enabled
- Crossbar enabled
- UART1 TX1 RX1 routed to Port pins
- UART1 RTS1 unavailable at Port pin
- UART1 CTS1 unavailable at Port pin
***********************************************************************/
XBR2 = XBR2_WEAKPUD__PULL_UPS_ENABLED | XBR2_XBARE__ENABLED
| XBR2_URT1E__ENABLED | XBR2_URT1RTSE__DISABLED
| XBR2_URT1CTSE__DISABLED;
// [XBR2 - Port I/O Crossbar 2]$
// $[PRTDRV - Port Drive Strength]
// [PRTDRV - Port Drive Strength]$
// $[XBR0 - Port I/O Crossbar 0]
// [XBR0 - Port I/O Crossbar 0]$
// $[XBR1 - Port I/O Crossbar 1]
// [XBR1 - Port I/O Crossbar 1]$
}
extern void TIMER_SETUP_0_enter_DefaultMode_from_RESET(void) {
// $[CKCON0 - Clock Control 0]
/***********************************************************************
- System clock divided by 12
- Counter/Timer 0 uses the clock defined by the prescale field, SCA
- Timer 2 high byte uses the clock defined by T2XCLK in TMR2CN0
- Timer 2 low byte uses the system clock
- Timer 3 high byte uses the clock defined by T3XCLK in TMR3CN0
- Timer 3 low byte uses the system clock
- Timer 1 uses the clock defined by the prescale field, SCA
***********************************************************************/
CKCON0 = CKCON0_SCA__SYSCLK_DIV_12 | CKCON0_T0M__PRESCALE
| CKCON0_T2MH__EXTERNAL_CLOCK | CKCON0_T2ML__SYSCLK
| CKCON0_T3MH__EXTERNAL_CLOCK | CKCON0_T3ML__SYSCLK
| CKCON0_T1M__PRESCALE;
// [CKCON0 - Clock Control 0]$
// $[CKCON1 - Clock Control 1]
// [CKCON1 - Clock Control 1]$
// $[TMOD - Timer 0/1 Mode]
// [TMOD - Timer 0/1 Mode]$
// $[TCON - Timer 0/1 Control]
// [TCON - Timer 0/1 Control]$
}
extern void UARTE_1_enter_DefaultMode_from_RESET(void) {
// $[SBCON1 - UART1 Baud Rate Generator Control]
/***********************************************************************
- Enable the baud rate generator
- Prescaler = 1
***********************************************************************/
SFRPAGE = 0x20;
SBCON1 = SBCON1_BREN__ENABLED | SBCON1_BPS__DIV_BY_1;
// [SBCON1 - UART1 Baud Rate Generator Control]$
// $[SMOD1 - UART1 Mode]
// [SMOD1 - UART1 Mode]$
// $[UART1FCN0 - UART1 FIFO Control 0]
// [UART1FCN0 - UART1 FIFO Control 0]$
// $[SBRLH1 - UART1 Baud Rate Generator High Byte]
/***********************************************************************
- UART1 Baud Rate Reload High = 0xFF
***********************************************************************/
SBRLH1 = (0xFF << SBRLH1_BRH__SHIFT);
// [SBRLH1 - UART1 Baud Rate Generator High Byte]$
// $[SBRLL1 - UART1 Baud Rate Generator Low Byte]
/***********************************************************************
- UART1 Baud Rate Reload Low = 0x30
***********************************************************************/
SBRLL1 = (0x30 << SBRLL1_BRL__SHIFT);
// [SBRLL1 - UART1 Baud Rate Generator Low Byte]$
// $[UART1LIN - UART1 LIN Configuration]
// [UART1LIN - UART1 LIN Configuration]$
// $[SCON1 - UART1 Serial Port Control]
/***********************************************************************
- UART1 reception enabled
***********************************************************************/
SCON1 |= SCON1_REN__RECEIVE_ENABLED;
// [SCON1 - UART1 Serial Port Control]$
// $[UART1FCN1 - UART1 FIFO Control 1]
// [UART1FCN1 - UART1 FIFO Control 1]$
}
extern void TIMER16_2_enter_DefaultMode_from_RESET(void) {
// $[Timer Initialization]
// Save Timer Configuration
uint8_t TMR2CN0_TR2_save;
TMR2CN0_TR2_save = TMR2CN0 & TMR2CN0_TR2__BMASK;
// Stop Timer
TMR2CN0 &= ~(TMR2CN0_TR2__BMASK);
// [Timer Initialization]$
// $[TMR2CN1 - Timer 2 Control 1]
// [TMR2CN1 - Timer 2 Control 1]$
// $[TMR2CN0 - Timer 2 Control]
// [TMR2CN0 - Timer 2 Control]$
// $[TMR2H - Timer 2 High Byte]
// [TMR2H - Timer 2 High Byte]$
// $[TMR2L - Timer 2 Low Byte]
// [TMR2L - Timer 2 Low Byte]$
// $[TMR2RLH - Timer 2 Reload High Byte]
/***********************************************************************
- Timer 2 Reload High Byte = 0x44
***********************************************************************/
TMR2RLH = (0x44 << TMR2RLH_TMR2RLH__SHIFT);
// [TMR2RLH - Timer 2 Reload High Byte]$
// $[TMR2RLL - Timer 2 Reload Low Byte]
/***********************************************************************
- Timer 2 Reload Low Byte = 0x80
***********************************************************************/
TMR2RLL = (0x80 << TMR2RLL_TMR2RLL__SHIFT);
// [TMR2RLL - Timer 2 Reload Low Byte]$
// $[TMR2CN0]
/***********************************************************************
- Start Timer 2 running
***********************************************************************/
TMR2CN0 |= TMR2CN0_TR2__RUN;
// [TMR2CN0]$
// $[Timer Restoration]
// Restore Timer Configuration
TMR2CN0 |= TMR2CN0_TR2_save;
// [Timer Restoration]$
}
extern void TIMER16_3_enter_DefaultMode_from_RESET(void) {
// $[Timer Initialization]
// Save Timer Configuration
uint8_t TMR3CN0_TR3_save;
TMR3CN0_TR3_save = TMR3CN0 & TMR3CN0_TR3__BMASK;
// Stop Timer
TMR3CN0 &= ~(TMR3CN0_TR3__BMASK);
// [Timer Initialization]$
// $[TMR3CN1 - Timer 3 Control 1]
// [TMR3CN1 - Timer 3 Control 1]$
// $[TMR3CN0 - Timer 3 Control]
// [TMR3CN0 - Timer 3 Control]$
// $[TMR3H - Timer 3 High Byte]
// [TMR3H - Timer 3 High Byte]$
// $[TMR3L - Timer 3 Low Byte]
// [TMR3L - Timer 3 Low Byte]$
// $[TMR3RLH - Timer 3 Reload High Byte]
// [TMR3RLH - Timer 3 Reload High Byte]$
// $[TMR3RLL - Timer 3 Reload Low Byte]
// [TMR3RLL - Timer 3 Reload Low Byte]$
// $[TMR3CN0]
// [TMR3CN0]$
// $[Timer Restoration]
// Restore Timer Configuration
TMR3CN0 |= TMR3CN0_TR3_save;
// [Timer Restoration]$
}
extern void PORTS_0_enter_DefaultMode_from_RESET(void) {
// $[P0 - Port 0 Pin Latch]
// [P0 - Port 0 Pin Latch]$
// $[P0MDOUT - Port 0 Output Mode]
/***********************************************************************
- P0.0 output is push-pull
- P0.1 output is open-drain
- P0.2 output is open-drain
- P0.3 output is open-drain
- P0.4 output is open-drain
- P0.5 output is open-drain
- P0.6 output is open-drain
- P0.7 output is open-drain
***********************************************************************/
P0MDOUT = P0MDOUT_B0__PUSH_PULL | P0MDOUT_B1__OPEN_DRAIN
| P0MDOUT_B2__OPEN_DRAIN | P0MDOUT_B3__OPEN_DRAIN
| P0MDOUT_B4__OPEN_DRAIN | P0MDOUT_B5__OPEN_DRAIN
| P0MDOUT_B6__OPEN_DRAIN | P0MDOUT_B7__OPEN_DRAIN;
// [P0MDOUT - Port 0 Output Mode]$
// $[P0MDIN - Port 0 Input Mode]
// [P0MDIN - Port 0 Input Mode]$
// $[P0SKIP - Port 0 Skip]
// [P0SKIP - Port 0 Skip]$
// $[P0MASK - Port 0 Mask]
// [P0MASK - Port 0 Mask]$
// $[P0MAT - Port 0 Match]
// [P0MAT - Port 0 Match]$
}
extern void PORTS_1_enter_DefaultMode_from_RESET(void) {
}
extern void PORTS_2_enter_DefaultMode_from_RESET(void) {
}

203
efm8/src/SILABS_STARTUP.A51 Normal file
View File

@@ -0,0 +1,203 @@
$NOMOD51
;------------------------------------------------------------------------------
; This file is part of the C51 Compiler package
; Copyright (c) 1988-2005 Keil Elektronik GmbH and Keil Software, Inc.
; Version 8.01
;
; *** <<< Use Configuration Wizard in Context Menu >>> ***
;------------------------------------------------------------------------------
; STARTUP.A51: This code is executed after processor reset.
;
; To translate this file use A51 with the following invocation:
;
; A51 STARTUP.A51
;
; To link the modified STARTUP.OBJ file to your application use the following
; Lx51 invocation:
;
; Lx51 your object file list, STARTUP.OBJ controls
;
;------------------------------------------------------------------------------
;
; User-defined <h> Power-On Initialization of Memory
;
; With the following EQU statements the initialization of memory
; at processor reset can be defined:
;
; <o> IDATALEN: IDATA memory size <0x0-0x100>
; <i> Note: The absolute start-address of IDATA memory is always 0
; <i> The IDATA space overlaps physically the DATA and BIT areas.
IDATALEN EQU 80H
;
; <o> XDATASTART: XDATA memory start address <0x0-0xFFFF>
; <i> The absolute start address of XDATA memory
XDATASTART EQU 0
;
; <o> XDATALEN: XDATA memory size <0x0-0xFFFF>
; <i> The length of XDATA memory in bytes.
XDATALEN EQU 0
;
; <o> PDATASTART: PDATA memory start address <0x0-0xFFFF>
; <i> The absolute start address of PDATA memory
PDATASTART EQU 0H
;
; <o> PDATALEN: PDATA memory size <0x0-0xFF>
; <i> The length of PDATA memory in bytes.
PDATALEN EQU 0H
;
;</h>
;------------------------------------------------------------------------------
;
;<h> Reentrant Stack Initialization
;
; The following EQU statements define the stack pointer for reentrant
; functions and initialized it:
;
; <h> Stack Space for reentrant functions in the SMALL model.
; <q> IBPSTACK: Enable SMALL model reentrant stack
; <i> Stack space for reentrant functions in the SMALL model.
IBPSTACK EQU 0 ; set to 1 if small reentrant is used.
; <o> IBPSTACKTOP: End address of SMALL model stack <0x0-0xFF>
; <i> Set the top of the stack to the highest location.
IBPSTACKTOP EQU 0xFF +1 ; default 0FFH+1
; </h>
;
; <h> Stack Space for reentrant functions in the LARGE model.
; <q> XBPSTACK: Enable LARGE model reentrant stack
; <i> Stack space for reentrant functions in the LARGE model.
XBPSTACK EQU 0 ; set to 1 if large reentrant is used.
; <o> XBPSTACKTOP: End address of LARGE model stack <0x0-0xFFFF>
; <i> Set the top of the stack to the highest location.
XBPSTACKTOP EQU 0xFFFF +1 ; default 0FFFFH+1
; </h>
;
; <h> Stack Space for reentrant functions in the COMPACT model.
; <q> PBPSTACK: Enable COMPACT model reentrant stack
; <i> Stack space for reentrant functions in the COMPACT model.
PBPSTACK EQU 0 ; set to 1 if compact reentrant is used.
;
; <o> PBPSTACKTOP: End address of COMPACT model stack <0x0-0xFFFF>
; <i> Set the top of the stack to the highest location.
PBPSTACKTOP EQU 0xFF +1 ; default 0FFH+1
; </h>
;</h>
;------------------------------------------------------------------------------
;
; Memory Page for Using the Compact Model with 64 KByte xdata RAM
; <e>Compact Model Page Definition
;
; <i>Define the XDATA page used for PDATA variables.
; <i>PPAGE must conform with the PPAGE set in the linker invocation.
;
; Enable pdata memory page initalization
PPAGEENABLE EQU 0 ; set to 1 if pdata object are used.
;
; <o> PPAGE number <0x0-0xFF>
; <i> uppermost 256-byte address of the page used for PDATA variables.
PPAGE EQU 0
;
; <o> SFR address which supplies uppermost address byte <0x0-0xFF>
; <i> most 8051 variants use P2 as uppermost address byte
PPAGE_SFR DATA 0A0H
;
; </e>
;------------------------------------------------------------------------------
; Standard SFR Symbols
ACC DATA 0E0H
B DATA 0F0H
SP DATA 81H
DPL DATA 82H
DPH DATA 83H
NAME ?C_STARTUP
?C_C51STARTUP SEGMENT CODE
?STACK SEGMENT IDATA
RSEG ?STACK
DS 1
EXTRN CODE (?C_START)
PUBLIC ?C_STARTUP
CSEG AT 0
?C_STARTUP: LJMP STARTUP1
RSEG ?C_C51STARTUP
STARTUP1:
$IF (SILABS_STARTUP = 1)
EXTRN CODE (SiLabs_Startup)
LCALL SiLabs_Startup
$ENDIF
IF IDATALEN <> 0
MOV R0,#IDATALEN - 1
CLR A
IDATALOOP: MOV @R0,A
DJNZ R0,IDATALOOP
ENDIF
IF XDATALEN <> 0
MOV DPTR,#XDATASTART
MOV R7,#LOW (XDATALEN)
IF (LOW (XDATALEN)) <> 0
MOV R6,#(HIGH (XDATALEN)) +1
ELSE
MOV R6,#HIGH (XDATALEN)
ENDIF
CLR A
XDATALOOP: MOVX @DPTR,A
INC DPTR
DJNZ R7,XDATALOOP
DJNZ R6,XDATALOOP
ENDIF
IF PPAGEENABLE <> 0
MOV PPAGE_SFR,#PPAGE
ENDIF
IF PDATALEN <> 0
MOV R0,#LOW (PDATASTART)
MOV R7,#LOW (PDATALEN)
CLR A
PDATALOOP: MOVX @R0,A
INC R0
DJNZ R7,PDATALOOP
ENDIF
IF IBPSTACK <> 0
EXTRN DATA (?C_IBP)
MOV ?C_IBP,#LOW IBPSTACKTOP
ENDIF
IF XBPSTACK <> 0
EXTRN DATA (?C_XBP)
MOV ?C_XBP,#HIGH XBPSTACKTOP
MOV ?C_XBP+1,#LOW XBPSTACKTOP
ENDIF
IF PBPSTACK <> 0
EXTRN DATA (?C_PBP)
MOV ?C_PBP,#LOW PBPSTACKTOP
ENDIF
MOV SP,#?STACK-1
; This code is required if you use L51_BANK.A51 with Banking Mode 4
;<h> Code Banking
; <q> Select Bank 0 for L51_BANK.A51 Mode 4
$IF (USE_BANKING = 1)
; <i> Initialize bank mechanism to code bank 0 when using L51_BANK.A51 with Banking Mode 4.
EXTRN CODE (?B_SWITCH0)
CALL ?B_SWITCH0 ; init bank mechanism to code bank 0
$ENDIF
;</h>
LJMP ?C_START
END

145
efm8/src/callback.c Normal file
View File

@@ -0,0 +1,145 @@
/*
* Copyright (c) 2016, Conor Patrick
* All rights reserved.
*
* 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.
*
* 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 OWNER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <SI_EFM8UB1_Register_Enums.h>
#include <efm8_usb.h>
#include <stdio.h>
#include "descriptors.h"
#define UNUSED(expr) do { (void)(expr); } while (0)
#define HID_INTERFACE_INDEX 0
uint8_t tmpBuffer;
void USBD_ResetCb(void) {
// u2f_print_ev("USBD_ResetCb\r\n");
}
void USBD_DeviceStateChangeCb(USBD_State_TypeDef oldState,
USBD_State_TypeDef newState) {
UNUSED(oldState);
UNUSED(newState);
// u2f_print_ev("USBD_DeviceStateChangeCb\r\n");
}
bool USBD_IsSelfPoweredCb(void) {
return false;
}
// Necessary routine for USB HID
USB_Status_TypeDef USBD_SetupCmdCb(
SI_VARIABLE_SEGMENT_POINTER(setup, USB_Setup_TypeDef, MEM_MODEL_SEG)) {
USB_Status_TypeDef retVal = USB_STATUS_REQ_UNHANDLED;
if ((setup->bmRequestType.Type == USB_SETUP_TYPE_STANDARD)
&& (setup->bmRequestType.Direction == USB_SETUP_DIR_IN)
&& (setup->bmRequestType.Recipient == USB_SETUP_RECIPIENT_INTERFACE)) {
// A HID device must extend the standard GET_DESCRIPTOR command
// with support for HID descriptors.
switch (setup->bRequest) {
case GET_DESCRIPTOR:
if (setup->wIndex == 0)
{
if ((setup->wValue >> 8) == USB_HID_REPORT_DESCRIPTOR) {
USBD_Write(EP0, ReportDescriptor0,
EFM8_MIN(sizeof(ReportDescriptor0), setup->wLength),
false);
retVal = USB_STATUS_OK;
} else if ((setup->wValue >> 8) == USB_HID_DESCRIPTOR) {
USBD_Write(EP0, (&configDesc[18]),
EFM8_MIN(USB_HID_DESCSIZE, setup->wLength), false);
retVal = USB_STATUS_OK;
}
}
break;
}
}
else if ((setup->bmRequestType.Type == USB_SETUP_TYPE_CLASS)
&& (setup->bmRequestType.Recipient == USB_SETUP_RECIPIENT_INTERFACE)
&& (setup->wIndex == HID_INTERFACE_INDEX))
{
// Implement the necessary HID class specific commands.
switch (setup->bRequest)
{
case USB_HID_SET_IDLE:
if (((setup->wValue & 0xFF) == 0) // Report ID
&& (setup->wLength == 0)
&& (setup->bmRequestType.Direction != USB_SETUP_DIR_IN))
{
retVal = USB_STATUS_OK;
}
break;
case USB_HID_GET_IDLE:
if ((setup->wValue == 0) // Report ID
&& (setup->wLength == 1)
&& (setup->bmRequestType.Direction == USB_SETUP_DIR_IN))
{
tmpBuffer = 24;
USBD_Write(EP0, &tmpBuffer, 1, false);
retVal = USB_STATUS_OK;
}
break;
default:
break;
}
}
return retVal;
}
uint8_t hidmsgbuf[64];
uint16_t USBD_XferCompleteCb(uint8_t epAddr, USB_Status_TypeDef status,
uint16_t xferred, uint16_t remaining ) {
UNUSED(status);
UNUSED(xferred);
UNUSED(remaining);
if (epAddr == EP1OUT)
{
// set_app_u2f_hid_msg((struct u2f_hid_msg *) hidmsgbuf );
}
return 0;
}

174
efm8/src/descriptors.c Normal file
View File

@@ -0,0 +1,174 @@
//=============================================================================
// src/descriptors.c: generated by Hardware Configurator
//
// This file is only generated if it does not exist. Modifications in this file
// will persist even if Configurator generates code. To refresh this file,
// you must first delete it and then regenerate code.
//=============================================================================
//-----------------------------------------------------------------------------
// Includes
//-----------------------------------------------------------------------------
#include <si_toolchain.h>
#include <endian.h>
#include <stdlib.h>
#include <string.h>
#include <efm8_usb.h>
#include "descriptors.h"
#ifdef __cplusplus
extern "C" {
#endif
// HID Report Descriptor for Interface 0
SI_SEGMENT_VARIABLE(ReportDescriptor0[34],
const uint8_t,
SI_SEG_CODE) =
{
0x06, 0xd0, 0xf1,// USAGE_PAGE (FIDO Alliance)
0x09, 0x01,// USAGE (Keyboard)
0xa1, 0x01,// COLLECTION (Application)
0x09, 0x20, // USAGE (Input Report Data)
0x15, 0x00, // LOGICAL_MINIMUM (0)
0x26, 0xff, 0x00, // LOGICAL_MAXIMUM (255)
0x75, 0x08, // REPORT_SIZE (8)
0x95, HID_PACKET_SIZE, // REPORT_COUNT (64)
0x81, 0x02, // INPUT (Data,Var,Abs)
0x09, 0x21, // USAGE(Output Report Data)
0x15, 0x00, // LOGICAL_MINIMUM (0)
0x26, 0xff, 0x00, // LOGICAL_MAXIMUM (255)
0x75, 0x08, // REPORT_SIZE (8)
0x95, HID_PACKET_SIZE, // REPORT_COUNT (64)
0x91, 0x02, // OUTPUT (Data,Var,Abs)
0xc0,// END_COLLECTION
};
SI_SEGMENT_VARIABLE(deviceDesc[],
const USB_DeviceDescriptor_TypeDef,
SI_SEG_CODE) =
{
USB_DEVICE_DESCSIZE, // bLength
USB_DEVICE_DESCRIPTOR,// bLength
htole16(0x0200),// bcdUSB
0,// bDeviceClass
0,// bDeviceSubClass
0,// bDeviceProtocol
64,// bMaxPacketSize
USB_VENDOR_ID,// idVendor
USB_PRODUCT_ID,// idProduct
htole16(0x0100),// bcdDevice
1,// iManufacturer
2,// iProduct
3,// iSerialNumber
1,// bNumConfigurations
};
SI_SEGMENT_VARIABLE(configDesc[],
const uint8_t,
SI_SEG_CODE) =
{
USB_CONFIG_DESCSIZE, // bLength
USB_CONFIG_DESCRIPTOR,// bLength
0x29,// wTotalLength(LSB)
0x00,// wTotalLength(MSB)
1,// bNumInterfaces
1,// bConfigurationValue
0,// iConfiguration
CONFIG_DESC_BM_RESERVED_D7,// bmAttrib: Bus powered
CONFIG_DESC_MAXPOWER_mA(100),// bMaxPower: 100 mA
//Interface 0 Descriptor
USB_INTERFACE_DESCSIZE,// bLength
USB_INTERFACE_DESCRIPTOR,// bDescriptorType
0,// bInterfaceNumber
0,// bAlternateSetting
2,// bNumEndpoints
3,// bInterfaceClass: HID (Human Interface Device)
0,// bInterfaceSubClass
0,// bInterfaceProtocol
4,// iInterface
//HID Descriptor
USB_HID_DESCSIZE,// bLength
USB_HID_DESCRIPTOR,// bLength
0x11,// bcdHID (LSB)
0x01,// bcdHID (MSB)
0,// bCountryCode
1,// bNumDescriptors
USB_HID_REPORT_DESCRIPTOR,// bDescriptorType
sizeof( ReportDescriptor0 ),// wDescriptorLength(LSB)
sizeof( ReportDescriptor0 )>>8,// wDescriptorLength(MSB)
//Endpoint 1 IN Descriptor
USB_ENDPOINT_DESCSIZE,// bLength
USB_ENDPOINT_DESCRIPTOR,// bDescriptorType
0x81,// bEndpointAddress
USB_EPTYPE_INTR,// bAttrib
HID_PACKET_SIZE,// wMaxPacketSize (LSB)
0x00,// wMaxPacketSize (MSB)
5,// bInterval
//Endpoint 1 OUT Descriptor
USB_ENDPOINT_DESCSIZE,// bLength
USB_ENDPOINT_DESCRIPTOR,// bDescriptorType
0x01,// bEndpointAddress
USB_EPTYPE_INTR,// bAttrib
HID_PACKET_SIZE,// wMaxPacketSize (LSB)
0x00,// wMaxPacketSize (MSB)
5,// bInterval
};
#define LANG_STRING htole16( SLAB_USB_LANGUAGE )
#define MFR_STRING 'S','i','l','i','c','o','n',' ','L','a','b','s','\0'
#define MFR_SIZE 13
#define PROD_STRING 'E','O','S',' ','W','a','l','l','e','t','\0'
#define PROD_SIZE 11
#define SER_STRING '0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F','\0'
#define SER_SIZE 17
#define CFG_STRING 'C','o','n','f','i','g',' ','#','1','\0'
#define CFG_SIZE 10
#define INT0_STRING 'E','O','S',' ','W','a','l','l','e','t','\0'
#define INT0_SIZE 11
LANGID_STATIC_CONST_STRING_DESC( langDesc[], LANG_STRING );
UTF16LE_PACKED_STATIC_CONST_STRING_DESC( mfrDesc[], MFR_STRING, MFR_SIZE);
UTF16LE_PACKED_STATIC_CONST_STRING_DESC( prodDesc[], PROD_STRING, PROD_SIZE);
UTF16LE_PACKED_STATIC_CONST_STRING_DESC( serDesc[], SER_STRING, SER_SIZE);
UTF16LE_PACKED_STATIC_CONST_STRING_DESC( cfgDesc[], CFG_STRING, CFG_SIZE);
UTF16LE_PACKED_STATIC_CONST_STRING_DESC( int0Desc[], INT0_STRING, INT0_SIZE);
//-----------------------------------------------------------------------------
SI_SEGMENT_POINTER(myUsbStringTable_USEnglish[],
static const USB_StringDescriptor_TypeDef,
const SI_SEG_CODE) =
{
langDesc,
mfrDesc,
prodDesc,
serDesc,
int0Desc,
};
//-----------------------------------------------------------------------------
SI_SEGMENT_VARIABLE(initstruct,
const USBD_Init_TypeDef,
SI_SEG_CODE) =
{
deviceDesc, // deviceDescriptor
configDesc,// configDescriptor
myUsbStringTable_USEnglish,// stringDescriptors
sizeof(myUsbStringTable_USEnglish) / sizeof(void *)// numberOfStrings
};
#ifdef __cplusplus
}
#endif

17
efm8/src/main.c Normal file
View File

@@ -0,0 +1,17 @@
#include <SI_EFM8UB1_Register_Enums.h>
#include "InitDevice.h"
#include "efm8_usb.h"
#include "printing.h"
int main(void) {
enter_DefaultMode_from_RESET();
cprints("hello,world\r\n");
while (1) {
}
}

171
efm8/src/printing.c Normal file
View File

@@ -0,0 +1,171 @@
/*
* printing.c
*
* Created on: Jun 25, 2018
* Author: conor
*/
#include <SI_EFM8UB1_Register_Enums.h>
#include <efm8_usb.h>
#include <stdarg.h>
#include <stdio.h>
#include "printing.h"
void putf(char c)
{
uint8_t i;
SBUF0 = c;
// Blocking delay that works for 115200 baud on this device (<1ms)
for (i=0; i<200; i++){}
for (i=0; i<200; i++){}
for (i=0; i<190; i++){}
watchdog();
}
void dump_hex(uint8_t* hex, uint8_t len)
{
uint8_t i;
for (i=0 ; i < len ; i++)
{
if (hex[i]<0x10)
{
putf('0');
}
cputb(hex[i]);
}
cprints("\r\n");
}
void cprints(char* d)
{
while(*d)
{
// UART0 output queue
putf(*d++);
}
}
static void int2str_reduce_n(char ** snum, uint32_t copy, uint8_t n)
{
do
{
copy /= n;
}while(copy);
}
static const char * __digits = "0123456789abcdef";
static char xdata __int2str_buf[9];
static void int2str_map_n(char ** snum, uint32_t i, uint8_t n)
{
do
{
*--*snum = __digits[i % n];
i /= n;
}while(i);
}
#define dint2str(i) __int2strn(i,10)
#define xint2str(i) __int2strn(i,16)
char * __int2strn(int32_t i, uint8_t n)
{
char * snum = __int2str_buf;
if (i<0) *snum++ = '-';
int2str_reduce_n(&snum, i, n);
*snum = '\0';
int2str_map_n(&snum, i, n);
return snum;
}
void cputd(int32_t i)
{
cprints(dint2str((int32_t)i));
}
void cputx(int32_t i)
{
cprints(xint2str(i));
}
static void put_space()
{
cprints(" ");
}
static void put_line()
{
cprints("\r\n");
}
void cprintd(const char * tag, uint8_t c, ...)
{
va_list args;
cprints(tag);
va_start(args,c);
while(c--)
{
cputd((int32_t)va_arg(args, int16_t));
}
put_line();
va_end(args);
}
void cprintl(const char * tag, uint8_t c, ...)
{
va_list args;
cprints(tag);
va_start(args,c);
while(c--)
{
cputl(va_arg(args, int32_t));
cprints(" ");
}
put_line();
va_end(args);
}
void cprintx(const char * tag, uint8_t c, ...)
{
va_list args;
cprints(tag);
va_start(args,c);
while(c--)
{
cputx((int32_t)va_arg(args, uint16_t));
cprints(" ");
}
put_line();
va_end(args);
}
void cprintb(const char * tag, uint8_t c, ...)
{
va_list args;
cprints(tag);
va_start(args,c);
while(c--)
{
cputb(va_arg(args, uint8_t));
put_space();
}
put_line();
va_end(args);
}
void cprintlx(const char * tag, uint8_t c, ...)
{
va_list args;
cprints(tag);
va_start(args,c);
while(c--)
{
cputlx(va_arg(args, int32_t));
put_space();
}
put_line();
va_end(args);
}