remove test_obsolete

This commit is contained in:
hathach 2019-06-10 17:42:27 +07:00
parent f3c2b9c2aa
commit ede3f36f31
No known key found for this signature in database
GPG Key ID: 2FA891220FBFD581
199 changed files with 0 additions and 56571 deletions

View File

@ -1,546 +0,0 @@
<?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.crt.advproject.toolchain.exe.debug.1281391870">
<storageModule buildSystemId="org.eclipse.cdt.managedbuilder.core.configurationDataProvider" id="com.crt.advproject.toolchain.exe.debug.1281391870" moduleId="org.eclipse.cdt.core.settings" name="Debug">
<externalSettings/>
<extensions>
<extension id="org.eclipse.cdt.core.GCCErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
<extension id="org.eclipse.cdt.core.GASErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
<extension id="org.eclipse.cdt.core.GLDErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
<extension id="org.eclipse.cdt.core.GmakeErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
<extension id="org.eclipse.cdt.core.CWDLocator" point="org.eclipse.cdt.core.ErrorParser"/>
<extension id="org.eclipse.cdt.core.VCErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
<extension id="org.eclipse.cdt.core.MakeErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
<extension id="org.eclipse.cdt.core.PE" point="org.eclipse.cdt.core.BinaryParser"/>
</extensions>
</storageModule>
<storageModule moduleId="cdtBuildSystem" version="4.0.0">
<configuration artifactName="${ProjName}" buildProperties="" description="" errorParsers="org.eclipse.cdt.core.GmakeErrorParser;org.eclipse.cdt.core.CWDLocator;org.eclipse.cdt.core.GCCErrorParser;org.eclipse.cdt.core.GASErrorParser;org.eclipse.cdt.core.GLDErrorParser;org.eclipse.cdt.core.VCErrorParser;org.eclipse.cdt.core.MakeErrorParser" id="com.crt.advproject.toolchain.exe.debug.1281391870" name="Debug" parent="org.eclipse.cdt.build.core.emptycfg">
<folderInfo id="com.crt.advproject.toolchain.exe.debug.1281391870.1757637439" name="/" resourcePath="">
<toolChain errorParsers="" id="cdt.managedbuild.toolchain.gnu.mingw.base.760207820" name="MinGW GCC" superClass="cdt.managedbuild.toolchain.gnu.mingw.base">
<targetPlatform archList="all" binaryParser="org.eclipse.cdt.core.PE" id="cdt.managedbuild.target.gnu.platform.mingw.base.1767850371" name="Debug Platform" osList="win32" superClass="cdt.managedbuild.target.gnu.platform.mingw.base"/>
<builder buildPath="${workspace_loc:/tinyusb/Debug}" errorParsers="org.eclipse.cdt.core.GmakeErrorParser;org.eclipse.cdt.core.CWDLocator" id="cdt.managedbuild.builder.gnu.cross.972264119" keepEnvironmentInBuildfile="false" managedBuildOn="false" name="Gnu Make Builder"/>
<tool errorParsers="org.eclipse.cdt.core.GASErrorParser" id="cdt.managedbuild.tool.gnu.assembler.mingw.base.232020028" name="GCC Assembler" superClass="cdt.managedbuild.tool.gnu.assembler.mingw.base">
<option id="gnu.both.asm.option.include.paths.186595949" name="Include paths (-I)" superClass="gnu.both.asm.option.include.paths" valueType="includePath">
<listOptionValue builtIn="false" value="&quot;C:\nxp\LPCXpresso_4.3.0_1023\lpcxpresso\Tools\lib\gcc\arm-none-eabi\4.5.1\include&quot;"/>
<listOptionValue builtIn="false" value="&quot;C:\nxp\LPCXpresso_4.3.0_1023\lpcxpresso\Tools\lib\gcc\arm-none-eabi\4.5.1\include-fixed&quot;"/>
<listOptionValue builtIn="false" value="&quot;C:\nxp\LPCXpresso_4.3.0_1023\lpcxpresso\Tools\arm-none-eabi\include&quot;"/>
</option>
<inputType id="cdt.managedbuild.tool.gnu.assembler.input.2093181178" superClass="cdt.managedbuild.tool.gnu.assembler.input"/>
</tool>
<tool id="cdt.managedbuild.tool.gnu.archiver.mingw.base.1485867060" name="GCC Archiver" superClass="cdt.managedbuild.tool.gnu.archiver.mingw.base"/>
<tool id="cdt.managedbuild.tool.gnu.cpp.compiler.mingw.base.694786126" name="GCC C++ Compiler" superClass="cdt.managedbuild.tool.gnu.cpp.compiler.mingw.base"/>
<tool errorParsers="org.eclipse.cdt.core.GCCErrorParser" id="cdt.managedbuild.tool.gnu.c.compiler.mingw.base.1588045403" name="GCC C Compiler" superClass="cdt.managedbuild.tool.gnu.c.compiler.mingw.base">
<option id="gnu.c.compiler.option.preprocessor.def.symbols.1484610767" name="Defined symbols (-D)" superClass="gnu.c.compiler.option.preprocessor.def.symbols" valueType="definedSymbols">
<listOptionValue builtIn="false" value="CFG_TUSB_MCU=OPT_MCU_LPC43XX"/>
</option>
<option id="gnu.c.compiler.option.preprocessor.undef.symbol.1508960620" name="Undefined symbols (-U)" superClass="gnu.c.compiler.option.preprocessor.undef.symbol"/>
<inputType id="cdt.managedbuild.tool.gnu.c.compiler.input.451457393" superClass="cdt.managedbuild.tool.gnu.c.compiler.input"/>
</tool>
<tool errorParsers="org.eclipse.cdt.core.GLDErrorParser" id="cdt.managedbuild.tool.gnu.c.linker.mingw.base.1896871485" name="MinGW C Linker" superClass="cdt.managedbuild.tool.gnu.c.linker.mingw.base">
<inputType id="cdt.managedbuild.tool.gnu.c.linker.input.1762310351" superClass="cdt.managedbuild.tool.gnu.c.linker.input">
<additionalInput kind="additionalinputdependency" paths="$(USER_OBJS)"/>
<additionalInput kind="additionalinput" paths="$(LIBS)"/>
</inputType>
</tool>
<tool id="cdt.managedbuild.tool.gnu.cpp.linker.mingw.base.420552955" name="MinGW C++ Linker" superClass="cdt.managedbuild.tool.gnu.cpp.linker.mingw.base"/>
</toolChain>
</folderInfo>
<sourceEntries>
<entry excluding="tests/build/test/cache|tests/build/test/dependencies|tests/build/test/runners|tests/build/test/out|tests/build/test/preprocess|tests/build/test/results" flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name=""/>
</sourceEntries>
</configuration>
</storageModule>
<storageModule moduleId="org.eclipse.cdt.core.externalSettings"/>
<storageModule moduleId="org.eclipse.cdt.core.language.mapping"/>
<storageModule moduleId="org.eclipse.cdt.internal.ui.text.commentOwnerProjectMappings"/>
</cconfiguration>
</storageModule>
<storageModule moduleId="cdtBuildSystem" version="4.0.0">
<project id="tinyusb.null.492346701" name="tinyusb"/>
</storageModule>
<storageModule moduleId="com.crt.config">
<projectStorage>&lt;?xml version="1.0" encoding="UTF-8"?&gt;&#13;
&lt;TargetConfig&gt;&#13;
&lt;Properties property_0="" property_2="LPC11_12_13_32K_8K.cfx" property_3="NXP" property_4="LPC1343" property_count="5" version="70200"/&gt;&#13;
&lt;infoList vendor="NXP"&gt;&#13;
&lt;info chip="LPC1343" flash_driver="LPC11_12_13_32K_8K.cfx" match_id="0x3d00002b" name="LPC1343" stub="crt_emu_lpc11_13_nxp"&gt;&#13;
&lt;chip&gt;&#13;
&lt;name&gt;LPC1343&lt;/name&gt;&#13;
&lt;family&gt;LPC13xx&lt;/family&gt;&#13;
&lt;vendor&gt;NXP (formerly Philips)&lt;/vendor&gt;&#13;
&lt;reset board="None" core="Real" sys="Real"/&gt;&#13;
&lt;clock changeable="TRUE" freq="12MHz" is_accurate="TRUE"/&gt;&#13;
&lt;memory can_program="true" id="Flash" is_ro="true" type="Flash"/&gt;&#13;
&lt;memory id="RAM" type="RAM"/&gt;&#13;
&lt;memory id="Periph" is_volatile="true" type="Peripheral"/&gt;&#13;
&lt;memoryInstance derived_from="Flash" id="MFlash32" location="0x0" size="0x8000"/&gt;&#13;
&lt;memoryInstance derived_from="RAM" id="RamLoc8" location="0x10000000" size="0x2000"/&gt;&#13;
&lt;peripheralInstance derived_from="V7M_NVIC" determined="infoFile" id="NVIC" location="0xe000e000"/&gt;&#13;
&lt;peripheralInstance derived_from="V7M_DCR" determined="infoFile" id="DCR" location="0xe000edf0"/&gt;&#13;
&lt;peripheralInstance derived_from="V7M_ITM" determined="infoFile" id="ITM" location="0xe0000000"/&gt;&#13;
&lt;peripheralInstance derived_from="I2C" determined="infoFile" id="I2C" location="0x40000000"/&gt;&#13;
&lt;peripheralInstance derived_from="WWDT" determined="infoFile" id="WWDT" location="0x40004000"/&gt;&#13;
&lt;peripheralInstance derived_from="UART" determined="infoFile" id="UART" location="0x40008000"/&gt;&#13;
&lt;peripheralInstance derived_from="CT16B0" determined="infoFile" id="CT16B0" location="0x4000c000"/&gt;&#13;
&lt;peripheralInstance derived_from="CT16B1" determined="infoFile" id="CT16B1" location="0x40010000"/&gt;&#13;
&lt;peripheralInstance derived_from="CT32B0" determined="infoFile" id="CT32B0" location="0x40014000"/&gt;&#13;
&lt;peripheralInstance derived_from="CT32B1" determined="infoFile" id="CT32B1" location="0x40018000"/&gt;&#13;
&lt;peripheralInstance derived_from="ADC" determined="infoFile" id="ADC" location="0x4001c000"/&gt;&#13;
&lt;peripheralInstance derived_from="USB" determined="infoFile" id="USB" location="0x40020000"/&gt;&#13;
&lt;peripheralInstance derived_from="PMU" determined="infoFile" id="PMU" location="0x40038000"/&gt;&#13;
&lt;peripheralInstance derived_from="FMC" determined="infoFile" id="FMC" location="0x4003c000"/&gt;&#13;
&lt;peripheralInstance derived_from="SSP0" determined="infoFile" id="SSP0" location="0x40040000"/&gt;&#13;
&lt;peripheralInstance derived_from="IOCON" determined="infoFile" id="IOCON" location="0x40044000"/&gt;&#13;
&lt;peripheralInstance derived_from="SYSCON" determined="infoFile" id="SYSCON" location="0x40048000"/&gt;&#13;
&lt;peripheralInstance derived_from="GPIO0" determined="infoFile" id="GPIO0" location="0x50000000"/&gt;&#13;
&lt;peripheralInstance derived_from="GPIO1" determined="infoFile" id="GPIO1" location="0x50010000"/&gt;&#13;
&lt;peripheralInstance derived_from="GPIO2" determined="infoFile" id="GPIO2" location="0x50020000"/&gt;&#13;
&lt;peripheralInstance derived_from="GPIO3" determined="infoFile" id="GPIO3" location="0x50030000"/&gt;&#13;
&lt;/chip&gt;&#13;
&lt;processor&gt;&#13;
&lt;name gcc_name="cortex-m3"&gt;Cortex-M3&lt;/name&gt;&#13;
&lt;family&gt;Cortex-M&lt;/family&gt;&#13;
&lt;/processor&gt;&#13;
&lt;link href="LPC13xx_peripheral.xme" show="embed" type="simple"/&gt;&#13;
&lt;/info&gt;&#13;
&lt;/infoList&gt;&#13;
&lt;/TargetConfig&gt;</projectStorage>
</storageModule>
<storageModule moduleId="refreshScope" versionNumber="1">
<resource resourceType="PROJECT" workspacePath="/tinyusb"/>
</storageModule>
<storageModule moduleId="scannerConfiguration">
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
<profile id="org.eclipse.cdt.make.core.GCCStandardMakePerProjectProfile">
<buildOutputProvider>
<openAction enabled="true" filePath=""/>
<parser enabled="true"/>
</buildOutputProvider>
<scannerInfoProvider id="specsFile">
<runAction arguments="-E -P -v -dD ${plugin_state_location}/${specs_file}" command="gcc" useDefault="true"/>
<parser enabled="true"/>
</scannerInfoProvider>
</profile>
<profile id="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfile">
<buildOutputProvider>
<openAction enabled="true" filePath=""/>
<parser enabled="true"/>
</buildOutputProvider>
<scannerInfoProvider id="specsFile">
<runAction arguments="-E -P -v -dD ${plugin_state_location}/${specs_file}" command="gcc" useDefault="true"/>
<parser enabled="true"/>
</scannerInfoProvider>
</profile>
<profile id="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfileCPP">
<buildOutputProvider>
<openAction enabled="true" filePath=""/>
<parser enabled="true"/>
</buildOutputProvider>
<scannerInfoProvider id="specsFile">
<runAction arguments="-E -P -v -dD ${plugin_state_location}/specs.cpp" command="g++" useDefault="true"/>
<parser enabled="true"/>
</scannerInfoProvider>
</profile>
<profile id="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfileC">
<buildOutputProvider>
<openAction enabled="true" filePath=""/>
<parser enabled="true"/>
</buildOutputProvider>
<scannerInfoProvider id="specsFile">
<runAction arguments="-E -P -v -dD ${plugin_state_location}/specs.c" command="gcc" useDefault="true"/>
<parser enabled="true"/>
</scannerInfoProvider>
</profile>
<scannerConfigBuildInfo instanceId="com.crt.advproject.toolchain.exe.debug.1281391870.909223166;com.crt.advproject.toolchain.exe.debug.1281391870.909223166.;cdt.managedbuild.tool.gnu.c.compiler.mingw.base.1123347799;cdt.managedbuild.tool.gnu.c.compiler.input.1476468867">
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfileC"/>
<profile id="org.eclipse.cdt.make.core.GCCStandardMakePerProjectProfile">
<buildOutputProvider>
<openAction enabled="true" filePath=""/>
<parser enabled="true"/>
</buildOutputProvider>
<scannerInfoProvider id="specsFile">
<runAction arguments="-E -P -v -dD ${plugin_state_location}/${specs_file}" command="gcc" useDefault="true"/>
<parser enabled="true"/>
</scannerInfoProvider>
</profile>
<profile id="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfile">
<buildOutputProvider>
<openAction enabled="true" filePath=""/>
<parser enabled="true"/>
</buildOutputProvider>
<scannerInfoProvider id="specsFile">
<runAction arguments="-E -P -v -dD ${plugin_state_location}/${specs_file}" command="gcc" useDefault="true"/>
<parser enabled="true"/>
</scannerInfoProvider>
</profile>
<profile id="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfileCPP">
<buildOutputProvider>
<openAction enabled="true" filePath=""/>
<parser enabled="true"/>
</buildOutputProvider>
<scannerInfoProvider id="specsFile">
<runAction arguments="-E -P -v -dD ${plugin_state_location}/specs.cpp" command="g++" useDefault="true"/>
<parser enabled="true"/>
</scannerInfoProvider>
</profile>
<profile id="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfileC">
<buildOutputProvider>
<openAction enabled="true" filePath=""/>
<parser enabled="true"/>
</buildOutputProvider>
<scannerInfoProvider id="specsFile">
<runAction arguments="-E -P -v -dD ${plugin_state_location}/specs.c" command="gcc" useDefault="true"/>
<parser enabled="true"/>
</scannerInfoProvider>
</profile>
</scannerConfigBuildInfo>
<scannerConfigBuildInfo instanceId="com.crt.advproject.toolchain.exe.debug.1281391870;com.crt.advproject.toolchain.exe.debug.1281391870.1757637439;com.crt.advproject.gcc.exe.debug.872963007;com.crt.advproject.compiler.input.2103556147">
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId="com.crt.advproject.GCCManagedMakePerProjectProfile"/>
<profile id="org.eclipse.cdt.make.core.GCCStandardMakePerProjectProfile">
<buildOutputProvider>
<openAction enabled="true" filePath=""/>
<parser enabled="true"/>
</buildOutputProvider>
<scannerInfoProvider id="specsFile">
<runAction arguments="-E -P -v -dD ${plugin_state_location}/${specs_file}" command="gcc" useDefault="true"/>
<parser enabled="true"/>
</scannerInfoProvider>
</profile>
<profile id="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfile">
<buildOutputProvider>
<openAction enabled="true" filePath=""/>
<parser enabled="true"/>
</buildOutputProvider>
<scannerInfoProvider id="specsFile">
<runAction arguments="-E -P -v -dD ${plugin_state_location}/${specs_file}" command="gcc" useDefault="true"/>
<parser enabled="true"/>
</scannerInfoProvider>
</profile>
<profile id="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfileCPP">
<buildOutputProvider>
<openAction enabled="true" filePath=""/>
<parser enabled="true"/>
</buildOutputProvider>
<scannerInfoProvider id="specsFile">
<runAction arguments="-E -P -v -dD ${plugin_state_location}/specs.cpp" command="g++" useDefault="true"/>
<parser enabled="true"/>
</scannerInfoProvider>
</profile>
<profile id="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfileC">
<buildOutputProvider>
<openAction enabled="true" filePath=""/>
<parser enabled="true"/>
</buildOutputProvider>
<scannerInfoProvider id="specsFile">
<runAction arguments="-E -P -v -dD ${plugin_state_location}/specs.c" command="gcc" useDefault="true"/>
<parser enabled="true"/>
</scannerInfoProvider>
</profile>
</scannerConfigBuildInfo>
<scannerConfigBuildInfo instanceId="com.crt.advproject.toolchain.exe.debug.1281391870;com.crt.advproject.toolchain.exe.debug.1281391870.1757637439;cdt.managedbuild.tool.gnu.c.compiler.mingw.base.1352687236;cdt.managedbuild.tool.gnu.c.compiler.input.1754985414">
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfileC"/>
<profile id="org.eclipse.cdt.make.core.GCCStandardMakePerProjectProfile">
<buildOutputProvider>
<openAction enabled="true" filePath=""/>
<parser enabled="true"/>
</buildOutputProvider>
<scannerInfoProvider id="specsFile">
<runAction arguments="-E -P -v -dD ${plugin_state_location}/${specs_file}" command="gcc" useDefault="true"/>
<parser enabled="true"/>
</scannerInfoProvider>
</profile>
<profile id="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfile">
<buildOutputProvider>
<openAction enabled="true" filePath=""/>
<parser enabled="true"/>
</buildOutputProvider>
<scannerInfoProvider id="specsFile">
<runAction arguments="-E -P -v -dD ${plugin_state_location}/${specs_file}" command="gcc" useDefault="true"/>
<parser enabled="true"/>
</scannerInfoProvider>
</profile>
<profile id="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfileCPP">
<buildOutputProvider>
<openAction enabled="true" filePath=""/>
<parser enabled="true"/>
</buildOutputProvider>
<scannerInfoProvider id="specsFile">
<runAction arguments="-E -P -v -dD ${plugin_state_location}/specs.cpp" command="g++" useDefault="true"/>
<parser enabled="true"/>
</scannerInfoProvider>
</profile>
<profile id="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfileC">
<buildOutputProvider>
<openAction enabled="true" filePath=""/>
<parser enabled="true"/>
</buildOutputProvider>
<scannerInfoProvider id="specsFile">
<runAction arguments="-E -P -v -dD ${plugin_state_location}/specs.c" command="gcc" useDefault="true"/>
<parser enabled="true"/>
</scannerInfoProvider>
</profile>
</scannerConfigBuildInfo>
<scannerConfigBuildInfo instanceId="com.crt.advproject.toolchain.exe.debug.1281391870;com.crt.advproject.toolchain.exe.debug.1281391870.1757637439;cdt.managedbuild.tool.gnu.c.compiler.mingw.base.1588045403;cdt.managedbuild.tool.gnu.c.compiler.input.451457393">
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfileC"/>
<profile id="org.eclipse.cdt.make.core.GCCStandardMakePerProjectProfile">
<buildOutputProvider>
<openAction enabled="true" filePath=""/>
<parser enabled="true"/>
</buildOutputProvider>
<scannerInfoProvider id="specsFile">
<runAction arguments="-E -P -v -dD ${plugin_state_location}/${specs_file}" command="gcc" useDefault="true"/>
<parser enabled="true"/>
</scannerInfoProvider>
</profile>
<profile id="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfile">
<buildOutputProvider>
<openAction enabled="true" filePath=""/>
<parser enabled="true"/>
</buildOutputProvider>
<scannerInfoProvider id="specsFile">
<runAction arguments="-E -P -v -dD ${plugin_state_location}/${specs_file}" command="gcc" useDefault="true"/>
<parser enabled="true"/>
</scannerInfoProvider>
</profile>
<profile id="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfileCPP">
<buildOutputProvider>
<openAction enabled="true" filePath=""/>
<parser enabled="true"/>
</buildOutputProvider>
<scannerInfoProvider id="specsFile">
<runAction arguments="-E -P -v -dD ${plugin_state_location}/specs.cpp" command="g++" useDefault="true"/>
<parser enabled="true"/>
</scannerInfoProvider>
</profile>
<profile id="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfileC">
<buildOutputProvider>
<openAction enabled="true" filePath=""/>
<parser enabled="true"/>
</buildOutputProvider>
<scannerInfoProvider id="specsFile">
<runAction arguments="-E -P -v -dD ${plugin_state_location}/specs.c" command="gcc" useDefault="true"/>
<parser enabled="true"/>
</scannerInfoProvider>
</profile>
</scannerConfigBuildInfo>
<scannerConfigBuildInfo instanceId="com.crt.advproject.toolchain.exe.debug.1281391870;com.crt.advproject.toolchain.exe.debug.1281391870.1757637439;com.crt.advproject.gas.exe.debug.11272906;com.crt.advproject.assembler.input.1065303549">
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId="com.crt.advproject.GCCManagedMakePerProjectProfile"/>
<profile id="org.eclipse.cdt.make.core.GCCStandardMakePerProjectProfile">
<buildOutputProvider>
<openAction enabled="true" filePath=""/>
<parser enabled="true"/>
</buildOutputProvider>
<scannerInfoProvider id="specsFile">
<runAction arguments="-E -P -v -dD ${plugin_state_location}/${specs_file}" command="gcc" useDefault="true"/>
<parser enabled="true"/>
</scannerInfoProvider>
</profile>
<profile id="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfile">
<buildOutputProvider>
<openAction enabled="true" filePath=""/>
<parser enabled="true"/>
</buildOutputProvider>
<scannerInfoProvider id="specsFile">
<runAction arguments="-E -P -v -dD ${plugin_state_location}/${specs_file}" command="gcc" useDefault="true"/>
<parser enabled="true"/>
</scannerInfoProvider>
</profile>
<profile id="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfileCPP">
<buildOutputProvider>
<openAction enabled="true" filePath=""/>
<parser enabled="true"/>
</buildOutputProvider>
<scannerInfoProvider id="specsFile">
<runAction arguments="-E -P -v -dD ${plugin_state_location}/specs.cpp" command="g++" useDefault="true"/>
<parser enabled="true"/>
</scannerInfoProvider>
</profile>
<profile id="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfileC">
<buildOutputProvider>
<openAction enabled="true" filePath=""/>
<parser enabled="true"/>
</buildOutputProvider>
<scannerInfoProvider id="specsFile">
<runAction arguments="-E -P -v -dD ${plugin_state_location}/specs.c" command="gcc" useDefault="true"/>
<parser enabled="true"/>
</scannerInfoProvider>
</profile>
</scannerConfigBuildInfo>
</storageModule>
<storageModule moduleId="org.eclipse.cdt.internal.ui.text.commentOwnerProjectMappings"/>
<storageModule moduleId="org.eclipse.cdt.make.core.buildtargets">
<buildTargets>
<target name="clean" path="lpc18xx_43xx" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
<buildCommand>rake.bat</buildCommand>
<buildArguments/>
<buildTarget>clean</buildTarget>
<stopOnError>true</stopOnError>
<useDefaultCommand>false</useDefaultCommand>
<runAllBuilders>true</runAllBuilders>
</target>
<target name="clobber" path="lpc18xx_43xx" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
<buildCommand>rake.bat</buildCommand>
<buildArguments/>
<buildTarget>clobber</buildTarget>
<stopOnError>true</stopOnError>
<useDefaultCommand>false</useDefaultCommand>
<runAllBuilders>true</runAllBuilders>
</target>
<target name="release" path="lpc18xx_43xx" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
<buildCommand>rake.bat</buildCommand>
<buildArguments/>
<buildTarget>release</buildTarget>
<stopOnError>true</stopOnError>
<useDefaultCommand>false</useDefaultCommand>
<runAllBuilders>true</runAllBuilders>
</target>
<target name="test" path="lpc18xx_43xx" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
<buildCommand>rake.bat</buildCommand>
<buildArguments/>
<buildTarget>test:all</buildTarget>
<stopOnError>true</stopOnError>
<useDefaultCommand>false</useDefaultCommand>
<runAllBuilders>true</runAllBuilders>
</target>
<target name="test delta" path="lpc18xx_43xx" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
<buildCommand>rake.bat</buildCommand>
<buildArguments/>
<buildTarget>test:delta</buildTarget>
<stopOnError>true</stopOnError>
<useDefaultCommand>false</useDefaultCommand>
<runAllBuilders>true</runAllBuilders>
</target>
<target name="test verbose" path="lpc18xx_43xx" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
<buildCommand>rake.bat</buildCommand>
<buildArguments/>
<buildTarget>verbosity[4] test:all</buildTarget>
<stopOnError>true</stopOnError>
<useDefaultCommand>false</useDefaultCommand>
<runAllBuilders>true</runAllBuilders>
</target>
<target name="test verbose delta" path="lpc18xx_43xx" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
<buildCommand>rake.bat</buildCommand>
<buildArguments/>
<buildTarget>verbosity[4] test:delta</buildTarget>
<stopOnError>true</stopOnError>
<useDefaultCommand>false</useDefaultCommand>
<runAllBuilders>true</runAllBuilders>
</target>
<target name="clean" path="lpc175x_6x" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
<buildCommand>rake.bat</buildCommand>
<buildArguments/>
<buildTarget>clean</buildTarget>
<stopOnError>true</stopOnError>
<useDefaultCommand>false</useDefaultCommand>
<runAllBuilders>true</runAllBuilders>
</target>
<target name="clobber" path="lpc175x_6x" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
<buildCommand>rake.bat</buildCommand>
<buildArguments/>
<buildTarget>clobber</buildTarget>
<stopOnError>true</stopOnError>
<useDefaultCommand>false</useDefaultCommand>
<runAllBuilders>true</runAllBuilders>
</target>
<target name="release" path="lpc175x_6x" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
<buildCommand>rake.bat</buildCommand>
<buildArguments/>
<buildTarget>release</buildTarget>
<stopOnError>true</stopOnError>
<useDefaultCommand>false</useDefaultCommand>
<runAllBuilders>true</runAllBuilders>
</target>
<target name="test" path="lpc175x_6x" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
<buildCommand>rake.bat</buildCommand>
<buildArguments/>
<buildTarget>test:all</buildTarget>
<stopOnError>true</stopOnError>
<useDefaultCommand>false</useDefaultCommand>
<runAllBuilders>true</runAllBuilders>
</target>
<target name="test delta" path="lpc175x_6x" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
<buildCommand>rake.bat</buildCommand>
<buildArguments/>
<buildTarget>test:delta</buildTarget>
<stopOnError>true</stopOnError>
<useDefaultCommand>false</useDefaultCommand>
<runAllBuilders>true</runAllBuilders>
</target>
<target name="test verbose" path="lpc175x_6x" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
<buildCommand>rake.bat</buildCommand>
<buildArguments/>
<buildTarget>verbosity[4] test:all</buildTarget>
<stopOnError>true</stopOnError>
<useDefaultCommand>false</useDefaultCommand>
<runAllBuilders>true</runAllBuilders>
</target>
<target name="test verbose delta" path="lpc175x_6x" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
<buildCommand>rake.bat</buildCommand>
<buildArguments/>
<buildTarget>verbosity[4] test:delta</buildTarget>
<stopOnError>true</stopOnError>
<useDefaultCommand>false</useDefaultCommand>
<runAllBuilders>true</runAllBuilders>
</target>
<target name="clean" path="tests/lpc175x_6x" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
<buildCommand>rake.bat</buildCommand>
<buildArguments/>
<buildTarget>clean</buildTarget>
<stopOnError>true</stopOnError>
<useDefaultCommand>false</useDefaultCommand>
<runAllBuilders>true</runAllBuilders>
</target>
<target name="clobber" path="tests/lpc175x_6x" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
<buildCommand>rake.bat</buildCommand>
<buildArguments/>
<buildTarget>clobber</buildTarget>
<stopOnError>true</stopOnError>
<useDefaultCommand>false</useDefaultCommand>
<runAllBuilders>true</runAllBuilders>
</target>
<target name="release" path="tests/lpc175x_6x" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
<buildCommand>rake.bat</buildCommand>
<buildArguments/>
<buildTarget>release</buildTarget>
<stopOnError>true</stopOnError>
<useDefaultCommand>false</useDefaultCommand>
<runAllBuilders>true</runAllBuilders>
</target>
<target name="test" path="tests/lpc175x_6x" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
<buildCommand>rake.bat</buildCommand>
<buildArguments/>
<buildTarget>test:all</buildTarget>
<stopOnError>true</stopOnError>
<useDefaultCommand>false</useDefaultCommand>
<runAllBuilders>true</runAllBuilders>
</target>
<target name="test delta" path="tests/lpc175x_6x" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
<buildCommand>rake.bat</buildCommand>
<buildArguments/>
<buildTarget>test:delta</buildTarget>
<stopOnError>true</stopOnError>
<useDefaultCommand>false</useDefaultCommand>
<runAllBuilders>true</runAllBuilders>
</target>
<target name="test verbose" path="tests/lpc175x_6x" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
<buildCommand>rake.bat</buildCommand>
<buildArguments/>
<buildTarget>verbosity[4] test:all</buildTarget>
<stopOnError>true</stopOnError>
<useDefaultCommand>false</useDefaultCommand>
<runAllBuilders>true</runAllBuilders>
</target>
<target name="test verbose delta" path="tests/lpc175x_6x" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
<buildCommand>rake.bat</buildCommand>
<buildArguments/>
<buildTarget>verbosity[4] test:delta</buildTarget>
<stopOnError>true</stopOnError>
<useDefaultCommand>false</useDefaultCommand>
<runAllBuilders>true</runAllBuilders>
</target>
</buildTargets>
</storageModule>
<storageModule moduleId="org.eclipse.cdt.core.LanguageSettingsProviders"/>
</cproject>

View File

@ -1,116 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>tinyusb_tests</name>
<comment></comment>
<projects>
</projects>
<buildSpec>
<buildCommand>
<name>org.eclipse.cdt.managedbuilder.core.genmakebuilder</name>
<triggers>clean,full,incremental,</triggers>
<arguments>
<dictionary>
<key>?name?</key>
<value></value>
</dictionary>
<dictionary>
<key>org.eclipse.cdt.make.core.append_environment</key>
<value>true</value>
</dictionary>
<dictionary>
<key>org.eclipse.cdt.make.core.buildArguments</key>
<value></value>
</dictionary>
<dictionary>
<key>org.eclipse.cdt.make.core.buildCommand</key>
<value>make</value>
</dictionary>
<dictionary>
<key>org.eclipse.cdt.make.core.buildLocation</key>
<value>${workspace_loc:/tinyusb/Debug}</value>
</dictionary>
<dictionary>
<key>org.eclipse.cdt.make.core.contents</key>
<value>org.eclipse.cdt.make.core.activeConfigSettings</value>
</dictionary>
<dictionary>
<key>org.eclipse.cdt.make.core.enableAutoBuild</key>
<value>false</value>
</dictionary>
<dictionary>
<key>org.eclipse.cdt.make.core.enableCleanBuild</key>
<value>true</value>
</dictionary>
<dictionary>
<key>org.eclipse.cdt.make.core.enableFullBuild</key>
<value>true</value>
</dictionary>
<dictionary>
<key>org.eclipse.cdt.make.core.stopOnError</key>
<value>true</value>
</dictionary>
<dictionary>
<key>org.eclipse.cdt.make.core.useDefaultBuildCmd</key>
<value>false</value>
</dictionary>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder</name>
<triggers>full,incremental,</triggers>
<arguments>
</arguments>
</buildCommand>
</buildSpec>
<natures>
<nature>org.eclipse.cdt.core.cnature</nature>
<nature>org.eclipse.cdt.managedbuilder.core.managedBuildNature</nature>
<nature>org.eclipse.cdt.managedbuilder.core.ScannerConfigNature</nature>
</natures>
<linkedResources>
<link>
<name>demo_vendor</name>
<type>2</type>
<locationURI>PARENT-1-PROJECT_LOC/vendor</locationURI>
</link>
<link>
<name>demos</name>
<type>2</type>
<locationURI>PARENT-1-PROJECT_LOC/demos</locationURI>
</link>
<link>
<name>tinyusb</name>
<type>2</type>
<locationURI>PARENT-1-PROJECT_LOC/tinyusb</locationURI>
</link>
</linkedResources>
<filteredResources>
<filter>
<id>1382413628300</id>
<name></name>
<type>22</type>
<matcher>
<id>org.eclipse.ui.ide.multiFilter</id>
<arguments>1.0-name-matches-false-false-*.o</arguments>
</matcher>
</filter>
<filter>
<id>1382413628332</id>
<name></name>
<type>22</type>
<matcher>
<id>org.eclipse.ui.ide.multiFilter</id>
<arguments>1.0-name-matches-false-false-*.d</arguments>
</matcher>
</filter>
<filter>
<id>1382413628348</id>
<name></name>
<type>26</type>
<matcher>
<id>org.eclipse.ui.ide.multiFilter</id>
<arguments>1.0-name-matches-false-false-build</arguments>
</matcher>
</filter>
</filteredResources>
</projectDescription>

View File

@ -1 +0,0 @@
just a build folder

View File

@ -1,91 +0,0 @@
---
# Notes:
# Sample project C code is not presently written to produce a release artifact.
# As such, release build options are disabled.
# This sample, therefore, only demonstrates running a collection of unit tests.
:project:
:use_exceptions: TRUE
:use_test_preprocessor: TRUE
:use_auxiliary_dependencies: TRUE
:use_deep_dependencies: TRUE
:build_root: build
# :release_build: TRUE
:test_file_prefix: test_
:release_build:
:output: test_tinyusb_lpc175x_6x.exe
:use_assembly: FALSE
:environment:
:extension:
:executable: .exe
:paths:
:test:
- +:test/**
:source:
- ../../tinyusb/**
- +:../../mcu/lpc175x_6x/**
#- +:../../demos/device/keyboard/*
- -:../../demos/
# - ../vendor/freertos/freertos/Source/*
# - ../vendor/freertos/freertos/Source/portable/MSVC-MingW/*
:support:
- ../support
:defines:
# in order to add common defines:
# 1) remove the trailing [] from the :common: section
# 2) add entries to the :common: section (e.g. :test: has TEST defined)
:commmon: &common_defines
- CFG_TUSB_MCU=MCU_LPC175X_6X -std=gnu99
# - -mx32
- CORE_M4
- __CODE_RED
- _TINY_USB_SOURCE_FILE_
- _TEST_
:test:
- *common_defines
:test_preprocess:
- *common_defines
# :release:
# :release_preprocess:
#:flags:
# :test:
# :compile:
# :dcd_lpc175x_6x.c:
# - -DMCU=MCU_LPC175X_6X
# Ceedling defaults to using gcc for compiling, linking, etc.
# As [:tools] is blank, gcc will be used (so long as it's in your system path)
# See documentation to configure a given toolchain for use
:cmock:
:mock_prefix: mock_
:when_no_prototypes: :warn
:enforce_strict_ordering: TRUE
:plugins:
- :ignore
- :callback
- :array
#:ignore: :args_only
:treat_as:
uint8: HEX8
uint16: HEX16
uint32: UINT32
int8: INT8
bool: UINT8
:plugins:
:load_paths:
- ../vendor/ceedling/plugins
:enabled:
#- stdout_pretty_tests_report
- stdout_ide_tests_report
- module_generator
...

View File

@ -1,4 +0,0 @@
PROJECT_CEEDLING_ROOT = "../vendor/ceedling"
load "#{PROJECT_CEEDLING_ROOT}/lib/rakefile.rb"
task :default => %w[ test:all release ]

View File

@ -1,148 +0,0 @@
/*
* The MIT License (MIT)
*
* Copyright (c) 2019 Ha Thach (tinyusb.org)
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
* This file is part of the TinyUSB stack.
*/
#include <stdlib.h>
#include "unity.h"
#include "tusb_errors.h"
#include "type_helper.h"
#include "mock_usbd_dcd.h"
#include "dcd_lpc175x_6x.h"
LPC_USB_TypeDef lpc_usb;
usbd_device_info_t usbd_devices[CONTROLLER_DEVICE_NUMBER];
extern dcd_dma_descriptor_t* dcd_udca[32];
extern dcd_dma_descriptor_t dcd_dd[DCD_MAX_DD];
void setUp(void)
{
tu_memclr(dcd_udca, 32*4);
tu_memclr(dcd_dd, sizeof(dcd_dma_descriptor_t)*DCD_MAX_DD);
tu_memclr(&lpc_usb, sizeof(LPC_USB_TypeDef));
}
void tearDown(void)
{
}
void test_dd_udca_align(void)
{
TEST_ASSERT_BITS_LOW(128-1, (uint32_t) dcd_udca);
}
void test_dd_structure(void)
{
//------------- word 0 -------------//
TEST_ASSERT_EQUAL( 0, offsetof(dcd_dma_descriptor_t, next));
//------------- word 1 -------------//
TEST_ASSERT_EQUAL( 0, BITFIELD_OFFSET_OF_UINT32(dcd_dma_descriptor_t, 1, mode) );
TEST_ASSERT_EQUAL( 2, BITFIELD_OFFSET_OF_UINT32(dcd_dma_descriptor_t, 1, is_next_valid) );
TEST_ASSERT_EQUAL( 4, BITFIELD_OFFSET_OF_UINT32(dcd_dma_descriptor_t, 1, is_isochronous) );
TEST_ASSERT_EQUAL( 5, BITFIELD_OFFSET_OF_UINT32(dcd_dma_descriptor_t, 1, max_packet_size) );
TEST_ASSERT_EQUAL( 16, BITFIELD_OFFSET_OF_UINT32(dcd_dma_descriptor_t, 1, buffer_length) );
//------------- word 2 -------------//
TEST_ASSERT_EQUAL( 8, offsetof(dcd_dma_descriptor_t, buffer_start_addr) );
//------------- word 3 -------------//
TEST_ASSERT_EQUAL( 0, BITFIELD_OFFSET_OF_UINT32(dcd_dma_descriptor_t, 3, is_retired) );
TEST_ASSERT_EQUAL( 1, BITFIELD_OFFSET_OF_UINT32(dcd_dma_descriptor_t, 3, status) );
TEST_ASSERT_EQUAL( 5, BITFIELD_OFFSET_OF_UINT32(dcd_dma_descriptor_t, 3, iso_last_packet_valid) );
TEST_ASSERT_EQUAL( 6, BITFIELD_OFFSET_OF_UINT32(dcd_dma_descriptor_t, 3, atle_is_lsb_extracted) );
TEST_ASSERT_EQUAL( 7, BITFIELD_OFFSET_OF_UINT32(dcd_dma_descriptor_t, 3, atle_is_msb_extracted) );
TEST_ASSERT_EQUAL( 8, BITFIELD_OFFSET_OF_UINT32(dcd_dma_descriptor_t, 3, atle_message_length_position) );
TEST_ASSERT_EQUAL( 16, BITFIELD_OFFSET_OF_UINT32(dcd_dma_descriptor_t, 3, present_count) );
//------------- word 4 -------------//
}
void test_dcd_init(void)
{
//------------- Code Under Test -------------//
dcd_init();
//------------- slave check -------------//
TEST_ASSERT_EQUAL_HEX( TU_BIN8(11), LPC_USB->USBEpIntEn );
TEST_ASSERT_EQUAL_HEX( DEV_INT_DEVICE_STATUS_MASK | DEV_INT_ENDPOINT_SLOW_MASK | DEV_INT_ERROR_MASK,
LPC_USB->USBDevIntEn );
TEST_ASSERT_EQUAL_HEX( 0, LPC_USB->USBEpIntPri);
//------------- DMA check -------------//
for (uint32_t i=0; i<32; i++)
{
TEST_ASSERT_EQUAL_HEX(dcd_dd+i, dcd_udca[i]);
}
TEST_ASSERT_EQUAL_HEX(dcd_udca, LPC_USB->USBUDCAH);
TEST_ASSERT_EQUAL_HEX(DMA_INT_END_OF_XFER_MASK | DMA_INT_NEW_DD_REQUEST_MASK | DMA_INT_ERROR_MASK,
LPC_USB->USBDMAIntEn);
}
void test_dcd_configure_endpoint_in(void)
{
tusb_desc_endpoint_t const desc_endpoint =
{
.bLength = sizeof(tusb_desc_endpoint_t),
.bDescriptorType = TUSB_DESC_TYPE_ENDPOINT,
.bEndpointAddress = 0x83,
.bmAttributes = { .xfer = TUSB_XFER_INTERRUPT },
.wMaxPacketSize = { .size = 0x08 },
.bInterval = 0x0A
};
dcd_init();
tu_memclr(&lpc_usb, sizeof(LPC_USB_TypeDef)); // clear to examine register after CUT
//------------- Code Under Test -------------//
dcd_pipe_open(0, &desc_endpoint);
uint8_t const phy_ep = 2*3 + 1;
TEST_ASSERT_EQUAL_HEX( TU_BIT(phy_ep), LPC_USB->USBReEp);
TEST_ASSERT_EQUAL_HEX( phy_ep, LPC_USB->USBEpInd);
TEST_ASSERT_EQUAL( desc_endpoint.wMaxPacketSize.size, LPC_USB->USBMaxPSize);
TEST_ASSERT_FALSE( dcd_dd[phy_ep].is_next_valid );
TEST_ASSERT_EQUAL_HEX( 0, dcd_dd[phy_ep].next );
TEST_ASSERT_EQUAL( 0, dcd_dd[phy_ep].mode);
TEST_ASSERT_FALSE( dcd_dd[phy_ep].is_isochronous );
TEST_ASSERT_EQUAL( 0, dcd_dd[phy_ep].buffer_length);
TEST_ASSERT_EQUAL_HEX( 0, dcd_dd[phy_ep].buffer_start_addr);
TEST_ASSERT_TRUE( dcd_dd[phy_ep].is_retired );
TEST_ASSERT_EQUAL( DD_STATUS_NOT_SERVICED, dcd_dd[phy_ep].status);
TEST_ASSERT_FALSE( dcd_dd[phy_ep].iso_last_packet_valid );
TEST_ASSERT_FALSE( dcd_dd[phy_ep].atle_is_lsb_extracted );
TEST_ASSERT_FALSE( dcd_dd[phy_ep].atle_is_msb_extracted );
TEST_ASSERT_FALSE( dcd_dd[phy_ep].atle_message_length_position );
TEST_ASSERT_FALSE( dcd_dd[phy_ep].present_count );
}
void test_dcd_configure_endpoint_out(void)
{
TEST_IGNORE();
}

View File

@ -1,141 +0,0 @@
/*
* The MIT License (MIT)
*
* Copyright (c) 2019 Ha Thach (tinyusb.org)
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
* This file is part of the TinyUSB stack.
*/
#include <stdlib.h>
#include "unity.h"
#include "tusb_errors.h"
#include "type_helper.h"
#include "tusb_descriptors.h"
#include "mock_hid_device.h"
#include "mock_dcd.h"
#include "usbd.h"
void setUp(void)
{
}
void tearDown(void)
{
}
void test_dcd_init_failed(void)
{
dcd_init_ExpectAndReturn(TUSB_ERROR_FAILED);
//------------- Code Under Test -------------//
TEST_ASSERT_EQUAL(TUSB_ERROR_FAILED, usbd_init() );
}
tusb_error_t stub_hidd_init(uint8_t coreid, tusb_desc_interface_t const* p_interface_desc, uint16_t* p_length, int num_call)
{
switch(num_call)
{
case 0:
TEST_ASSERT_EQUAL_HEX(&app_tusb_desc_configuration.keyboard_interface, p_interface_desc);
break;
case 1:
TEST_ASSERT_EQUAL_HEX32(&app_tusb_desc_configuration.mouse_interface, p_interface_desc);
break;
default:
TEST_FAIL();
return TUSB_ERROR_FAILED;
}
return TUSB_ERROR_NONE;
}
void class_init_epxect(void)
{
#if CFG_TUD_HID
hidd_init_StubWithCallback(stub_hidd_init);
#endif
}
void test_usbd_init(void)
{
dcd_init_ExpectAndReturn(TUSB_ERROR_NONE);
class_init_epxect();
dcd_controller_connect_Expect(0);
//------------- Code Under Test -------------//
TEST_ASSERT_STATUS( usbd_init() );
}
void test_usbd_init_ok(void)
{
TEST_IGNORE_MESSAGE("pause device stack");
dcd_init_ExpectAndReturn(TUSB_ERROR_NONE);
hidd_init_StubWithCallback(stub_hidd_init);
dcd_controller_connect_Expect(0);
//------------- Code Under Test -------------//
TEST_ASSERT_EQUAL( TUSB_ERROR_NONE, usbd_init() );
}
void test_usbd_string_descriptor(void)
{
dcd_init_IgnoreAndReturn(TUSB_ERROR_FAILED);
//------------- Code Under Test -------------//
TEST_ASSERT_EQUAL( TUSB_ERROR_FAILED, usbd_init() );
//------------- manufacturer string descriptor -------------//
uint32_t const manufacturer_len = sizeof(CFG_TUD_STRING_MANUFACTURER) - 1;
TEST_ASSERT_EQUAL(manufacturer_len*2 + 2, app_tusb_desc_strings.manufacturer.bLength);
for(uint32_t i=0; i<manufacturer_len; i++)
{
TEST_ASSERT_EQUAL(CFG_TUD_STRING_MANUFACTURER[i], app_tusb_desc_strings.manufacturer.unicode_string[i]);
}
//------------- product string descriptor -------------//
uint32_t const product_len = sizeof(CFG_TUD_STRING_PRODUCT) - 1;
TEST_ASSERT_EQUAL(product_len*2 + 2, app_tusb_desc_strings.product.bLength);
for(uint32_t i=0; i < product_len; i++)
{
TEST_ASSERT_EQUAL(CFG_TUD_STRING_PRODUCT[i], app_tusb_desc_strings.product.unicode_string[i]);
}
//------------- serial string descriptor -------------//
uint32_t const serial_len = sizeof(CFG_TUD_STRING_SERIAL) - 1;
TEST_ASSERT_EQUAL(serial_len*2 + 2, app_tusb_desc_strings.serial.bLength);
for(uint32_t i=0; i<serial_len; i++)
{
TEST_ASSERT_EQUAL(CFG_TUD_STRING_SERIAL[i], app_tusb_desc_strings.serial.unicode_string[i]);
}
}

View File

@ -1 +0,0 @@
just a build folder

View File

@ -1,92 +0,0 @@
---
# Notes:
# Sample project C code is not presently written to produce a release artifact.
# As such, release build options are disabled.
# This sample, therefore, only demonstrates running a collection of unit tests.
:project:
:use_exceptions: TRUE
:use_test_preprocessor: TRUE
:use_auxiliary_dependencies: TRUE
:use_deep_dependencies: TRUE
:build_root: build
# :release_build: TRUE
:test_file_prefix: test_
:release_build:
:output: test_tinyusb.exe
:use_assembly: FALSE
:environment:
:extension:
:executable: .exe
:paths:
:test:
- +:test/**
:support:
- ../support
:source:
- ../../tinyusb/**
- +:../../mcu/lpc43xx/**
#- +:../../demos/device/keyboard/*
- -:../../demos/
#- ../../vendor/freertos/freertos/Source/*
#- ../../vendor/freertos/freertos/Source/portable/MSVC-MingW/*
:defines:
# in order to add common defines:
# 1) remove the trailing [] from the :common: section
# 2) add entries to the :common: section (e.g. :test: has TEST defined)
:commmon: &common_defines
- CFG_TUSB_MCU=MCU_LPC43XX -std=gnu99
# - -mx32
- CORE_M4
- __CODE_RED
- _TINY_USB_SOURCE_FILE_
- _TEST_
:test:
- *common_defines
:test_preprocess:
- *common_defines
# :release:
# :release_preprocess:
#:flags:
# :test:
# :compile:
# :dcd_lpc175x_6x.c:
# - -DMCU=MCU_LPC175X_6X
# Ceedling defaults to using gcc for compiling, linking, etc.
# As [:tools] is blank, gcc will be used (so long as it's in your system path)
# See documentation to configure a given toolchain for use
:cmock:
:mock_prefix: mock_
:when_no_prototypes: :warn
:enforce_strict_ordering: TRUE
:plugins:
- :ignore
- :callback
- :array
#:ignore: :args_only
:treat_as:
uint8: HEX8
uint16: HEX16
uint32: UINT32
int8: INT8
bool: UINT8
:plugins:
:load_paths:
- ../vendor/ceedling/plugins
:enabled:
#- stdout_pretty_tests_report
- stdout_ide_tests_report
- module_generator
...

View File

@ -1,4 +0,0 @@
PROJECT_CEEDLING_ROOT = "../vendor/ceedling"
load "#{PROJECT_CEEDLING_ROOT}/lib/rakefile.rb"
task :default => %w[ test:all release ]

View File

@ -1,58 +0,0 @@
/*
* The MIT License (MIT)
*
* Copyright (c) 2019 Ha Thach (tinyusb.org)
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
* This file is part of the TinyUSB stack.
*/
/** \ingroup TBD
* \defgroup TBD
* \brief TBD
*
* @{
*/
#ifndef _TUSB_CDC_CALLBACK_H_
#define _TUSB_CDC_CALLBACK_H_
#include "common/common.h"
#include "cdc_host.h"
#ifdef __cplusplus
extern "C" {
#endif
void tusbh_cdc_mounted_cb(uint8_t dev_addr);
void tusbh_cdc_unmounted_cb(uint8_t dev_addr);
void tusbh_cdc_xfer_isr(uint8_t dev_addr, xfer_result_t event, cdc_pipeid_t pipe_id, uint32_t xferred_bytes);
void tusbh_cdc_rndis_mounted_cb(uint8_t dev_addr);
void tusbh_cdc_rndis_unmounted_isr(uint8_t dev_addr);
#ifdef __cplusplus
}
#endif
#endif /* _TUSB_CDC_CALLBACK_H_ */
/** @} */

View File

@ -1,276 +0,0 @@
/*
* The MIT License (MIT)
*
* Copyright (c) 2019 Ha Thach (tinyusb.org)
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
* This file is part of the TinyUSB stack.
*/
#include "tusb_option.h"
#include "descriptor_cdc.h"
//--------------------------------------------------------------------+
// CDC Serials
//--------------------------------------------------------------------+
CFG_TUSB_MEM_SECTION
const cdc_configuration_desc_t cdc_config_descriptor =
{
.configuration =
{
.bLength = sizeof(tusb_desc_configuration_t),
.bDescriptorType = TUSB_DESC_TYPE_CONFIGURATION,
.wTotalLength = sizeof(cdc_configuration_desc_t),
.bNumInterfaces = 2,
.bConfigurationValue = 1,
.iConfiguration = 0x00,
.bmAttributes = TUSB_DESC_CONFIG_ATT_BUS_POWER,
.bMaxPower = TUSB_DESC_CONFIG_POWER_MA(100)
},
// IAD points to CDC Interfaces
.cdc_iad =
{
.bLength = sizeof(tusb_desc_interface_assoc_t),
.bDescriptorType = TUSB_DESC_TYPE_INTERFACE_ASSOCIATION,
.bFirstInterface = 1,
.bInterfaceCount = 2,
.bFunctionClass = TUSB_CLASS_CDC,
.bFunctionSubClass = CDC_COMM_SUBCLASS_ABSTRACT_CONTROL_MODEL,
.bFunctionProtocol = CDC_COMM_PROTOCOL_ATCOMMAND,
.iFunction = 0
},
// USB CDC Serial Interface
//------------- CDC Communication Interface -------------//
.cdc_comm_interface =
{
.bLength = sizeof(tusb_desc_interface_t),
.bDescriptorType = TUSB_DESC_TYPE_INTERFACE,
.bInterfaceNumber = 1,
.bAlternateSetting = 0,
.bNumEndpoints = 1,
.bInterfaceClass = TUSB_CLASS_CDC,
.bInterfaceSubClass = CDC_COMM_SUBCLASS_ABSTRACT_CONTROL_MODEL,
.bInterfaceProtocol = CDC_COMM_PROTOCOL_ATCOMMAND,
.iInterface = 0x00
},
.cdc_header =
{
.bLength = sizeof(cdc_desc_func_header_t),
.bDescriptorType = TUSB_DESC_TYPE_INTERFACE_CLASS_SPECIFIC,
.bDescriptorSubType = CDC_FUNC_DESC_HEADER,
.bcdCDC = 0x0120
},
.cdc_acm =
{
.bLength = sizeof(cdc_desc_func_acm_t),
.bDescriptorType = TUSB_DESC_TYPE_INTERFACE_CLASS_SPECIFIC,
.bDescriptorSubType = CDC_FUNC_DESC_ABSTRACT_CONTROL_MANAGEMENT,
.bmCapabilities = { // 0x06
.support_line_request = 1,
.support_send_break = 1
}
},
.cdc_union =
{
.bLength = sizeof(cdc_desc_func_union_t), // plus number of
.bDescriptorType = TUSB_DESC_TYPE_INTERFACE_CLASS_SPECIFIC,
.bDescriptorSubType = CDC_FUNC_DESC_UNION,
.bControlInterface = 1,
.bSubordinateInterface = 2,
},
.cdc_endpoint_notification =
{
.bLength = sizeof(tusb_desc_endpoint_t),
.bDescriptorType = TUSB_DESC_TYPE_ENDPOINT,
.bEndpointAddress = 0x81,
.bmAttributes = { .xfer = TUSB_XFER_INTERRUPT },
.wMaxPacketSize = 8,
.bInterval = 0x0a // lowest polling rate
},
//------------- CDC Data Interface -------------//
.cdc_data_interface =
{
.bLength = sizeof(tusb_desc_interface_t),
.bDescriptorType = TUSB_DESC_TYPE_INTERFACE,
.bInterfaceNumber = 2,
.bAlternateSetting = 0x00,
.bNumEndpoints = 2,
.bInterfaceClass = TUSB_CLASS_CDC_DATA,
.bInterfaceSubClass = 0,
.bInterfaceProtocol = 0,
.iInterface = 0x00
},
.cdc_endpoint_out =
{
.bLength = sizeof(tusb_desc_endpoint_t),
.bDescriptorType = TUSB_DESC_TYPE_ENDPOINT,
.bEndpointAddress = 2,
.bmAttributes = { .xfer = TUSB_XFER_BULK },
.wMaxPacketSize = 64,
.bInterval = 0
},
.cdc_endpoint_in =
{
.bLength = sizeof(tusb_desc_endpoint_t),
.bDescriptorType = TUSB_DESC_TYPE_ENDPOINT,
.bEndpointAddress = 0x82,
.bmAttributes = { .xfer = TUSB_XFER_BULK },
.wMaxPacketSize = 64,
.bInterval = 0
},
};
//--------------------------------------------------------------------+
// CDC RNSID
//--------------------------------------------------------------------+
CFG_TUSB_MEM_SECTION
const cdc_configuration_desc_t rndis_config_descriptor =
{
.configuration =
{
.bLength = sizeof(tusb_desc_configuration_t),
.bDescriptorType = TUSB_DESC_TYPE_CONFIGURATION,
.wTotalLength = sizeof(cdc_configuration_desc_t),
.bNumInterfaces = 2,
.bConfigurationValue = 1,
.iConfiguration = 0x00,
.bmAttributes = TUSB_DESC_CONFIG_ATT_BUS_POWER,
.bMaxPower = TUSB_DESC_CONFIG_POWER_MA(100)
},
// IAD points to CDC Interfaces
.cdc_iad =
{
.bLength = sizeof(tusb_desc_interface_assoc_t),
.bDescriptorType = TUSB_DESC_TYPE_INTERFACE_ASSOCIATION,
.bFirstInterface = 1,
.bInterfaceCount = 2,
.bFunctionClass = TUSB_CLASS_CDC,
.bFunctionSubClass = CDC_COMM_SUBCLASS_ABSTRACT_CONTROL_MODEL,
.bFunctionProtocol = 0,
.iFunction = 0
},
// USB CDC Serial Interface
//------------- CDC Communication Interface -------------//
.cdc_comm_interface =
{
.bLength = sizeof(tusb_desc_interface_t),
.bDescriptorType = TUSB_DESC_TYPE_INTERFACE,
.bInterfaceNumber = 1,
.bAlternateSetting = 0,
.bNumEndpoints = 1,
.bInterfaceClass = TUSB_CLASS_CDC,
.bInterfaceSubClass = CDC_COMM_SUBCLASS_ABSTRACT_CONTROL_MODEL,
.bInterfaceProtocol = 0xff, // RNDIS is vendor specific protocol
.iInterface = 0x00
},
.cdc_header =
{
.bLength = sizeof(cdc_desc_func_header_t),
.bDescriptorType = TUSB_DESC_TYPE_INTERFACE_CLASS_SPECIFIC,
.bDescriptorSubType = CDC_FUNC_DESC_HEADER,
.bcdCDC = 0x0120
},
.cdc_acm =
{
.bLength = sizeof(cdc_desc_func_acm_t),
.bDescriptorType = TUSB_DESC_TYPE_INTERFACE_CLASS_SPECIFIC,
.bDescriptorSubType = CDC_FUNC_DESC_ABSTRACT_CONTROL_MANAGEMENT,
.bmCapabilities = { 0 }
},
.cdc_union =
{
.bLength = sizeof(cdc_desc_func_union_t), // plus number of
.bDescriptorType = TUSB_DESC_TYPE_INTERFACE_CLASS_SPECIFIC,
.bDescriptorSubType = CDC_FUNC_DESC_UNION,
.bControlInterface = 1,
.bSubordinateInterface = 2,
},
.cdc_endpoint_notification =
{
.bLength = sizeof(tusb_desc_endpoint_t),
.bDescriptorType = TUSB_DESC_TYPE_ENDPOINT,
.bEndpointAddress = 0x81,
.bmAttributes = { .xfer = TUSB_XFER_INTERRUPT },
.wMaxPacketSize = 8,
.bInterval = 0x0a // lowest polling rate
},
//------------- CDC Data Interface -------------//
.cdc_data_interface =
{
.bLength = sizeof(tusb_desc_interface_t),
.bDescriptorType = TUSB_DESC_TYPE_INTERFACE,
.bInterfaceNumber = 2,
.bAlternateSetting = 0x00,
.bNumEndpoints = 2,
.bInterfaceClass = TUSB_CLASS_CDC_DATA,
.bInterfaceSubClass = 0,
.bInterfaceProtocol = 0,
.iInterface = 0x00
},
.cdc_endpoint_out =
{
.bLength = sizeof(tusb_desc_endpoint_t),
.bDescriptorType = TUSB_DESC_TYPE_ENDPOINT,
.bEndpointAddress = 2,
.bmAttributes = { .xfer = TUSB_XFER_BULK },
.wMaxPacketSize = 512,
.bInterval = 0
},
.cdc_endpoint_in =
{
.bLength = sizeof(tusb_desc_endpoint_t),
.bDescriptorType = TUSB_DESC_TYPE_ENDPOINT,
.bEndpointAddress = 0x82,
.bmAttributes = { .xfer = TUSB_XFER_BULK },
.wMaxPacketSize = 512,
.bInterval = 0
},
};

View File

@ -1,73 +0,0 @@
/*
* The MIT License (MIT)
*
* Copyright (c) 2019 Ha Thach (tinyusb.org)
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
* This file is part of the TinyUSB stack.
*/
/** \ingroup TBD
* \defgroup TBD
* \brief TBD
*
* @{
*/
#ifndef _TUSB_DESCRIPTOR_CDC_H_
#define _TUSB_DESCRIPTOR_CDC_H_
#include "common/common.h"
#include "class/cdc.h"
#ifdef __cplusplus
extern "C" {
#endif
typedef struct
{
tusb_desc_configuration_t configuration;
tusb_desc_interface_assoc_t cdc_iad;
//CDC Control Interface
tusb_desc_interface_t cdc_comm_interface;
cdc_desc_func_header_t cdc_header;
cdc_desc_func_acm_t cdc_acm;
cdc_desc_func_union_t cdc_union;
tusb_desc_endpoint_t cdc_endpoint_notification;
//CDC Data Interface
tusb_desc_interface_t cdc_data_interface;
tusb_desc_endpoint_t cdc_endpoint_out;
tusb_desc_endpoint_t cdc_endpoint_in;
} cdc_configuration_desc_t;
extern const cdc_configuration_desc_t cdc_config_descriptor;
extern const cdc_configuration_desc_t rndis_config_descriptor;
#ifdef __cplusplus
}
#endif
#endif /* _TUSB_DESCRIPTOR_CDC_H_ */
/** @} */

View File

@ -1,278 +0,0 @@
/*
* The MIT License (MIT)
*
* Copyright (c) 2019 Ha Thach (tinyusb.org)
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
* This file is part of the TinyUSB stack.
*/
#include "stdlib.h"
#include "unity.h"
#include "tusb_option.h"
#include "tusb_errors.h"
#include "binary.h"
#include "type_helper.h"
#include "mock_osal.h"
#include "mock_hcd.h"
#include "mock_usbh.h"
#include "mock_cdc_callback.h"
#include "descriptor_cdc.h"
#include "cdc_host.h"
#if CFG_TUH_CDC_RNDIS // TODO enable
#include "cdc_rndis_host.h"
#endif
static uint8_t dev_addr;
static uint16_t length;
static tusb_desc_interface_t const * p_comm_interface = &cdc_config_descriptor.cdc_comm_interface;
static tusb_desc_endpoint_t const * p_endpoint_notification = &cdc_config_descriptor.cdc_endpoint_notification;
static tusb_desc_endpoint_t const * p_endpoint_out = &cdc_config_descriptor.cdc_endpoint_out;
static tusb_desc_endpoint_t const * p_endpoint_in = &cdc_config_descriptor.cdc_endpoint_in;
extern cdch_data_t cdch_data[CFG_TUSB_HOST_DEVICE_MAX];
static cdch_data_t * p_cdc = &cdch_data[0];
void setUp(void)
{
length = 0;
dev_addr = 1;
tu_memclr(cdch_data, sizeof(cdch_data_t)*CFG_TUSB_HOST_DEVICE_MAX);
}
void tearDown(void)
{
}
//--------------------------------------------------------------------+
// OPEN
//--------------------------------------------------------------------+
void test_cdch_open_failed_to_open_notification_endpoint(void)
{
pipe_handle_t null_hdl = {0};
hcd_edpt_open_ExpectAndReturn(dev_addr, p_endpoint_notification, TUSB_CLASS_CDC, null_hdl);
//------------- CUT -------------//
TEST_ASSERT_EQUAL(TUSB_ERROR_HCD_OPEN_PIPE_FAILED, cdch_open(dev_addr, p_comm_interface, &length));
}
void test_cdch_open_failed_to_open_data_endpoint_out(void)
{
pipe_handle_t dummy_hld = { .dev_addr = 1 };
pipe_handle_t null_hdl = {0};
hcd_edpt_open_ExpectAndReturn(dev_addr, p_endpoint_notification, TUSB_CLASS_CDC, dummy_hld);
hcd_edpt_open_ExpectAndReturn(dev_addr, p_endpoint_out, TUSB_CLASS_CDC, null_hdl);
//------------- CUT -------------//
TEST_ASSERT_EQUAL(TUSB_ERROR_HCD_OPEN_PIPE_FAILED, cdch_open(dev_addr, p_comm_interface, &length));
}
void test_cdch_open_failed_to_open_data_endpoint_in(void)
{
pipe_handle_t dummy_hld = { .dev_addr = 1 };
pipe_handle_t null_hdl = {0};
hcd_edpt_open_ExpectAndReturn(dev_addr, p_endpoint_notification, TUSB_CLASS_CDC, dummy_hld);
hcd_edpt_open_ExpectAndReturn(dev_addr, p_endpoint_out, TUSB_CLASS_CDC, dummy_hld);
hcd_edpt_open_ExpectAndReturn(dev_addr, p_endpoint_in, TUSB_CLASS_CDC, null_hdl);
//------------- CUT -------------//
TEST_ASSERT_EQUAL(TUSB_ERROR_HCD_OPEN_PIPE_FAILED, cdch_open(dev_addr, p_comm_interface, &length));
}
void test_cdch_open_length_check(void)
{
const uint16_t expected_length =
//------------- Comm Interface -------------//
sizeof(tusb_desc_interface_t) + sizeof(cdc_desc_func_header_t) +
sizeof(cdc_desc_func_acm_t) + sizeof(cdc_desc_func_union_t) +
sizeof(tusb_desc_endpoint_t) +
//------------- Data Interface -------------//
sizeof(tusb_desc_interface_t) + 2*sizeof(tusb_desc_endpoint_t);
pipe_handle_t dummy_hld = { .dev_addr = 1 };
hcd_edpt_open_IgnoreAndReturn(dummy_hld);
tusbh_cdc_mounted_cb_Expect(dev_addr);
//------------- CUT -------------//
TEST_ASSERT_EQUAL( TUSB_ERROR_NONE, cdch_open(dev_addr, p_comm_interface, &length) );
TEST_ASSERT_EQUAL(expected_length, length);
}
void test_cdch_open_interface_number_check(void)
{
pipe_handle_t dummy_hld = { .dev_addr = 1 };
hcd_edpt_open_IgnoreAndReturn(dummy_hld);
tusbh_cdc_mounted_cb_Expect(dev_addr);
//------------- CUT -------------//
TEST_ASSERT_EQUAL( TUSB_ERROR_NONE, cdch_open(dev_addr, p_comm_interface, &length) );
TEST_ASSERT_EQUAL(1, p_cdc->interface_number);
}
void test_cdch_open_protocol_check(void)
{
pipe_handle_t dummy_hld = { .dev_addr = 1 };
hcd_edpt_open_IgnoreAndReturn(dummy_hld);
tusbh_cdc_mounted_cb_Expect(dev_addr);
//------------- CUT -------------//
TEST_ASSERT_EQUAL( TUSB_ERROR_NONE, cdch_open(dev_addr, p_comm_interface, &length) );
TEST_ASSERT_EQUAL(p_comm_interface->bInterfaceProtocol, p_cdc->interface_protocol);
}
void test_cdch_open_acm_capacity_check(void)
{
pipe_handle_t dummy_hld = { .dev_addr = 1 };
hcd_edpt_open_IgnoreAndReturn(dummy_hld);
tusbh_cdc_mounted_cb_Expect(dev_addr);
//------------- CUT -------------//
TEST_ASSERT_EQUAL( TUSB_ERROR_NONE, cdch_open(dev_addr, p_comm_interface, &length) );
TEST_ASSERT_EQUAL_MEMORY(&cdc_config_descriptor.cdc_acm.bmCapabilities, &p_cdc->acm_capability, 1);
}
//--------------------------------------------------------------------+
// CLOSE
//--------------------------------------------------------------------+
void test_cdch_close_device(void)
{
pipe_handle_t pipe_notification = { .dev_addr = 1, .xfer_type = TUSB_XFER_INTERRUPT };
pipe_handle_t pipe_out = { .dev_addr = 1, .xfer_type = TUSB_XFER_BULK, .index = 0 };
pipe_handle_t pipe_int = { .dev_addr = 1, .xfer_type = TUSB_XFER_BULK, .index = 1 };
hcd_edpt_open_ExpectAndReturn(dev_addr, p_endpoint_notification, TUSB_CLASS_CDC, pipe_notification);
hcd_edpt_open_ExpectAndReturn(dev_addr, p_endpoint_out, TUSB_CLASS_CDC, pipe_out);
hcd_edpt_open_ExpectAndReturn(dev_addr, p_endpoint_in, TUSB_CLASS_CDC, pipe_int);
tusbh_cdc_mounted_cb_Expect(dev_addr);
TEST_ASSERT_EQUAL( TUSB_ERROR_NONE, cdch_open(dev_addr, p_comm_interface, &length) );
hcd_pipe_close_ExpectAndReturn(pipe_notification , TUSB_ERROR_NONE);
hcd_pipe_close_ExpectAndReturn(pipe_int , TUSB_ERROR_NONE);
hcd_pipe_close_ExpectAndReturn(pipe_out , TUSB_ERROR_NONE);
tusbh_cdc_unmounted_cb_Expect(dev_addr);
//------------- CUT -------------//
cdch_close(dev_addr);
}
//--------------------------------------------------------------------+
// CHECKING API
//--------------------------------------------------------------------+
void test_cdc_serial_is_mounted_not_configured(void)
{
tusbh_device_get_mounted_class_flag_ExpectAndReturn(dev_addr, 0);
TEST_ASSERT_FALSE( tusbh_cdc_serial_is_mounted(dev_addr) );
}
void test_cdc_serial_is_mounted_protocol_zero(void)
{
tusbh_device_get_mounted_class_flag_ExpectAndReturn(dev_addr, TU_BIT(TUSB_CLASS_CDC) );
cdch_data[0].interface_protocol = 0;
TEST_ASSERT_FALSE( tusbh_cdc_serial_is_mounted(dev_addr) );
}
void test_cdc_serial_is_mounted_protocol_is_vendor(void)
{
tusbh_device_get_mounted_class_flag_ExpectAndReturn(dev_addr, TU_BIT(TUSB_CLASS_CDC) );
cdch_data[0].interface_protocol = 0xff;
TEST_ASSERT_FALSE( tusbh_cdc_serial_is_mounted(dev_addr) );
}
void test_cdc_serial_is_mounted_protocol_is_at_command(void)
{
tusbh_device_get_mounted_class_flag_ExpectAndReturn(dev_addr, TU_BIT(TUSB_CLASS_CDC) );
cdch_data[0].interface_protocol = CDC_COMM_PROTOCOL_ATCOMMAND;
TEST_ASSERT( tusbh_cdc_serial_is_mounted(dev_addr) );
}
//--------------------------------------------------------------------+
// TRANSFER API
//--------------------------------------------------------------------+
void test_cdc_xfer_notification_pipe(void)
{
pipe_handle_t pipe_notification = { .dev_addr = 1, .xfer_type = TUSB_XFER_INTERRUPT };
pipe_handle_t pipe_out = { .dev_addr = 1, .xfer_type = TUSB_XFER_BULK, .index = 0 };
pipe_handle_t pipe_in = { .dev_addr = 1, .xfer_type = TUSB_XFER_BULK, .index = 1 };
cdch_data[dev_addr-1].pipe_notification = pipe_notification;
cdch_data[dev_addr-1].pipe_out = pipe_out;
cdch_data[dev_addr-1].pipe_in = pipe_in;
tusbh_cdc_xfer_isr_Expect(dev_addr, XFER_RESULT_SUCCESS, CDC_PIPE_NOTIFICATION, 10);
//------------- CUT -------------//
cdch_isr(pipe_notification, XFER_RESULT_SUCCESS, 10);
}
void test_cdc_xfer_pipe_out(void)
{
pipe_handle_t pipe_notification = { .dev_addr = 1, .xfer_type = TUSB_XFER_INTERRUPT };
pipe_handle_t pipe_out = { .dev_addr = 1, .xfer_type = TUSB_XFER_BULK, .index = 0 };
pipe_handle_t pipe_in = { .dev_addr = 1, .xfer_type = TUSB_XFER_BULK, .index = 1 };
cdch_data[dev_addr-1].pipe_notification = pipe_notification;
cdch_data[dev_addr-1].pipe_out = pipe_out;
cdch_data[dev_addr-1].pipe_in = pipe_in;
tusbh_cdc_xfer_isr_Expect(dev_addr, XFER_RESULT_FAILED, CDC_PIPE_DATA_OUT, 20);
//------------- CUT -------------//
cdch_isr(pipe_out, XFER_RESULT_FAILED, 20);
}
void test_cdc_xfer_pipe_in(void)
{
pipe_handle_t pipe_notification = { .dev_addr = 1, .xfer_type = TUSB_XFER_INTERRUPT };
pipe_handle_t pipe_out = { .dev_addr = 1, .xfer_type = TUSB_XFER_BULK, .index = 0 };
pipe_handle_t pipe_in = { .dev_addr = 1, .xfer_type = TUSB_XFER_BULK, .index = 1 };
cdch_data[dev_addr-1].pipe_notification = pipe_notification;
cdch_data[dev_addr-1].pipe_out = pipe_out;
cdch_data[dev_addr-1].pipe_in = pipe_in;
tusbh_cdc_xfer_isr_Expect(dev_addr, XFER_RESULT_STALLED, CDC_PIPE_DATA_IN, 0);
//------------- CUT -------------//
cdch_isr(pipe_in, XFER_RESULT_STALLED, 0);
}

View File

@ -1,304 +0,0 @@
/*
* The MIT License (MIT)
*
* Copyright (c) 2019 Ha Thach (tinyusb.org)
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
* This file is part of the TinyUSB stack.
*/
void setUp(void)
{
}
void tearDown(void)
{
}
#if 0 // TODO enable
#include "stdlib.h"
#include "unity.h"
#include "tusb_option.h"
#include "tusb_errors.h"
#include "binary.h"
#include "type_helper.h"
#include "mock_osal.h"
#include "mock_hcd.h"
#include "mock_usbh.h"
#include "mock_cdc_callback.h"
#include "descriptor_cdc.h"
#include "cdc_host.h"
#include "cdc_rndis_host.h"
static uint8_t dev_addr;
static uint16_t length;
static tusb_desc_interface_t const * p_comm_interface = &rndis_config_descriptor.cdc_comm_interface;
static tusb_desc_endpoint_t const * p_endpoint_notification = &rndis_config_descriptor.cdc_endpoint_notification;
static tusb_desc_endpoint_t const * p_endpoint_out = &rndis_config_descriptor.cdc_endpoint_out;
static tusb_desc_endpoint_t const * p_endpoint_in = &rndis_config_descriptor.cdc_endpoint_in;
static pipe_handle_t pipe_notification = { .dev_addr = 1, .xfer_type = TUSB_XFER_INTERRUPT };
static pipe_handle_t pipe_out = { .dev_addr = 1, .xfer_type = TUSB_XFER_BULK, .index = 0 };
static pipe_handle_t pipe_in = { .dev_addr = 1, .xfer_type = TUSB_XFER_BULK, .index = 1 };
extern cdch_data_t cdch_data[CFG_TUSB_HOST_DEVICE_MAX];
extern rndish_data_t rndish_data[CFG_TUSB_HOST_DEVICE_MAX];
static cdch_data_t * p_cdc = &cdch_data[0];
static rndish_data_t * p_rndis = &rndish_data[0];
enum {
bmrequest_send = 0x21,
bmrequest_get = 0xA1
};
void stub_mutex_wait(osal_mutex_handle_t mutex_hdl, uint32_t msec, tusb_error_t *p_error, int num_call)
{
*p_error = TUSB_ERROR_NONE;
}
void setUp(void)
{
length = 0;
dev_addr = 1;
for (uint8_t i=0; i<CFG_TUSB_HOST_DEVICE_MAX; i++)
{
osal_semaphore_create_ExpectAndReturn( &rndish_data[i].semaphore_notification, &rndish_data[i].semaphore_notification);
}
cdch_init();
osal_mutex_wait_StubWithCallback(stub_mutex_wait);
osal_mutex_release_IgnoreAndReturn(TUSB_ERROR_NONE);
hcd_edpt_open_ExpectAndReturn(dev_addr, p_endpoint_notification, TUSB_CLASS_CDC, pipe_notification);
hcd_edpt_open_ExpectAndReturn(dev_addr, p_endpoint_out, TUSB_CLASS_CDC, pipe_out);
hcd_edpt_open_ExpectAndReturn(dev_addr, p_endpoint_in, TUSB_CLASS_CDC, pipe_in);
}
void tearDown(void)
{
}
static rndis_msg_initialize_t msg_init =
{
.type = RNDIS_MSG_INITIALIZE,
.length = sizeof(rndis_msg_initialize_t),
.request_id = 1, // TODO should use some magic number
.major_version = 1,
.minor_version = 0,
.max_xfer_size = 0x4000 // TODO mimic windows
};
static rndis_msg_initialize_cmplt_t msg_init_cmplt =
{
.type = RNDIS_MSG_INITIALIZE_CMPLT,
.length = sizeof(rndis_msg_initialize_cmplt_t),
.request_id = 1,
.status = RNDIS_STATUS_SUCCESS,
.major_version = 1,
.minor_version = 0,
.device_flags = 0x10,
.medium = 0, // TODO cannot find info on this
.max_packet_per_xfer = 1,
.max_xfer_size = 0x100, // TODO change later
.packet_alignment_factor = 5 // aligment of each RNDIS message (payload) = 2^factor
};
static rndis_msg_query_t msg_query_permanent_addr =
{
.type = RNDIS_MSG_QUERY,
.length = sizeof(rndis_msg_query_t)+6,
.request_id = 1,
.oid = RNDIS_OID_802_3_PERMANENT_ADDRESS,
.buffer_length = 6,
.buffer_offset = 20,
.oid_buffer = {0, 0, 0, 0, 0, 0}
};
static rndis_msg_query_cmplt_t msg_query_permanent_addr_cmplt =
{
.type = RNDIS_MSG_QUERY_CMPLT,
.length = sizeof(rndis_msg_query_cmplt_t)+6,
.request_id = 1,
.status = RNDIS_STATUS_SUCCESS,
.buffer_length = 6,
.buffer_offset = 16,
.oid_buffer = "CAFEBB"
};
static rndis_msg_set_t msg_set_packet_filter =
{
.type = RNDIS_MSG_SET,
.length = sizeof(rndis_msg_set_t)+4,
.request_id = 1,
.oid = RNDIS_OID_GEN_CURRENT_PACKET_FILTER,
.buffer_length = 4,
.buffer_offset = 20,
.oid_buffer = {RNDIS_PACKET_TYPE_DIRECTED | RNDIS_PACKET_TYPE_MULTICAST | RNDIS_PACKET_TYPE_BROADCAST, 0, 0, 0}
};
static rndis_msg_set_cmplt_t msg_set_packet_filter_cmplt =
{
.type = RNDIS_MSG_SET_CMPLT,
.length = sizeof(rndis_msg_set_cmplt_t),
.request_id = 1,
.status = RNDIS_STATUS_SUCCESS
};
static tusb_error_t stub_pipe_notification_xfer(pipe_handle_t pipe_hdl, uint8_t buffer[], uint16_t total_bytes, bool int_on_complete, int num_call)
{
TEST_ASSERT( pipehandle_is_equal(pipe_notification, pipe_hdl) );
TEST_ASSERT_EQUAL( 8, total_bytes );
TEST_ASSERT( int_on_complete );
buffer[0] = 1; // response available
cdch_isr(pipe_hdl, XFER_RESULT_SUCCESS, 8);
return TUSB_ERROR_NONE;
}
void stub_sem_wait_success(osal_semaphore_handle_t const sem_hdl, uint32_t msec, tusb_error_t *p_error, int num_call)
{
TEST_ASSERT_EQUAL_HEX(p_rndis->sem_notification_hdl, sem_hdl);
(*p_error) = TUSB_ERROR_NONE;
}
void stub_sem_wait_timeout(osal_semaphore_handle_t const sem_hdl, uint32_t msec, tusb_error_t *p_error, int num_call)
{
(*p_error) = TUSB_ERROR_OSAL_TIMEOUT;
}
//------------- Test Code -------------//
void test_rndis_send_initalize_failed(void)
{
usbh_control_xfer_subtask_ExpectWithArrayAndReturn(
dev_addr, bmrequest_send, SEND_ENCAPSULATED_COMMAND, 0, p_comm_interface->bInterfaceNumber,
sizeof(rndis_msg_initialize_t), (uint8_t*)&msg_init, sizeof(rndis_msg_initialize_t), TUSB_ERROR_OSAL_TIMEOUT);
tusbh_cdc_mounted_cb_Expect(dev_addr);
//------------- Code Under Test -------------//
TEST_ASSERT_EQUAL( TUSB_ERROR_NONE, cdch_open_subtask(dev_addr, p_comm_interface, &length) );
}
void test_rndis_initialization_notification_timeout(void)
{
usbh_control_xfer_subtask_ExpectWithArrayAndReturn(
dev_addr, bmrequest_send, SEND_ENCAPSULATED_COMMAND, 0, p_comm_interface->bInterfaceNumber,
sizeof(rndis_msg_initialize_t), (uint8_t*)&msg_init, sizeof(rndis_msg_initialize_t), TUSB_ERROR_NONE);
hcd_pipe_xfer_IgnoreAndReturn(TUSB_ERROR_NONE);
osal_semaphore_wait_StubWithCallback(stub_sem_wait_timeout);
tusbh_cdc_mounted_cb_Expect(dev_addr);
//------------- Code Under Test -------------//
TEST_ASSERT_STATUS( cdch_open_subtask(dev_addr, p_comm_interface, &length) );
TEST_ASSERT_FALSE(p_cdc->is_rndis);
}
tusb_error_t stub_control_xfer(uint8_t addr, uint8_t bmRequestType, uint8_t bRequest,
uint16_t wValue, uint16_t wIndex, uint16_t wLength, uint8_t* data, int num_call )
{
TEST_ASSERT_EQUAL(p_comm_interface->bInterfaceNumber, wIndex);
TEST_ASSERT_EQUAL(0, wValue);
TEST_ASSERT_EQUAL(dev_addr, addr);
switch(num_call)
{
//------------- Initialize -------------//
case 0*2+0: // initialize
TEST_ASSERT_EQUAL(bmrequest_send, bmRequestType);
TEST_ASSERT_EQUAL(SEND_ENCAPSULATED_COMMAND, bRequest);
TEST_ASSERT_EQUAL(sizeof(rndis_msg_initialize_t), wLength);
TEST_ASSERT_EQUAL_HEX8_ARRAY(&msg_init, data, wLength);
break;
case 0*2+1: // initialize complete
TEST_ASSERT_EQUAL(bmrequest_get, bmRequestType);
TEST_ASSERT_EQUAL(GET_ENCAPSULATED_RESPONSE, bRequest);
TEST_ASSERT( wLength >= 0x0400 ); // Microsoft Specs
memcpy(data, &msg_init_cmplt, sizeof(rndis_msg_initialize_cmplt_t));
break;
// query for RNDIS_OID_802_3_PERMANENT_ADDRESS
case 1*2+0:
TEST_ASSERT_EQUAL(bmrequest_send, bmRequestType);
TEST_ASSERT_EQUAL(SEND_ENCAPSULATED_COMMAND, bRequest);
TEST_ASSERT_EQUAL(sizeof(rndis_msg_query_t) + 6, wLength); // 6 bytes for MAC address
TEST_ASSERT_EQUAL_HEX8_ARRAY(&msg_query_permanent_addr, data, wLength);
break;
case 1*2+1: // query complete for RNDIS_OID_802_3_PERMANENT_ADDRESS
TEST_ASSERT_EQUAL(bmrequest_get, bmRequestType);
TEST_ASSERT_EQUAL(GET_ENCAPSULATED_RESPONSE, bRequest);
TEST_ASSERT( wLength >= 0x0400 ); // Microsoft Specs
memcpy(data, &msg_query_permanent_addr_cmplt, sizeof(rndis_msg_query_cmplt_t) + 6);
break;
// set RNDIS_OID_GEN_CURRENT_PACKET_FILTER to DIRECTED | MULTICAST | BROADCAST
case 2*2+0:
TEST_ASSERT_EQUAL(bmrequest_send, bmRequestType);
TEST_ASSERT_EQUAL(SEND_ENCAPSULATED_COMMAND, bRequest);
TEST_ASSERT_EQUAL(sizeof(rndis_msg_set_t)+4, wLength);
TEST_ASSERT_EQUAL_HEX8_ARRAY(&msg_set_packet_filter, data, wLength);
break;
case 2*2+1: // query complete for RNDIS_OID_802_3_PERMANENT_ADDRESS
TEST_ASSERT_EQUAL(bmrequest_get, bmRequestType);
TEST_ASSERT_EQUAL(GET_ENCAPSULATED_RESPONSE, bRequest);
TEST_ASSERT( wLength >= 0x0400 ); // Microsoft Specs
memcpy(data, &msg_set_packet_filter_cmplt, sizeof(rndis_msg_set_cmplt_t) );
break;
default:
return TUSB_ERROR_OSAL_TIMEOUT;
}
return TUSB_ERROR_NONE;
}
void test_rndis_initialization_sequence_ok(void)
{
usbh_control_xfer_subtask_StubWithCallback(stub_control_xfer);
hcd_pipe_xfer_StubWithCallback(stub_pipe_notification_xfer);
osal_semaphore_wait_StubWithCallback(stub_sem_wait_success);
osal_semaphore_post_ExpectAndReturn(p_rndis->sem_notification_hdl, TUSB_ERROR_NONE);
osal_semaphore_post_ExpectAndReturn(p_rndis->sem_notification_hdl, TUSB_ERROR_NONE);
osal_semaphore_post_ExpectAndReturn(p_rndis->sem_notification_hdl, TUSB_ERROR_NONE);
tusbh_cdc_rndis_mounted_cb_Expect(dev_addr);
//------------- Code Under Test -------------//
TEST_ASSERT_STATUS( cdch_open_subtask(dev_addr, p_comm_interface, &length) );
TEST_ASSERT(p_cdc->is_rndis);
TEST_ASSERT_EQUAL(msg_init_cmplt.max_xfer_size, p_rndis->max_xfer_size);
TEST_ASSERT_EQUAL_HEX8_ARRAY("CAFEBB", p_rndis->mac_address, 6);
}
#endif

View File

@ -1,165 +0,0 @@
/*
* The MIT License (MIT)
*
* Copyright (c) 2019 Ha Thach (tinyusb.org)
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
* This file is part of the TinyUSB stack.
*/
#include <stdlib.h>
#include "unity.h"
#include "type_helper.h"
#include "tusb_option.h"
#include "tusb_errors.h"
#include "binary.h"
#include "hal.h"
#include "hcd.h"
#include "ehci.h"
#include "ehci_controller_fake.h"
#include "mock_osal.h"
#include "mock_usbh_hcd.h"
usbh_device_t _usbh_devices[CFG_TUSB_HOST_DEVICE_MAX+1];
static uint8_t hostid;
//--------------------------------------------------------------------+
// Setup/Teardown + helper declare
//--------------------------------------------------------------------+
void setUp(void)
{
ehci_controller_init();
TEST_ASSERT_STATUS( hcd_init() );
hostid = RANDOM(CONTROLLER_HOST_NUMBER) + TEST_CONTROLLER_HOST_START_INDEX;
}
void tearDown(void)
{
}
//--------------------------------------------------------------------+
// Initialization
//--------------------------------------------------------------------+
void test_hcd_init_data(void)
{
//------------- check memory data -------------//
TEST_ASSERT_MEM_ZERO(&ehci_data.device, sizeof(ehci_data.device));
TEST_ASSERT_MEM_ZERO(ehci_data.addr0_qtd, sizeof(ehci_qtd_t)*3);
}
void test_hcd_init_usbint(void)
{
ehci_registers_t* const regs = get_operational_register(hostid);
//------------- USB INT Enable-------------//
TEST_ASSERT(regs->usb_int_enable_bit.usb_error);
TEST_ASSERT(regs->usb_int_enable_bit.port_change_detect);
TEST_ASSERT(regs->usb_int_enable_bit.async_advance);
TEST_ASSERT_FALSE(regs->usb_int_enable_bit.framelist_rollover);
TEST_ASSERT_FALSE(regs->usb_int_enable_bit.pci_host_system_error);
TEST_ASSERT_FALSE(regs->usb_int_enable_bit.nxp_int_sof);
TEST_ASSERT_FALSE(regs->usb_int_enable_bit.usb);
TEST_ASSERT_TRUE(regs->usb_int_enable_bit.nxp_int_async);
TEST_ASSERT_TRUE(regs->usb_int_enable_bit.nxp_int_period);
// TODO to be portable use usbint instead of nxp int async/period
}
void test_hcd_init_async_list(void)
{
ehci_registers_t * const regs = get_operational_register(hostid);
ehci_qhd_t * const async_head = get_async_head(hostid);
TEST_ASSERT_EQUAL_HEX(async_head, regs->async_list_base);
TEST_ASSERT_EQUAL_HEX(async_head, tu_align32( (uint32_t) async_head) );
TEST_ASSERT_EQUAL(EHCI_QUEUE_ELEMENT_QHD, async_head->next.type);
TEST_ASSERT_FALSE(async_head->next.terminate);
TEST_ASSERT(async_head->head_list_flag);
TEST_ASSERT(async_head->qtd_overlay.halted);
}
void check_qhd_endpoint_link(ehci_link_t *p_prev, ehci_qhd_t *p_qhd)
{
//------------- period list check -------------//
TEST_ASSERT_EQUAL_HEX((uint32_t) p_qhd, tu_align32(p_prev->address));
TEST_ASSERT_FALSE(p_prev->terminate);
TEST_ASSERT_EQUAL(EHCI_QUEUE_ELEMENT_QHD, p_prev->type);
}
void test_hcd_init_period_list(void)
{
ehci_registers_t* const regs = get_operational_register(hostid);
ehci_qhd_t * const period_head_arr = get_period_head(hostid, 1);
ehci_link_t * const framelist = get_period_frame_list(hostid);
TEST_ASSERT_EQUAL_HEX( (uint32_t) framelist, regs->periodic_list_base);
check_qhd_endpoint_link( framelist+0, period_head_arr+1);
check_qhd_endpoint_link( framelist+2, period_head_arr+1);
check_qhd_endpoint_link( framelist+4, period_head_arr+1);
check_qhd_endpoint_link( framelist+6, period_head_arr+1);
check_qhd_endpoint_link( framelist+1, period_head_arr+2);
check_qhd_endpoint_link( framelist+5, period_head_arr+2);
check_qhd_endpoint_link( framelist+3, period_head_arr+3);
check_qhd_endpoint_link( framelist+7, period_head_arr);
check_qhd_endpoint_link( (ehci_link_t*) (period_head_arr+1), period_head_arr);
check_qhd_endpoint_link( (ehci_link_t*) (period_head_arr+2), period_head_arr);
check_qhd_endpoint_link( (ehci_link_t*) (period_head_arr+3), period_head_arr);
for(uint32_t i=0; i<4; i++)
{
TEST_ASSERT(period_head_arr[i].interrupt_smask);
TEST_ASSERT(period_head_arr[i].qtd_overlay.halted);
}
TEST_ASSERT_TRUE(period_head_arr[0].next.terminate);
}
void test_hcd_init_tt_control(void)
{
ehci_registers_t* const regs = get_operational_register(hostid);
}
void test_hcd_init_usbcmd(void)
{
ehci_registers_t* const regs = get_operational_register(hostid);
TEST_ASSERT(regs->usb_cmd_bit.async_enable);
TEST_ASSERT(regs->usb_cmd_bit.periodic_enable);
//------------- Framelist size (NXP specific) -------------//
TEST_ASSERT_BITS(TU_BIN8(11), EHCI_CFG_FRAMELIST_SIZE_BITS, regs->usb_cmd_bit.framelist_size);
TEST_ASSERT_EQUAL(EHCI_CFG_FRAMELIST_SIZE_BITS >> 2, regs->usb_cmd_bit.nxp_framelist_size_msb);
}
void test_hcd_init_portsc(void)
{
TEST_IGNORE_MESSAGE("more advance stuff need manipulate this register");
}

View File

@ -1,92 +0,0 @@
/*
* The MIT License (MIT)
*
* Copyright (c) 2019 Ha Thach (tinyusb.org)
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
* This file is part of the TinyUSB stack.
*/
#include <stdlib.h>
#include "unity.h"
#include "tusb_option.h"
#include "tusb_errors.h"
#include "binary.h"
#include "type_helper.h"
#include "hal.h"
#include "ehci.h"
#include "ehci_controller_fake.h"
#include "mock_osal.h"
#include "mock_usbh_hcd.h"
usbh_device_t _usbh_devices[CFG_TUSB_HOST_DEVICE_MAX+1];
static uint8_t hostid;
static ehci_registers_t * regs;
void setUp(void)
{
ehci_controller_init();
TEST_ASSERT_STATUS( hcd_init());
hostid = RANDOM(CONTROLLER_HOST_NUMBER) + TEST_CONTROLLER_HOST_START_INDEX;
regs = get_operational_register(hostid);
}
void tearDown(void)
{
}
void test_isr_device_connect_highspeed(void)
{
hcd_event_device_attach_Expect(hostid);
//------------- Code Under Test -------------//
ehci_controller_device_plug(hostid, TUSB_SPEED_HIGH);
}
void test_isr_device_connect_fullspeed(void)
{
hcd_event_device_attach_Expect(hostid);
//------------- Code Under Test -------------//
ehci_controller_device_plug(hostid, TUSB_SPEED_FULL);
}
void test_isr_device_connect_slowspeed(void)
{
hcd_event_device_attach_Expect(hostid);
//------------- Code Under Test -------------//
ehci_controller_device_plug(hostid, TUSB_SPEED_LOW);
}
void test_isr_device_disconnect(void)
{
hcd_event_device_remove_Expect(hostid);
//------------- Code Under Test -------------//
ehci_controller_device_unplug(hostid);
// TEST_ASSERT(regs->usb_cmd_bit.advacne_async);
}

View File

@ -1,292 +0,0 @@
/*
* The MIT License (MIT)
*
* Copyright (c) 2019 Ha Thach (tinyusb.org)
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
* This file is part of the TinyUSB stack.
*/
#include <stdlib.h>
#include "unity.h"
#include "tusb_option.h"
#include "tusb_errors.h"
#include "binary.h"
#include "type_helper.h"
#include "hal.h"
#include "hcd.h"
#include "ehci.h"
#include "ehci_controller_fake.h"
#include "mock_osal.h"
#include "mock_usbh_hcd.h"
usbh_device_t _usbh_devices[CFG_TUSB_HOST_DEVICE_MAX+1];
//--------------------------------------------------------------------+
// Setup/Teardown + helper declare
//--------------------------------------------------------------------+
void setUp(void)
{
}
void tearDown(void)
{
}
//--------------------------------------------------------------------+
//
//--------------------------------------------------------------------+
void test_struct_alignment(void)
{
TEST_ASSERT_EQUAL( 32, __alignof__(ehci_qhd_t) );
// TEST_ASSERT_EQUAL( 32, __alignof__(ehci_qtd_t) ); ehci_qtd_t is used to declare overlay variable in qhd --> cannot declare with TU_ATTR_ALIGNED(32)
TEST_ASSERT_EQUAL( 32, __alignof__(ehci_itd_t) );
TEST_ASSERT_EQUAL( 32, __alignof__(ehci_sitd_t) );
}
void test_struct_size(void)
{
if (4 < sizeof(void*)) // running tests in x64 environment
{
TEST_ASSERT_EQUAL( 64 - 8, offsetof(ehci_qhd_t, p_qtd_list_head) ); // 64 - 2x 32-bit pointer qtds
}else
{
TEST_ASSERT_EQUAL( 64, sizeof(ehci_qhd_t) );
}
TEST_ASSERT_EQUAL( 32, sizeof(ehci_qtd_t) );
TEST_ASSERT_EQUAL( 64, sizeof(ehci_itd_t) );
TEST_ASSERT_EQUAL( 32, sizeof(ehci_sitd_t) );
TEST_ASSERT_EQUAL( 4, sizeof(ehci_link_t) );
}
//--------------------------------------------------------------------+
// EHCI Data Structure
//--------------------------------------------------------------------+
void test_qtd_structure(void)
{
TEST_ASSERT_EQUAL( 0, offsetof(ehci_qtd_t, next));
TEST_ASSERT_EQUAL( 4, offsetof(ehci_qtd_t, alternate));
TEST_ASSERT_EQUAL( 5, BITFIELD_OFFSET_OF_UINT32(ehci_qtd_t, 1, used));
//------------- Word 2 -------------//
TEST_ASSERT_EQUAL( 0, BITFIELD_OFFSET_OF_UINT32(ehci_qtd_t, 2, pingstate_err) );
TEST_ASSERT_EQUAL( 1, BITFIELD_OFFSET_OF_UINT32(ehci_qtd_t, 2, non_hs_split_state) );
TEST_ASSERT_EQUAL( 2, BITFIELD_OFFSET_OF_UINT32(ehci_qtd_t, 2, non_hs_period_missed_uframe));
TEST_ASSERT_EQUAL( 3, BITFIELD_OFFSET_OF_UINT32(ehci_qtd_t, 2, xact_err) );
TEST_ASSERT_EQUAL( 4, BITFIELD_OFFSET_OF_UINT32(ehci_qtd_t, 2, babble_err) );
TEST_ASSERT_EQUAL( 5, BITFIELD_OFFSET_OF_UINT32(ehci_qtd_t, 2, buffer_err) );
TEST_ASSERT_EQUAL( 6, BITFIELD_OFFSET_OF_UINT32(ehci_qtd_t, 2, halted) );
TEST_ASSERT_EQUAL( 7, BITFIELD_OFFSET_OF_UINT32(ehci_qtd_t, 2, active) );
TEST_ASSERT_EQUAL( 8, BITFIELD_OFFSET_OF_UINT32(ehci_qtd_t, 2, pid) );
TEST_ASSERT_EQUAL( 10, BITFIELD_OFFSET_OF_UINT32(ehci_qtd_t, 2, cerr) );
TEST_ASSERT_EQUAL( 12, BITFIELD_OFFSET_OF_UINT32(ehci_qtd_t, 2, current_page) );
TEST_ASSERT_EQUAL( 15, BITFIELD_OFFSET_OF_UINT32(ehci_qtd_t, 2, int_on_complete) );
TEST_ASSERT_EQUAL( 16, BITFIELD_OFFSET_OF_UINT32(ehci_qtd_t, 2, total_bytes) );
TEST_ASSERT_EQUAL( 31, BITFIELD_OFFSET_OF_UINT32(ehci_qtd_t, 2, data_toggle) );
TEST_ASSERT_EQUAL( 12, offsetof(ehci_qtd_t, buffer));
}
void test_qhd_structure(void)
{
TEST_ASSERT_EQUAL( 0, offsetof(ehci_qhd_t, next));
//------------- Word 1 -------------//
TEST_ASSERT_EQUAL( 0, BITFIELD_OFFSET_OF_UINT32(ehci_qhd_t, 1, device_address) );
TEST_ASSERT_EQUAL( 7, BITFIELD_OFFSET_OF_UINT32(ehci_qhd_t, 1, non_hs_period_inactive_next_xact) );
TEST_ASSERT_EQUAL( 8, BITFIELD_OFFSET_OF_UINT32(ehci_qhd_t, 1, endpoint_number) );
TEST_ASSERT_EQUAL( 12, BITFIELD_OFFSET_OF_UINT32(ehci_qhd_t, 1, endpoint_speed) );
TEST_ASSERT_EQUAL( 14, BITFIELD_OFFSET_OF_UINT32(ehci_qhd_t, 1, data_toggle_control) );
TEST_ASSERT_EQUAL( 15, BITFIELD_OFFSET_OF_UINT32(ehci_qhd_t, 1, head_list_flag) );
TEST_ASSERT_EQUAL( 16, BITFIELD_OFFSET_OF_UINT32(ehci_qhd_t, 1, max_package_size) );
TEST_ASSERT_EQUAL( 27, BITFIELD_OFFSET_OF_UINT32(ehci_qhd_t, 1, non_hs_control_endpoint) );
TEST_ASSERT_EQUAL( 28, BITFIELD_OFFSET_OF_UINT32(ehci_qhd_t, 1, nak_count_reload) );
//------------- Word 2 -------------//
TEST_ASSERT_EQUAL( 0, BITFIELD_OFFSET_OF_UINT32(ehci_qhd_t, 2, interrupt_smask) );
TEST_ASSERT_EQUAL( 8, BITFIELD_OFFSET_OF_UINT32(ehci_qhd_t, 2, non_hs_interrupt_cmask) );
TEST_ASSERT_EQUAL( 16, BITFIELD_OFFSET_OF_UINT32(ehci_qhd_t, 2, hub_address) );
TEST_ASSERT_EQUAL( 23, BITFIELD_OFFSET_OF_UINT32(ehci_qhd_t, 2, hub_port) );
TEST_ASSERT_EQUAL( 30, BITFIELD_OFFSET_OF_UINT32(ehci_qhd_t, 2, mult) );
TEST_ASSERT_EQUAL( 3*4, offsetof(ehci_qhd_t, qtd_addr));
TEST_ASSERT_EQUAL( 4*4, offsetof(ehci_qhd_t, qtd_overlay));
}
void test_itd_structure(void)
{
TEST_ASSERT_EQUAL( 0, offsetof(ehci_itd_t, next));
// Each Transaction Word
TEST_ASSERT_EQUAL( 0 , BITFIELD_OFFSET_OF_MEMBER(ehci_itd_t, xact[0], offset) );
TEST_ASSERT_EQUAL( 12 , BITFIELD_OFFSET_OF_MEMBER(ehci_itd_t, xact[0], page_select) );
TEST_ASSERT_EQUAL( 15 , BITFIELD_OFFSET_OF_MEMBER(ehci_itd_t, xact[0], int_on_complete) );
TEST_ASSERT_EQUAL( 16 , BITFIELD_OFFSET_OF_MEMBER(ehci_itd_t, xact[0], length) );
TEST_ASSERT_EQUAL( 28 , BITFIELD_OFFSET_OF_MEMBER(ehci_itd_t, xact[0], error) );
TEST_ASSERT_EQUAL( 29 , BITFIELD_OFFSET_OF_MEMBER(ehci_itd_t, xact[0], babble_err) );
TEST_ASSERT_EQUAL( 30 , BITFIELD_OFFSET_OF_MEMBER(ehci_itd_t, xact[0], buffer_err) );
TEST_ASSERT_EQUAL( 31 , BITFIELD_OFFSET_OF_MEMBER(ehci_itd_t, xact[0], active) );
TEST_ASSERT_EQUAL( 9*4, offsetof(ehci_itd_t, BufferPointer));
}
void test_sitd_structure(void)
{
TEST_ASSERT_EQUAL( 0, offsetof(ehci_sitd_t, next));
//------------- Word 1 -------------//
TEST_ASSERT_EQUAL( 0, BITFIELD_OFFSET_OF_UINT32(ehci_sitd_t, 1, device_address) );
TEST_ASSERT_EQUAL( 8, BITFIELD_OFFSET_OF_UINT32(ehci_sitd_t, 1, endpoint_number) );
TEST_ASSERT_EQUAL( 16, BITFIELD_OFFSET_OF_UINT32(ehci_sitd_t, 1, hub_address) );
TEST_ASSERT_EQUAL( 24, BITFIELD_OFFSET_OF_UINT32(ehci_sitd_t, 1, port_number) );
TEST_ASSERT_EQUAL( 31, BITFIELD_OFFSET_OF_UINT32(ehci_sitd_t, 1, direction) );
//------------- Word 2 -------------//
TEST_ASSERT_EQUAL( 4*2, offsetof(ehci_sitd_t, interrupt_smask));
TEST_ASSERT_EQUAL( 4*2+1, offsetof(ehci_sitd_t, non_hs_interrupt_cmask));
//------------- Word 3 -------------//
TEST_ASSERT_EQUAL( 1, BITFIELD_OFFSET_OF_UINT32(ehci_sitd_t, 3, split_state) );
TEST_ASSERT_EQUAL( 2, BITFIELD_OFFSET_OF_UINT32(ehci_sitd_t, 3, missed_uframe));
TEST_ASSERT_EQUAL( 3, BITFIELD_OFFSET_OF_UINT32(ehci_sitd_t, 3, xact_err) );
TEST_ASSERT_EQUAL( 4, BITFIELD_OFFSET_OF_UINT32(ehci_sitd_t, 3, babble_err) );
TEST_ASSERT_EQUAL( 5, BITFIELD_OFFSET_OF_UINT32(ehci_sitd_t, 3, buffer_err) );
TEST_ASSERT_EQUAL( 6, BITFIELD_OFFSET_OF_UINT32(ehci_sitd_t, 3, error) );
TEST_ASSERT_EQUAL( 7, BITFIELD_OFFSET_OF_UINT32(ehci_sitd_t, 3, active) );
TEST_ASSERT_EQUAL( 8, BITFIELD_OFFSET_OF_UINT32(ehci_sitd_t, 3, cmask_progress) );
TEST_ASSERT_EQUAL( 16, BITFIELD_OFFSET_OF_UINT32(ehci_sitd_t, 3, total_bytes) );
TEST_ASSERT_EQUAL( 30, BITFIELD_OFFSET_OF_UINT32(ehci_sitd_t, 3, page_select) );
TEST_ASSERT_EQUAL( 31, BITFIELD_OFFSET_OF_UINT32(ehci_sitd_t, 3, int_on_complete) );
//------------- Word 4 -------------//
TEST_ASSERT_EQUAL( 4*4, offsetof(ehci_sitd_t, buffer));
TEST_ASSERT_EQUAL( 4*6, offsetof(ehci_sitd_t, back));
}
//--------------------------------------------------------------------+
// EHCI Register Interface
//--------------------------------------------------------------------+
void test_register_offset(void)
{
TEST_ASSERT_EQUAL( 0x00, offsetof(ehci_registers_t, usb_cmd));
TEST_ASSERT_EQUAL( 0x04, offsetof(ehci_registers_t, usb_sts));
TEST_ASSERT_EQUAL( 0x08, offsetof(ehci_registers_t, usb_int_enable));
TEST_ASSERT_EQUAL( 0x0C, offsetof(ehci_registers_t, frame_index));
TEST_ASSERT_EQUAL( 0x10, offsetof(ehci_registers_t, ctrl_ds_seg));
TEST_ASSERT_EQUAL( 0x14, offsetof(ehci_registers_t, periodic_list_base));
TEST_ASSERT_EQUAL( 0x18, offsetof(ehci_registers_t, async_list_base));
TEST_ASSERT_EQUAL( 0x1C, offsetof(ehci_registers_t, tt_control)); // NXP specific
TEST_ASSERT_EQUAL( 0x40, offsetof(ehci_registers_t, config_flag)); // NXP not used
TEST_ASSERT_EQUAL( 0x44, offsetof(ehci_registers_t, portsc));
}
void test_register_usbcmd(void)
{
TEST_ASSERT_EQUAL( 0 , BITFIELD_OFFSET_OF_MEMBER(ehci_registers_t, usb_cmd_bit, run_stop) );
TEST_ASSERT_EQUAL( 1 , BITFIELD_OFFSET_OF_MEMBER(ehci_registers_t, usb_cmd_bit, reset) );
TEST_ASSERT_EQUAL( 2 , BITFIELD_OFFSET_OF_MEMBER(ehci_registers_t, usb_cmd_bit, framelist_size) );
TEST_ASSERT_EQUAL( 4 , BITFIELD_OFFSET_OF_MEMBER(ehci_registers_t, usb_cmd_bit, periodic_enable) );
TEST_ASSERT_EQUAL( 5 , BITFIELD_OFFSET_OF_MEMBER(ehci_registers_t, usb_cmd_bit, async_enable) );
TEST_ASSERT_EQUAL( 6 , BITFIELD_OFFSET_OF_MEMBER(ehci_registers_t, usb_cmd_bit, advance_async) );
TEST_ASSERT_EQUAL( 7 , BITFIELD_OFFSET_OF_MEMBER(ehci_registers_t, usb_cmd_bit, light_reset) );
TEST_ASSERT_EQUAL( 8 , BITFIELD_OFFSET_OF_MEMBER(ehci_registers_t, usb_cmd_bit, async_park) );
TEST_ASSERT_EQUAL( 11 , BITFIELD_OFFSET_OF_MEMBER(ehci_registers_t, usb_cmd_bit, async_park_enable) );
TEST_ASSERT_EQUAL( 15 , BITFIELD_OFFSET_OF_MEMBER(ehci_registers_t, usb_cmd_bit, nxp_framelist_size_msb) );
TEST_ASSERT_EQUAL( 16 , BITFIELD_OFFSET_OF_MEMBER(ehci_registers_t, usb_cmd_bit, int_threshold) );
}
void test_register_usbsts(void)
{
TEST_ASSERT_EQUAL( 0 , BITFIELD_OFFSET_OF_MEMBER(ehci_registers_t, usb_sts_bit, usb));
TEST_ASSERT_EQUAL( 1 , BITFIELD_OFFSET_OF_MEMBER(ehci_registers_t, usb_sts_bit, usb_error));
TEST_ASSERT_EQUAL( 2 , BITFIELD_OFFSET_OF_MEMBER(ehci_registers_t, usb_sts_bit, port_change_detect));
TEST_ASSERT_EQUAL( 3 , BITFIELD_OFFSET_OF_MEMBER(ehci_registers_t, usb_sts_bit, framelist_rollover));
TEST_ASSERT_EQUAL( 4 , BITFIELD_OFFSET_OF_MEMBER(ehci_registers_t, usb_sts_bit, pci_host_system_error));
TEST_ASSERT_EQUAL( 5 , BITFIELD_OFFSET_OF_MEMBER(ehci_registers_t, usb_sts_bit, async_advance));
TEST_ASSERT_EQUAL( 7 , BITFIELD_OFFSET_OF_MEMBER(ehci_registers_t, usb_sts_bit, nxp_int_sof));
TEST_ASSERT_EQUAL( 12 , BITFIELD_OFFSET_OF_MEMBER(ehci_registers_t, usb_sts_bit, hc_halted));
TEST_ASSERT_EQUAL( 13 , BITFIELD_OFFSET_OF_MEMBER(ehci_registers_t, usb_sts_bit, reclamation));
TEST_ASSERT_EQUAL( 14 , BITFIELD_OFFSET_OF_MEMBER(ehci_registers_t, usb_sts_bit, period_schedule_status));
TEST_ASSERT_EQUAL( 15 , BITFIELD_OFFSET_OF_MEMBER(ehci_registers_t, usb_sts_bit, async_schedule_status));
TEST_ASSERT_EQUAL( 18 , BITFIELD_OFFSET_OF_MEMBER(ehci_registers_t, usb_sts_bit, nxp_int_async));
TEST_ASSERT_EQUAL( 19 , BITFIELD_OFFSET_OF_MEMBER(ehci_registers_t, usb_sts_bit, nxp_int_period));
}
void test_register_usbint(void)
{
TEST_ASSERT_EQUAL( 0 , BITFIELD_OFFSET_OF_MEMBER(ehci_registers_t, usb_int_enable_bit, usb));
TEST_ASSERT_EQUAL( 1 , BITFIELD_OFFSET_OF_MEMBER(ehci_registers_t, usb_int_enable_bit, usb_error));
TEST_ASSERT_EQUAL( 2 , BITFIELD_OFFSET_OF_MEMBER(ehci_registers_t, usb_int_enable_bit, port_change_detect));
TEST_ASSERT_EQUAL( 3 , BITFIELD_OFFSET_OF_MEMBER(ehci_registers_t, usb_int_enable_bit, framelist_rollover));
TEST_ASSERT_EQUAL( 4 , BITFIELD_OFFSET_OF_MEMBER(ehci_registers_t, usb_int_enable_bit, pci_host_system_error));
TEST_ASSERT_EQUAL( 5 , BITFIELD_OFFSET_OF_MEMBER(ehci_registers_t, usb_int_enable_bit, async_advance));
TEST_ASSERT_EQUAL( 7 , BITFIELD_OFFSET_OF_MEMBER(ehci_registers_t, usb_int_enable_bit, nxp_int_sof));
TEST_ASSERT_EQUAL( 18 , BITFIELD_OFFSET_OF_MEMBER(ehci_registers_t, usb_int_enable_bit, nxp_int_async));
TEST_ASSERT_EQUAL( 19 , BITFIELD_OFFSET_OF_MEMBER(ehci_registers_t, usb_int_enable_bit, nxp_int_period));
}
void test_register_portsc(void)
{
TEST_ASSERT_EQUAL( 0 , BITFIELD_OFFSET_OF_MEMBER(ehci_registers_t, portsc_bit, current_connect_status));
TEST_ASSERT_EQUAL( 1 , BITFIELD_OFFSET_OF_MEMBER(ehci_registers_t, portsc_bit, connect_status_change));
TEST_ASSERT_EQUAL( 2 , BITFIELD_OFFSET_OF_MEMBER(ehci_registers_t, portsc_bit, port_enable));
TEST_ASSERT_EQUAL( 3 , BITFIELD_OFFSET_OF_MEMBER(ehci_registers_t, portsc_bit, port_enable_change));
TEST_ASSERT_EQUAL( 4 , BITFIELD_OFFSET_OF_MEMBER(ehci_registers_t, portsc_bit, over_current_active));
TEST_ASSERT_EQUAL( 5 , BITFIELD_OFFSET_OF_MEMBER(ehci_registers_t, portsc_bit, over_current_change));
TEST_ASSERT_EQUAL( 6 , BITFIELD_OFFSET_OF_MEMBER(ehci_registers_t, portsc_bit, force_port_resume));
TEST_ASSERT_EQUAL( 7 , BITFIELD_OFFSET_OF_MEMBER(ehci_registers_t, portsc_bit, suspend));
TEST_ASSERT_EQUAL( 8 , BITFIELD_OFFSET_OF_MEMBER(ehci_registers_t, portsc_bit, port_reset));
TEST_ASSERT_EQUAL( 9 , BITFIELD_OFFSET_OF_MEMBER(ehci_registers_t, portsc_bit, nxp_highspeed_status));
TEST_ASSERT_EQUAL( 10 , BITFIELD_OFFSET_OF_MEMBER(ehci_registers_t, portsc_bit, line_status));
TEST_ASSERT_EQUAL( 12 , BITFIELD_OFFSET_OF_MEMBER(ehci_registers_t, portsc_bit, port_power));
TEST_ASSERT_EQUAL( 13 , BITFIELD_OFFSET_OF_MEMBER(ehci_registers_t, portsc_bit, port_owner));
TEST_ASSERT_EQUAL( 14 , BITFIELD_OFFSET_OF_MEMBER(ehci_registers_t, portsc_bit, port_indicator_control));
TEST_ASSERT_EQUAL( 16 , BITFIELD_OFFSET_OF_MEMBER(ehci_registers_t, portsc_bit, port_test_control));
TEST_ASSERT_EQUAL( 20 , BITFIELD_OFFSET_OF_MEMBER(ehci_registers_t, portsc_bit, wake_on_connect_enable));
TEST_ASSERT_EQUAL( 21 , BITFIELD_OFFSET_OF_MEMBER(ehci_registers_t, portsc_bit, wake_on_disconnect_enable));
TEST_ASSERT_EQUAL( 22 , BITFIELD_OFFSET_OF_MEMBER(ehci_registers_t, portsc_bit, wake_on_over_current_enable));
TEST_ASSERT_EQUAL( 23 , BITFIELD_OFFSET_OF_MEMBER(ehci_registers_t, portsc_bit, nxp_phy_clock_disable));
TEST_ASSERT_EQUAL( 24 , BITFIELD_OFFSET_OF_MEMBER(ehci_registers_t, portsc_bit, nxp_port_force_fullspeed));
TEST_ASSERT_EQUAL( 26 , BITFIELD_OFFSET_OF_MEMBER(ehci_registers_t, portsc_bit, nxp_port_speed));
}
//--------------------------------------------------------------------+
// EHCI Data Organization
//--------------------------------------------------------------------+
void test_ehci_data(void)
{
for(uint32_t i=0; i<CONTROLLER_HOST_NUMBER; i++)
{
uint8_t hostid = i+TEST_CONTROLLER_HOST_START_INDEX;
TEST_ASSERT_BITS_LOW(4096-1, (uint32_t)get_period_frame_list(hostid) );
}
// TODO more tests on ehci_data
}

View File

@ -1,198 +0,0 @@
/*
* The MIT License (MIT)
*
* Copyright (c) 2019 Ha Thach (tinyusb.org)
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
* This file is part of the TinyUSB stack.
*/
#include <stdlib.h>
#include "unity.h"
#include "tusb_option.h"
#include "tusb_errors.h"
#include "binary.h"
#include "type_helper.h"
#include "hal.h"
#include "mock_osal.h"
#include "mock_hid_host.h"
#include "mock_msc_host.h"
#include "mock_cdc_host.h"
#include "hcd.h"
#include "usbh_hcd.h"
#include "hub.h"
#include "usbh.h"
#include "ehci.h"
#include "ehci_controller_fake.h"
#include "host_helper.h"
static uint8_t const control_max_packet_size = 64;
static uint8_t hub_addr;
static uint8_t hub_port;
static uint8_t dev_addr;
static uint8_t hostid;
static ehci_registers_t * regs;
static ehci_qhd_t *async_head;
static ehci_qhd_t *period_head_arr;
extern osal_queue_handle_t enum_queue_hdl;
void setUp(void)
{
hub_addr = hub_port = 0;
dev_addr = 1;
hostid = RANDOM(CONTROLLER_HOST_NUMBER) + TEST_CONTROLLER_HOST_START_INDEX;
ehci_controller_init();
helper_usbh_init_expect();
helper_class_init_expect();
usbh_init();
helper_usbh_device_emulate(dev_addr, hub_addr, hub_port, hostid, TUSB_SPEED_HIGH);
regs = get_operational_register(hostid);
async_head = get_async_head( hostid );
period_head_arr = (ehci_qhd_t*) get_period_head( hostid, 1 );
regs->usb_sts = 0; // hcd_init clear usb_sts by writing 1s
}
void tearDown(void)
{
}
void test_addr0_control_close(void)
{
dev_addr = 0;
helper_usbh_device_emulate(0, hub_addr, hub_port, hostid, TUSB_SPEED_HIGH);
TEST_ASSERT_STATUS( hcd_pipe_control_open(dev_addr, control_max_packet_size) );
TEST_ASSERT( hcd_pipe_control_xfer(dev_addr,
&(tusb_control_request_t) {
.bmRequestType_bit = { .direction = TUSB_DIR_HOST_TO_DEV, .type = TUSB_REQ_TYPE_STANDARD, .recipient = TUSB_REQ_RECIPIENT_DEVICE },
.bRequest = TUSB_REQ_SET_ADDRESS,
.wValue = 3 },
NULL) ) ;
ehci_qhd_t *p_qhd = async_head;
TEST_ASSERT_STATUS( hcd_pipe_control_close(dev_addr) );
//------------- Code Under Test -------------//
regs->usb_sts_bit.port_change_detect = 0; // clear port change detect
regs->usb_sts_bit.async_advance = 1;
hcd_isr(hostid); // async advance
TEST_ASSERT( p_qhd->qtd_overlay.halted );
TEST_ASSERT_FALSE( p_qhd->is_removing );
TEST_ASSERT_NULL( p_qhd->p_qtd_list_head );
TEST_ASSERT_NULL( p_qhd->p_qtd_list_tail );
}
#if 0 // TODO TEST enable this
void test_isr_disconnect_then_async_advance_control_pipe(void)
{
TEST_ASSERT_STATUS( hcd_pipe_control_open(dev_addr, control_max_packet_size) );
TEST_ASSERT( hcd_pipe_control_xfer(dev_addr,
&(tusb_control_request_t) {
.bmRequestType_bit = { .direction = TUSB_DIR_HOST_TO_DEV, .type = TUSB_REQ_TYPE_STANDARD, .recipient = TUSB_REQ_RECIPIENT_DEVICE },
.bRequest = TUSB_REQ_SET_ADDRESS,
.wValue = 3 },
NULL) );
ehci_qhd_t *p_qhd = get_control_qhd(dev_addr);
ehci_qtd_t *p_qtd_head = p_qhd->p_qtd_list_head;
ehci_qtd_t *p_qtd_tail = p_qhd->p_qtd_list_tail;
usbh_enumerate_t root_enum_entry = { .core_id = hostid, .hub_addr = 0, .hub_port = 0 };
osal_queue_send_ExpectWithArrayAndReturn(enum_queue_hdl, (uint8_t*)&root_enum_entry, sizeof(usbh_enumerate_t), TUSB_ERROR_NONE);
ehci_controller_device_unplug(hostid);
//------------- Code Under Test -------------//
usbh_enumeration_task(NULL); // carry out unplug task
regs->usb_sts_bit.port_change_detect = 0; // clear port change detect
regs->usb_sts_bit.async_advance = 1;
hcd_isr(hostid); // async advance
TEST_ASSERT_FALSE(p_qhd->used);
TEST_ASSERT_FALSE(p_qhd->is_removing);
// TEST_ASSERT_NULL(p_qhd->p_qtd_list_head);
// TEST_ASSERT_NULL(p_qhd->p_qtd_list_tail);
}
#endif
void test_bulk_pipe_close(void)
{
tusb_desc_endpoint_t const desc_ept_bulk_in =
{
.bLength = sizeof(tusb_desc_endpoint_t),
.bDescriptorType = TUSB_DESC_TYPE_ENDPOINT,
.bEndpointAddress = 0x81,
.bmAttributes = { .xfer = TUSB_XFER_BULK },
.wMaxPacketSize = 512,
.bInterval = 0
};
uint8_t xfer_data[100];
pipe_handle_t pipe_hdl = hcd_edpt_open(dev_addr, &desc_ept_bulk_in, TUSB_CLASS_MSC);
TEST_ASSERT_STATUS( hcd_pipe_xfer(pipe_hdl, xfer_data, sizeof(xfer_data), 100) );
TEST_ASSERT_STATUS( hcd_pipe_xfer(pipe_hdl, xfer_data, sizeof(xfer_data), 50) );
ehci_qhd_t *p_qhd = &ehci_data.device[dev_addr-1].qhd[pipe_hdl.index];
ehci_qtd_t *p_qtd_head = p_qhd->p_qtd_list_head;
ehci_qtd_t *p_qtd_tail = p_qhd->p_qtd_list_tail;
TEST_ASSERT_STATUS( hcd_pipe_close(pipe_hdl) );
//------------- Code Under Test -------------//
regs->usb_sts_bit.async_advance = 1;
get_control_qhd(dev_addr)->is_removing = 1; // mimic unmount
hcd_isr(hostid); // async advance
TEST_ASSERT_FALSE(p_qhd->used);
TEST_ASSERT_FALSE(p_qhd->is_removing);
// TEST_ASSERT_NULL(p_qhd->p_qtd_list_head);
// TEST_ASSERT_NULL(p_qhd->p_qtd_list_tail);
TEST_ASSERT_FALSE(p_qtd_head->used);
TEST_ASSERT_FALSE(p_qtd_tail->used);
}
#if 0 // TODO TEST enable this
void test_device_unplugged_status(void)
{
usbh_enumerate_t root_enum_entry = { .core_id = hostid, .hub_addr = 0, .hub_port = 0 };
osal_queue_send_ExpectWithArrayAndReturn(enum_queue_hdl, (uint8_t*)&root_enum_entry, sizeof(usbh_enumerate_t), TUSB_ERROR_NONE);
ehci_controller_device_unplug(hostid);
// hcd_isr(hostid);
TEST_ASSERT_EQUAL(TUSB_DEVICE_STATE_REMOVING, usbh_devices[dev_addr].state);
regs->usb_sts_bit.async_advance = 1;
hcd_isr(hostid); // async advance
TEST_ASSERT_EQUAL(TUSB_DEVICE_STATE_UNPLUG, usbh_devices[dev_addr].state);
}
#endif

View File

@ -1,188 +0,0 @@
/*
* The MIT License (MIT)
*
* Copyright (c) 2019 Ha Thach (tinyusb.org)
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
* This file is part of the TinyUSB stack.
*/
#include <stdlib.h>
#include "unity.h"
#include "tusb_option.h"
#include "tusb_errors.h"
#include "binary.h"
#include "type_helper.h"
#include "hal.h"
#include "mock_osal.h"
#include "hcd.h"
#include "mock_usbh_hcd.h"
#include "ehci.h"
#include "ehci_controller_fake.h"
#include "host_helper.h"
usbh_device_t _usbh_devices[CFG_TUSB_HOST_DEVICE_MAX+1];
static uint8_t const hub_addr = 2;
static uint8_t const hub_port = 2;
static uint8_t dev_addr;
static uint8_t hostid;
static ehci_qhd_t *async_head;
//--------------------------------------------------------------------+
// Setup/Teardown + helper declare
//--------------------------------------------------------------------+
void setUp(void)
{
TEST_ASSERT_STATUS( hcd_init() );
dev_addr = 1;
hostid = RANDOM(CONTROLLER_HOST_NUMBER) + TEST_CONTROLLER_HOST_START_INDEX;
tu_memclr(_usbh_devices, sizeof(usbh_device_t)*(CFG_TUSB_HOST_DEVICE_MAX+1));
helper_usbh_device_emulate(dev_addr, hub_addr, hub_port, hostid, TUSB_SPEED_HIGH);
async_head = get_async_head( hostid );
}
void tearDown(void)
{
}
void verify_open_qhd(ehci_qhd_t *p_qhd, uint8_t endpoint_addr, uint16_t max_packet_size)
{
TEST_ASSERT_EQUAL(dev_addr, p_qhd->device_address);
TEST_ASSERT_FALSE(p_qhd->non_hs_period_inactive_next_xact);
TEST_ASSERT_EQUAL(endpoint_addr & 0x0F, p_qhd->endpoint_number);
TEST_ASSERT_EQUAL(_usbh_devices[dev_addr].speed, p_qhd->endpoint_speed);
TEST_ASSERT_EQUAL(max_packet_size, p_qhd->max_package_size);
TEST_ASSERT_EQUAL(0, p_qhd->nak_count_reload); // TDD NAK Reload disable
TEST_ASSERT_EQUAL(hub_addr, p_qhd->hub_address);
TEST_ASSERT_EQUAL(hub_port, p_qhd->hub_port);
TEST_ASSERT_EQUAL(1, p_qhd->mult); // TDD operation model for mult
TEST_ASSERT_FALSE(p_qhd->qtd_overlay.halted);
TEST_ASSERT(p_qhd->qtd_overlay.next.terminate);
TEST_ASSERT(p_qhd->qtd_overlay.alternate.terminate);
//------------- HCD -------------//
TEST_ASSERT(p_qhd->used);
TEST_ASSERT_FALSE(p_qhd->is_removing);
TEST_ASSERT_NULL(p_qhd->p_qtd_list_head);
TEST_ASSERT_NULL(p_qhd->p_qtd_list_tail);
}
//--------------------------------------------------------------------+
// PIPE OPEN
//--------------------------------------------------------------------+
tusb_desc_endpoint_t const desc_ept_bulk_in =
{
.bLength = sizeof(tusb_desc_endpoint_t),
.bDescriptorType = TUSB_DESC_TYPE_ENDPOINT,
.bEndpointAddress = 0x81,
.bmAttributes = { .xfer = TUSB_XFER_BULK },
.wMaxPacketSize = 512,
.bInterval = 0
};
tusb_desc_endpoint_t const desc_ept_bulk_out =
{
.bLength = sizeof(tusb_desc_endpoint_t),
.bDescriptorType = TUSB_DESC_TYPE_ENDPOINT,
.bEndpointAddress = 0x01,
.bmAttributes = { .xfer = TUSB_XFER_BULK },
.wMaxPacketSize = 512,
.bInterval = 0
};
void verify_bulk_open_qhd(ehci_qhd_t *p_qhd, tusb_desc_endpoint_t const * desc_endpoint, uint8_t class_code)
{
verify_open_qhd(p_qhd, desc_endpoint->bEndpointAddress, desc_endpoint->wMaxPacketSize.size);
TEST_ASSERT_FALSE(p_qhd->head_list_flag);
TEST_ASSERT_EQUAL(0, p_qhd->data_toggle_control);
TEST_ASSERT_EQUAL(0, p_qhd->interrupt_smask);
TEST_ASSERT_EQUAL(0, p_qhd->non_hs_interrupt_cmask);
TEST_ASSERT_FALSE(p_qhd->non_hs_control_endpoint);
// TEST_ASSERT_EQUAL(desc_endpoint->bInterval); TDD highspeed bulk/control OUT
TEST_ASSERT_EQUAL(desc_endpoint->bEndpointAddress & 0x80 ? EHCI_PID_IN : EHCI_PID_OUT, p_qhd->pid_non_control);
TEST_ASSERT_EQUAL(class_code, p_qhd->class_code);
//------------- async list check -------------//
TEST_ASSERT_EQUAL_HEX((uint32_t) p_qhd, tu_align32(async_head->next.address));
TEST_ASSERT_FALSE(async_head->next.terminate);
TEST_ASSERT_EQUAL(EHCI_QUEUE_ELEMENT_QHD, async_head->next.type);
}
void test_open_bulk_qhd_data(void)
{
ehci_qhd_t *p_qhd;
pipe_handle_t pipe_hdl;
tusb_desc_endpoint_t const * desc_endpoint = &desc_ept_bulk_in;
//------------- Code Under TEST -------------//
pipe_hdl = hcd_edpt_open(dev_addr, desc_endpoint, TUSB_CLASS_MSC);
TEST_ASSERT_EQUAL(dev_addr, pipe_hdl.dev_addr);
TEST_ASSERT_EQUAL(TUSB_XFER_BULK, pipe_hdl.xfer_type);
p_qhd = &ehci_data.device[ pipe_hdl.dev_addr-1 ].qhd[ pipe_hdl.index ];
verify_bulk_open_qhd(p_qhd, desc_endpoint, TUSB_CLASS_MSC);
//------------- async list check -------------//
TEST_ASSERT_EQUAL_HEX((uint32_t) p_qhd, tu_align32(async_head->next.address));
TEST_ASSERT_FALSE(async_head->next.terminate);
TEST_ASSERT_EQUAL(EHCI_QUEUE_ELEMENT_QHD, async_head->next.type);
}
void test_open_bulk_hs_out_pingstate(void)
{
ehci_qhd_t *p_qhd;
pipe_handle_t pipe_hdl;
//------------- Code Under TEST -------------//
pipe_hdl = hcd_edpt_open(dev_addr, &desc_ept_bulk_out, TUSB_CLASS_MSC);
p_qhd = &ehci_data.device[ pipe_hdl.dev_addr-1 ].qhd[ pipe_hdl.index ];
TEST_ASSERT(p_qhd->qtd_overlay.pingstate_err);
}
//--------------------------------------------------------------------+
// PIPE CLOSE
//--------------------------------------------------------------------+
void test_bulk_close(void)
{
tusb_desc_endpoint_t const * desc_endpoint = &desc_ept_bulk_in;
pipe_handle_t pipe_hdl = hcd_edpt_open(dev_addr, desc_endpoint, TUSB_CLASS_MSC);
ehci_qhd_t *p_qhd = &ehci_data.device[ pipe_hdl.dev_addr-1].qhd[ pipe_hdl.index ];
//------------- Code Under TEST -------------//
hcd_pipe_close(pipe_hdl);
TEST_ASSERT(p_qhd->is_removing);
TEST_ASSERT( tu_align32(async_head->next.address) != (uint32_t) p_qhd );
TEST_ASSERT_EQUAL_HEX( (uint32_t) async_head, tu_align32(p_qhd->next.address) );
TEST_ASSERT_EQUAL(EHCI_QUEUE_ELEMENT_QHD, p_qhd->next.type);
}

View File

@ -1,210 +0,0 @@
/*
* The MIT License (MIT)
*
* Copyright (c) 2019 Ha Thach (tinyusb.org)
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
* This file is part of the TinyUSB stack.
*/
#include <stdlib.h>
#include "unity.h"
#include "tusb_option.h"
#include "tusb_errors.h"
#include "binary.h"
#include "type_helper.h"
#include "hal.h"
#include "mock_osal.h"
#include "hcd.h"
#include "mock_usbh_hcd.h"
#include "ehci.h"
#include "ehci_controller_fake.h"
#include "host_helper.h"
usbh_device_t _usbh_devices[CFG_TUSB_HOST_DEVICE_MAX+1];
static uint8_t hub_addr = 2;
static uint8_t hub_port = 2;
static uint8_t dev_addr;
static uint8_t hostid;
static uint8_t xfer_data [18000]; // 18K to test buffer pointer list
static uint8_t data2[100];
static ehci_qhd_t *async_head;
static ehci_qhd_t *p_qhd_bulk;
static pipe_handle_t pipe_hdl_bulk;
tusb_desc_endpoint_t const desc_ept_bulk_in =
{
.bLength = sizeof(tusb_desc_endpoint_t),
.bDescriptorType = TUSB_DESC_TYPE_ENDPOINT,
.bEndpointAddress = 0x81,
.bmAttributes = { .xfer = TUSB_XFER_BULK },
.wMaxPacketSize = 512,
.bInterval = 0
};
tusb_desc_endpoint_t const desc_ept_bulk_out =
{
.bLength = sizeof(tusb_desc_endpoint_t),
.bDescriptorType = TUSB_DESC_TYPE_ENDPOINT,
.bEndpointAddress = 0x01,
.bmAttributes = { .xfer = TUSB_XFER_BULK },
.wMaxPacketSize = 512,
.bInterval = 0
};
//--------------------------------------------------------------------+
// Setup/Teardown + helper declare
//--------------------------------------------------------------------+
void setUp(void)
{
ehci_controller_init();
tu_memclr(xfer_data, sizeof(xfer_data));
tu_memclr(_usbh_devices, sizeof(usbh_device_t)*(CFG_TUSB_HOST_DEVICE_MAX+1));
TEST_ASSERT_STATUS( hcd_init() );
dev_addr = 1;
hostid = RANDOM(CONTROLLER_HOST_NUMBER) + TEST_CONTROLLER_HOST_START_INDEX;
helper_usbh_device_emulate(dev_addr, hub_addr, hub_port, hostid, TUSB_SPEED_HIGH);
async_head = get_async_head( hostid );
//------------- pipe open -------------//
pipe_hdl_bulk = hcd_edpt_open(dev_addr, &desc_ept_bulk_in, TUSB_CLASS_MSC);
TEST_ASSERT_EQUAL(dev_addr, pipe_hdl_bulk.dev_addr);
TEST_ASSERT_EQUAL(TUSB_XFER_BULK, pipe_hdl_bulk.xfer_type);
p_qhd_bulk = &ehci_data.device[ dev_addr -1].qhd[ pipe_hdl_bulk.index ];
}
void tearDown(void)
{
}
//--------------------------------------------------------------------+
// BULK TRANSFER
//--------------------------------------------------------------------+
void verify_qtd(ehci_qtd_t *p_qtd, uint8_t p_data[], uint16_t length)
{
TEST_ASSERT_TRUE(p_qtd->alternate.terminate); // not used, always invalid
//------------- status -------------//
TEST_ASSERT_FALSE(p_qtd->pingstate_err);
TEST_ASSERT_FALSE(p_qtd->non_hs_split_state);
TEST_ASSERT_FALSE(p_qtd->non_hs_period_missed_uframe);
TEST_ASSERT_FALSE(p_qtd->xact_err);
TEST_ASSERT_FALSE(p_qtd->babble_err);
TEST_ASSERT_FALSE(p_qtd->buffer_err);
TEST_ASSERT_FALSE(p_qtd->halted);
TEST_ASSERT_TRUE(p_qtd->active);
TEST_ASSERT_FALSE(p_qtd->data_toggle);
TEST_ASSERT_EQUAL(3, p_qtd->cerr);
TEST_ASSERT_EQUAL(0, p_qtd->current_page);
TEST_ASSERT_EQUAL(length, p_qtd->total_bytes);
TEST_ASSERT_EQUAL(length, p_qtd->expected_bytes);
TEST_ASSERT_TRUE(p_qtd->used);
TEST_ASSERT_EQUAL_HEX( p_data, p_qtd->buffer[0] );
for(uint8_t i=1; i<5; i++)
{
TEST_ASSERT_EQUAL_HEX( tu_align4k((uint32_t) (p_data+4096*i)), tu_align4k(p_qtd->buffer[i]) );
}
}
void test_bulk_xfer_hs_ping_out(void)
{
_usbh_devices[dev_addr].speed = TUSB_SPEED_HIGH;
pipe_handle_t pipe_hdl = hcd_edpt_open(dev_addr, &desc_ept_bulk_out, TUSB_CLASS_MSC);
ehci_qhd_t *p_qhd = qhd_get_from_pipe_handle(pipe_hdl);
//------------- Code Under Test -------------//
TEST_ASSERT_STATUS( hcd_pipe_xfer(pipe_hdl, xfer_data, sizeof(xfer_data), true) );
ehci_qtd_t* p_qtd = p_qhd->p_qtd_list_head;
}
void test_bulk_xfer(void)
{
//------------- Code Under Test -------------//
TEST_ASSERT_STATUS( hcd_pipe_xfer(pipe_hdl_bulk, xfer_data, sizeof(xfer_data), true) );
ehci_qtd_t* p_qtd = p_qhd_bulk->p_qtd_list_head;
TEST_ASSERT_NOT_NULL(p_qtd);
verify_qtd( p_qtd, xfer_data, sizeof(xfer_data));
TEST_ASSERT_EQUAL_HEX(p_qhd_bulk->qtd_overlay.next.address, p_qtd);
TEST_ASSERT_TRUE(p_qtd->next.terminate);
TEST_ASSERT_EQUAL(EHCI_PID_IN, p_qtd->pid);
TEST_ASSERT_TRUE(p_qtd->int_on_complete);
}
void test_bulk_xfer_double(void)
{
//------------- Code Under Test -------------//
TEST_ASSERT_STATUS( hcd_pipe_xfer(pipe_hdl_bulk, xfer_data, sizeof(xfer_data), false) );
TEST_ASSERT_STATUS( hcd_pipe_xfer(pipe_hdl_bulk, data2, sizeof(data2), true) );
ehci_qtd_t* p_head = p_qhd_bulk->p_qtd_list_head;
ehci_qtd_t* p_tail = p_qhd_bulk->p_qtd_list_tail;
//------------- list head -------------//
TEST_ASSERT_NOT_NULL(p_head);
verify_qtd(p_head, xfer_data, sizeof(xfer_data));
TEST_ASSERT_EQUAL_HEX(p_qhd_bulk->qtd_overlay.next.address, p_head);
TEST_ASSERT_EQUAL(EHCI_PID_IN, p_head->pid);
TEST_ASSERT_FALSE(p_head->next.terminate);
TEST_ASSERT_FALSE(p_head->int_on_complete);
//------------- list tail -------------//
TEST_ASSERT_NOT_NULL(p_tail);
verify_qtd(p_tail, data2, sizeof(data2));
TEST_ASSERT_EQUAL_HEX( tu_align32(p_head->next.address), p_tail);
TEST_ASSERT_EQUAL(EHCI_PID_IN, p_tail->pid);
TEST_ASSERT_TRUE(p_tail->next.terminate);
TEST_ASSERT_TRUE(p_tail->int_on_complete);
}
void test_bulk_xfer_complete_isr(void)
{
TEST_ASSERT_STATUS( hcd_pipe_xfer(pipe_hdl_bulk, xfer_data, sizeof(xfer_data), false) );
TEST_ASSERT_STATUS( hcd_pipe_xfer(pipe_hdl_bulk, data2, sizeof(data2), true) );
ehci_qtd_t* p_head = p_qhd_bulk->p_qtd_list_head;
ehci_qtd_t* p_tail = p_qhd_bulk->p_qtd_list_tail;
hcd_event_xfer_complete_Expect(pipe_hdl_bulk, TUSB_CLASS_MSC, XFER_RESULT_SUCCESS, sizeof(data2)+sizeof(xfer_data));
//------------- Code Under Test -------------//
ehci_controller_run(hostid);
TEST_ASSERT_EQUAL(0, p_qhd_bulk->total_xferred_bytes);
TEST_ASSERT_TRUE(p_qhd_bulk->qtd_overlay.next.terminate);
TEST_ASSERT_FALSE(p_head->used);
TEST_ASSERT_FALSE(p_tail->used);
TEST_ASSERT_NULL(p_qhd_bulk->p_qtd_list_head);
TEST_ASSERT_NULL(p_qhd_bulk->p_qtd_list_tail);
}

View File

@ -1,184 +0,0 @@
/*
* The MIT License (MIT)
*
* Copyright (c) 2019 Ha Thach (tinyusb.org)
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
* This file is part of the TinyUSB stack.
*/
#include <stdlib.h>
#include "unity.h"
#include "tusb_option.h"
#include "tusb_errors.h"
#include "binary.h"
#include "type_helper.h"
#include "hal.h"
#include "mock_osal.h"
#include "hcd.h"
#include "mock_usbh_hcd.h"
#include "ehci.h"
#include "ehci_controller_fake.h"
#include "host_helper.h"
usbh_device_t _usbh_devices[CFG_TUSB_HOST_DEVICE_MAX+1];
static uint8_t const control_max_packet_size = 64;
static uint8_t const hub_addr = 2;
static uint8_t const hub_port = 2;
static uint8_t dev_addr;
static uint8_t hostid;
static ehci_qhd_t *async_head;
static ehci_qhd_t *p_control_qhd;
//--------------------------------------------------------------------+
// Setup/Teardown + helper declare
//--------------------------------------------------------------------+
void setUp(void)
{
tu_memclr(_usbh_devices, sizeof(usbh_device_t)*(CFG_TUSB_HOST_DEVICE_MAX+1));
TEST_ASSERT_STATUS( hcd_init() );
dev_addr = 1;
hostid = RANDOM(CONTROLLER_HOST_NUMBER) + TEST_CONTROLLER_HOST_START_INDEX;
helper_usbh_device_emulate(0, hub_addr, hub_port, hostid, TUSB_SPEED_HIGH);
helper_usbh_device_emulate(dev_addr, hub_addr, hub_port, hostid, TUSB_SPEED_HIGH);
async_head = get_async_head( hostid );
p_control_qhd = &ehci_data.device[dev_addr-1].control.qhd;
}
void tearDown(void)
{
}
void verify_open_qhd(ehci_qhd_t *p_qhd, uint8_t endpoint_addr, uint16_t max_packet_size)
{
TEST_ASSERT_EQUAL(dev_addr, p_qhd->device_address);
TEST_ASSERT_FALSE(p_qhd->non_hs_period_inactive_next_xact);
TEST_ASSERT_EQUAL(endpoint_addr & 0x0F, p_qhd->endpoint_number);
TEST_ASSERT_EQUAL(_usbh_devices[dev_addr].speed, p_qhd->endpoint_speed);
TEST_ASSERT_EQUAL(max_packet_size, p_qhd->max_package_size);
TEST_ASSERT_EQUAL(0, p_qhd->nak_count_reload); // TDD NAK Reload disable
TEST_ASSERT_EQUAL(hub_addr, p_qhd->hub_address);
TEST_ASSERT_EQUAL(hub_port, p_qhd->hub_port);
TEST_ASSERT_EQUAL(1, p_qhd->mult); // TDD operation model for mult
TEST_ASSERT_FALSE(p_qhd->qtd_overlay.halted);
TEST_ASSERT(p_qhd->qtd_overlay.next.terminate);
TEST_ASSERT(p_qhd->qtd_overlay.alternate.terminate);
//------------- HCD -------------//
TEST_ASSERT(p_qhd->used);
TEST_ASSERT_FALSE(p_qhd->is_removing);
TEST_ASSERT_NULL(p_qhd->p_qtd_list_head);
TEST_ASSERT_NULL(p_qhd->p_qtd_list_tail);
}
void verify_control_open_qhd(ehci_qhd_t *p_qhd)
{
verify_open_qhd(p_qhd, 0, control_max_packet_size);
TEST_ASSERT_EQUAL(0, p_qhd->class_code);
TEST_ASSERT_EQUAL(1, p_qhd->data_toggle_control);
TEST_ASSERT_EQUAL(0, p_qhd->interrupt_smask);
TEST_ASSERT_EQUAL(0, p_qhd->non_hs_interrupt_cmask);
}
//--------------------------------------------------------------------+
// PIPE OPEN
//--------------------------------------------------------------------+
void test_control_open_addr0_qhd_data(void)
{
dev_addr = 0;
//------------- Code Under Test -------------//
TEST_ASSERT_STATUS( hcd_pipe_control_open(dev_addr, control_max_packet_size) );
verify_control_open_qhd(async_head);
TEST_ASSERT(async_head->head_list_flag);
}
void test_control_open_qhd_data(void)
{
//------------- Code Under TEST -------------//
TEST_ASSERT_STATUS( hcd_pipe_control_open(dev_addr, control_max_packet_size));
verify_control_open_qhd(p_control_qhd);
TEST_ASSERT_FALSE(p_control_qhd->head_list_flag);
//------------- async list check -------------//
TEST_ASSERT_EQUAL_HEX((uint32_t) p_control_qhd, tu_align32(async_head->next.address));
TEST_ASSERT_FALSE(async_head->next.terminate);
TEST_ASSERT_EQUAL(EHCI_QUEUE_ELEMENT_QHD, async_head->next.type);
}
void test_control_open_highspeed(void)
{
_usbh_devices[dev_addr].speed = TUSB_SPEED_HIGH;
//------------- Code Under TEST -------------//
TEST_ASSERT_STATUS( hcd_pipe_control_open(dev_addr, control_max_packet_size) );
TEST_ASSERT_FALSE(p_control_qhd->non_hs_control_endpoint);
}
void test_control_open_non_highspeed(void)
{
_usbh_devices[dev_addr].speed = TUSB_SPEED_FULL;
//------------- Code Under TEST -------------//
TEST_ASSERT_STATUS( hcd_pipe_control_open(dev_addr, control_max_packet_size) );
TEST_ASSERT_TRUE(p_control_qhd->non_hs_control_endpoint);
}
//--------------------------------------------------------------------+
// PIPE CLOSE
//--------------------------------------------------------------------+
void test_control_addr0_close(void)
{
dev_addr = 0;
TEST_ASSERT_STATUS( hcd_pipe_control_open(dev_addr, control_max_packet_size) );
//------------- Code Under Test -------------//
TEST_ASSERT_STATUS( hcd_pipe_control_close(dev_addr) );
TEST_ASSERT(async_head->head_list_flag);
TEST_ASSERT(async_head->is_removing);
}
void test_control_close(void)
{
TEST_ASSERT_STATUS( hcd_pipe_control_open(dev_addr, control_max_packet_size) );
//------------- Code Under TEST -------------//
TEST_ASSERT_STATUS( hcd_pipe_control_close(dev_addr) );
TEST_ASSERT(p_control_qhd->is_removing);
TEST_ASSERT(p_control_qhd->used);
TEST_ASSERT( tu_align32(get_async_head(hostid)->next.address) != (uint32_t) p_control_qhd );
TEST_ASSERT_EQUAL( get_async_head(hostid), tu_align32(p_control_qhd->next.address));
}

View File

@ -1,275 +0,0 @@
/*
* The MIT License (MIT)
*
* Copyright (c) 2019 Ha Thach (tinyusb.org)
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
* This file is part of the TinyUSB stack.
*/
#include <stdlib.h>
#include "unity.h"
#include "tusb_option.h"
#include "tusb_errors.h"
#include "binary.h"
#include "type_helper.h"
#include "hal.h"
#include "mock_osal.h"
#include "hcd.h"
#include "mock_usbh_hcd.h"
#include "ehci.h"
#include "ehci_controller_fake.h"
#include "host_helper.h"
usbh_device_t _usbh_devices[CFG_TUSB_HOST_DEVICE_MAX+1];
static uint8_t const control_max_packet_size = 64;
static uint8_t const hub_addr = 2;
static uint8_t const hub_port = 2;
static uint8_t dev_addr;
static uint8_t hostid;
static uint8_t xfer_data [100];
static ehci_qhd_t *async_head;
static ehci_qhd_t *p_control_qhd;
static ehci_qtd_t *p_setup;
static ehci_qtd_t *p_data;
static ehci_qtd_t *p_status;
//--------------------------------------------------------------------+
// Setup/Teardown + helper declare
//--------------------------------------------------------------------+
void setUp(void)
{
ehci_controller_init();
tu_memclr(_usbh_devices, sizeof(usbh_device_t)*(CFG_TUSB_HOST_DEVICE_MAX+1));
tu_memclr(xfer_data, sizeof(xfer_data));
TEST_ASSERT_STATUS( hcd_init() );
dev_addr = 1;
hostid = RANDOM(CONTROLLER_HOST_NUMBER) + TEST_CONTROLLER_HOST_START_INDEX;
helper_usbh_device_emulate(0 , hub_addr, hub_port, hostid, TUSB_SPEED_HIGH);
helper_usbh_device_emulate(dev_addr , hub_addr, hub_port, hostid, TUSB_SPEED_HIGH);
async_head = get_async_head( hostid );
//------------- pipe open -------------//
TEST_ASSERT_STATUS( hcd_pipe_control_open(dev_addr, control_max_packet_size) );
p_control_qhd = &ehci_data.device[dev_addr-1].control.qhd;
p_setup = &ehci_data.device[dev_addr-1].control.qtd[0];
p_data = &ehci_data.device[dev_addr-1].control.qtd[1];
p_status = &ehci_data.device[dev_addr-1].control.qtd[2];
}
void tearDown(void)
{
}
//--------------------------------------------------------------------+
// CONTROL TRANSFER
//--------------------------------------------------------------------+
tusb_control_request_t request_get_dev_desc =
{
.bmRequestType_bit = { .direction = TUSB_DIR_DEV_TO_HOST, .type = TUSB_REQ_TYPE_STANDARD, .recipient = TUSB_REQ_RECIPIENT_DEVICE },
.bRequest = TUSB_REQ_GET_DESCRIPTOR,
.wValue = (TUSB_DESC_TYPE_DEVICE << 8),
.wLength = 18
};
tusb_control_request_t request_set_dev_addr =
{
.bmRequestType_bit = { .direction = TUSB_DIR_HOST_TO_DEV, .type = TUSB_REQ_TYPE_STANDARD, .recipient = TUSB_REQ_RECIPIENT_DEVICE },
.bRequest = TUSB_REQ_SET_ADDRESS,
.wValue = 3
};
void verify_qtd(ehci_qtd_t *p_qtd, uint8_t p_data[], uint16_t length)
{
TEST_ASSERT_TRUE(p_qtd->alternate.terminate); // not used, always invalid
TEST_ASSERT_FALSE(p_qtd->pingstate_err);
TEST_ASSERT_FALSE(p_qtd->non_hs_split_state);
TEST_ASSERT_FALSE(p_qtd->non_hs_period_missed_uframe);
TEST_ASSERT_FALSE(p_qtd->xact_err);
TEST_ASSERT_FALSE(p_qtd->babble_err);
TEST_ASSERT_FALSE(p_qtd->buffer_err);
TEST_ASSERT_FALSE(p_qtd->halted);
TEST_ASSERT_TRUE(p_qtd->active);
TEST_ASSERT_EQUAL(3, p_qtd->cerr);
TEST_ASSERT_EQUAL(0, p_qtd->current_page);
TEST_ASSERT_EQUAL(length, p_qtd->total_bytes);
TEST_ASSERT_EQUAL_HEX(p_data, p_qtd->buffer[0]);
}
//--------------------------------------------------------------------+
// Address 0
//--------------------------------------------------------------------+
void test_control_addr0_xfer_get_check_qhd_qtd_mapping(void)
{
dev_addr = 0;
ehci_qhd_t * const p_qhd = async_head;
TEST_ASSERT_STATUS( hcd_pipe_control_open(dev_addr, control_max_packet_size) );
//------------- Code Under TEST -------------//
TEST_ASSERT( hcd_pipe_control_xfer(dev_addr, &request_get_dev_desc, xfer_data) );
p_setup = &ehci_data.addr0_qtd[0];
p_data = &ehci_data.addr0_qtd[1];
p_status = &ehci_data.addr0_qtd[2];
TEST_ASSERT_EQUAL(0 , p_qhd->total_xferred_bytes);
TEST_ASSERT_EQUAL_HEX( p_setup, p_qhd->qtd_overlay.next.address );
TEST_ASSERT_EQUAL_HEX( p_setup , p_qhd->p_qtd_list_head);
TEST_ASSERT_EQUAL_HEX( p_data , p_setup->next.address);
TEST_ASSERT_EQUAL_HEX( p_status , p_data->next.address );
TEST_ASSERT_TRUE( p_status->next.terminate );
verify_qtd(p_setup, (uint8_t*) &request_get_dev_desc, 8);
}
//--------------------------------------------------------------------+
// Normal Control
//--------------------------------------------------------------------+
void test_control_xfer_get(void)
{
//------------- Code Under TEST -------------//
TEST_ASSERT( hcd_pipe_control_xfer(dev_addr, &request_get_dev_desc, xfer_data) );
TEST_ASSERT_EQUAL_HEX( p_setup, p_control_qhd->qtd_overlay.next.address );
TEST_ASSERT_EQUAL_HEX( p_setup , p_control_qhd->p_qtd_list_head);
TEST_ASSERT_EQUAL_HEX( p_data , p_setup->next.address);
TEST_ASSERT_EQUAL_HEX( p_status , p_data->next.address );
TEST_ASSERT_TRUE( p_status->next.terminate );
//------------- SETUP -------------//
verify_qtd(p_setup, (uint8_t*) &request_get_dev_desc, 8);
TEST_ASSERT_FALSE(p_setup->int_on_complete);
TEST_ASSERT_FALSE(p_setup->data_toggle);
TEST_ASSERT_EQUAL(EHCI_PID_SETUP, p_setup->pid);
//------------- DATA -------------//
verify_qtd(p_data, xfer_data, request_get_dev_desc.wLength);
TEST_ASSERT_FALSE(p_data->int_on_complete);
TEST_ASSERT_TRUE(p_data->data_toggle);
TEST_ASSERT_EQUAL(EHCI_PID_IN, p_data->pid);
//------------- STATUS -------------//
verify_qtd(p_status, NULL, 0);
TEST_ASSERT_TRUE(p_status->int_on_complete);
TEST_ASSERT_TRUE(p_status->data_toggle);
TEST_ASSERT_EQUAL(EHCI_PID_OUT, p_status->pid);
TEST_ASSERT_TRUE(p_status->next.terminate);
TEST_ASSERT_EQUAL_HEX(p_setup, p_control_qhd->p_qtd_list_head);
TEST_ASSERT_EQUAL_HEX(p_status, p_control_qhd->p_qtd_list_tail);
}
void test_control_xfer_set(void)
{
//------------- Code Under TEST -------------//
TEST_ASSERT( hcd_pipe_control_xfer(dev_addr, &request_set_dev_addr, xfer_data) );
TEST_ASSERT_EQUAL_HEX( p_setup, p_control_qhd->qtd_overlay.next.address );
TEST_ASSERT_EQUAL_HEX( p_setup , p_control_qhd->p_qtd_list_head);
TEST_ASSERT_EQUAL_HEX( p_status , p_setup->next.address );
TEST_ASSERT_TRUE( p_status->next.terminate );
//------------- STATUS -------------//
verify_qtd(p_status, NULL, 0);
TEST_ASSERT_TRUE(p_status->int_on_complete);
TEST_ASSERT_TRUE(p_status->data_toggle);
TEST_ASSERT_EQUAL(EHCI_PID_IN, p_status->pid);
TEST_ASSERT_TRUE(p_status->next.terminate);
TEST_ASSERT_EQUAL_HEX(p_setup, p_control_qhd->p_qtd_list_head);
TEST_ASSERT_EQUAL_HEX(p_status, p_control_qhd->p_qtd_list_tail);
}
void test_control_xfer_complete_isr(void)
{
TEST_ASSERT( hcd_pipe_control_xfer(dev_addr, &request_get_dev_desc, xfer_data) );
hcd_event_xfer_complete_Expect(((pipe_handle_t){.dev_addr = dev_addr}), 0, XFER_RESULT_SUCCESS, 18);
//------------- Code Under TEST -------------//
ehci_controller_run(hostid);
TEST_ASSERT_EQUAL(0, p_control_qhd->total_xferred_bytes);
TEST_ASSERT_NULL(p_control_qhd->p_qtd_list_head);
TEST_ASSERT_NULL(p_control_qhd->p_qtd_list_tail);
TEST_ASSERT_FALSE(p_setup->used);
TEST_ASSERT_FALSE(p_data->used);
TEST_ASSERT_FALSE(p_status->used);
}
void test_control_xfer_error_isr(void)
{
TEST_ASSERT( hcd_pipe_control_xfer(dev_addr, &request_get_dev_desc, xfer_data) );
hcd_event_xfer_complete_Expect(((pipe_handle_t){.dev_addr = dev_addr}), 0, XFER_RESULT_FAILED, 0);
//------------- Code Under TEST -------------//
ehci_controller_run_error(hostid);
TEST_ASSERT_EQUAL(0, p_control_qhd->total_xferred_bytes);
TEST_ASSERT_NULL( p_control_qhd->p_qtd_list_head );
TEST_ASSERT_NULL( p_control_qhd->p_qtd_list_tail );
TEST_ASSERT_TRUE( p_control_qhd->qtd_overlay.next.terminate);
TEST_ASSERT_TRUE( p_control_qhd->qtd_overlay.alternate.terminate);
TEST_ASSERT_FALSE( p_control_qhd->qtd_overlay.halted);
}
void test_control_xfer_error_stall(void)
{
TEST_ASSERT( hcd_pipe_control_xfer(dev_addr, &request_get_dev_desc, xfer_data) );
hcd_event_xfer_complete_Expect(((pipe_handle_t){.dev_addr = dev_addr}), 0, XFER_RESULT_STALLED, 0);
//------------- Code Under TEST -------------//
ehci_controller_run_stall(hostid);
TEST_ASSERT_EQUAL(0, p_control_qhd->total_xferred_bytes);
TEST_ASSERT_NULL( p_control_qhd->p_qtd_list_head );
TEST_ASSERT_NULL( p_control_qhd->p_qtd_list_tail );
TEST_ASSERT_TRUE( p_control_qhd->qtd_overlay.next.terminate);
TEST_ASSERT_TRUE( p_control_qhd->qtd_overlay.alternate.terminate);
TEST_ASSERT_FALSE( p_control_qhd->qtd_overlay.halted);
TEST_ASSERT_FALSE( p_setup->used );
TEST_ASSERT_FALSE( p_data->used );
TEST_ASSERT_FALSE( p_status->used );
}

View File

@ -1,330 +0,0 @@
/*
* The MIT License (MIT)
*
* Copyright (c) 2019 Ha Thach (tinyusb.org)
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
* This file is part of the TinyUSB stack.
*/
#include "unity.h"
#include "tusb_option.h"
#include "tusb_errors.h"
#include "binary.h"
#include "type_helper.h"
#include "hal.h"
#include "mock_osal.h"
#include "hcd.h"
#include "mock_usbh_hcd.h"
#include "ehci.h"
#include "ehci_controller_fake.h"
#include "host_helper.h"
usbh_device_t _usbh_devices[CFG_TUSB_HOST_DEVICE_MAX+1];
static uint8_t const hub_addr = 2;
static uint8_t const hub_port = 2;
static uint8_t dev_addr;
static uint8_t hostid;
static ehci_qhd_t *period_head_arr;
static ehci_qhd_t *p_int_qhd;
static pipe_handle_t pipe_hdl;
//--------------------------------------------------------------------+
// Setup/Teardown + helper declare
//--------------------------------------------------------------------+
void setUp(void)
{
tu_memclr(_usbh_devices, sizeof(usbh_device_t)*(CFG_TUSB_HOST_DEVICE_MAX+1));
hcd_init();
dev_addr = 1;
hostid = RANDOM(CONTROLLER_HOST_NUMBER) + TEST_CONTROLLER_HOST_START_INDEX;
helper_usbh_device_emulate(dev_addr , hub_addr, hub_port, hostid, TUSB_SPEED_HIGH);
period_head_arr = get_period_head( hostid, 1 );
p_int_qhd = NULL;
tu_memclr(&pipe_hdl, sizeof(pipe_handle_t));
}
void tearDown(void)
{
}
void verify_open_qhd(ehci_qhd_t *p_qhd, uint8_t endpoint_addr, uint16_t max_packet_size)
{
TEST_ASSERT_EQUAL(dev_addr, p_qhd->device_address);
TEST_ASSERT_FALSE(p_qhd->non_hs_period_inactive_next_xact);
TEST_ASSERT_EQUAL(endpoint_addr & 0x0F, p_qhd->endpoint_number);
TEST_ASSERT_EQUAL(_usbh_devices[dev_addr].speed, p_qhd->endpoint_speed);
TEST_ASSERT_EQUAL(max_packet_size, p_qhd->max_package_size);
TEST_ASSERT_EQUAL(0, p_qhd->nak_count_reload); // TDD NAK Reload disable
TEST_ASSERT_EQUAL(hub_addr, p_qhd->hub_address);
TEST_ASSERT_EQUAL(hub_port, p_qhd->hub_port);
TEST_ASSERT_EQUAL(1, p_qhd->mult); // TDD operation model for mult
TEST_ASSERT_FALSE(p_qhd->qtd_overlay.halted);
TEST_ASSERT(p_qhd->qtd_overlay.next.terminate);
TEST_ASSERT(p_qhd->qtd_overlay.alternate.terminate);
//------------- HCD -------------//
TEST_ASSERT(p_qhd->used);
TEST_ASSERT_FALSE(p_qhd->is_removing);
TEST_ASSERT_NULL(p_qhd->p_qtd_list_head);
TEST_ASSERT_NULL(p_qhd->p_qtd_list_tail);
}
//--------------------------------------------------------------------+
// PIPE OPEN
//--------------------------------------------------------------------+
tusb_desc_endpoint_t const desc_ept_interrupt_out =
{
.bLength = sizeof(tusb_desc_endpoint_t),
.bDescriptorType = TUSB_DESC_TYPE_ENDPOINT,
.bEndpointAddress = 0x02,
.bmAttributes = { .xfer = TUSB_XFER_INTERRUPT },
.wMaxPacketSize = 16,
.bInterval = 4
};
void verify_int_qhd(ehci_qhd_t *p_qhd, tusb_desc_endpoint_t const * desc_endpoint, uint8_t class_code)
{
verify_open_qhd(p_qhd, desc_endpoint->bEndpointAddress, desc_endpoint->wMaxPacketSize.size);
TEST_ASSERT_FALSE(p_qhd->head_list_flag);
TEST_ASSERT_FALSE(p_qhd->data_toggle_control);
TEST_ASSERT_FALSE(p_qhd->non_hs_control_endpoint);
TEST_ASSERT_EQUAL(desc_endpoint->bEndpointAddress & 0x80 ? EHCI_PID_IN : EHCI_PID_OUT, p_qhd->pid_non_control);
}
void check_int_endpoint_link(ehci_qhd_t *p_prev, ehci_qhd_t *p_qhd)
{
//------------- period list check -------------//
TEST_ASSERT_EQUAL_HEX((uint32_t) p_qhd, tu_align32(p_prev->next.address));
TEST_ASSERT_FALSE(p_prev->next.terminate);
TEST_ASSERT_EQUAL(EHCI_QUEUE_ELEMENT_QHD, p_prev->next.type);
}
void test_open_interrupt_qhd_hs(void)
{
//------------- Code Under TEST -------------//
pipe_hdl = hcd_edpt_open(dev_addr, &desc_ept_interrupt_out, TUSB_CLASS_HID);
TEST_ASSERT_EQUAL(dev_addr, pipe_hdl.dev_addr);
TEST_ASSERT_EQUAL(TUSB_XFER_INTERRUPT, pipe_hdl.xfer_type);
p_int_qhd = &ehci_data.device[ pipe_hdl.dev_addr-1].qhd[ pipe_hdl.index ];
verify_int_qhd(p_int_qhd, &desc_ept_interrupt_out, TUSB_CLASS_HID);
TEST_ASSERT_EQUAL(0, p_int_qhd->non_hs_interrupt_cmask);
}
void test_open_interrupt_hs_interval_1(void)
{
tusb_desc_endpoint_t int_edp_interval = desc_ept_interrupt_out;
int_edp_interval.bInterval = 1;
//------------- Code Under TEST -------------//
pipe_hdl = hcd_edpt_open(dev_addr, &int_edp_interval, TUSB_CLASS_HID);
p_int_qhd = &ehci_data.device[ pipe_hdl.dev_addr-1].qhd[ pipe_hdl.index ];
TEST_ASSERT_EQUAL(0 , p_int_qhd->interval_ms);
TEST_ASSERT_EQUAL(TU_BIN8(11111111) , p_int_qhd->interrupt_smask);
check_int_endpoint_link(period_head_arr, p_int_qhd);
}
void test_open_interrupt_hs_interval_2(void)
{
tusb_desc_endpoint_t int_edp_interval = desc_ept_interrupt_out;
int_edp_interval.bInterval = 2;
//------------- Code Under TEST -------------//
pipe_hdl = hcd_edpt_open(dev_addr, &int_edp_interval, TUSB_CLASS_HID);
p_int_qhd = &ehci_data.device[ pipe_hdl.dev_addr-1].qhd[ pipe_hdl.index ];
TEST_ASSERT_EQUAL(0 , p_int_qhd->interval_ms);
TEST_ASSERT_EQUAL(4 , tu_cardof(p_int_qhd->interrupt_smask)); // either 10101010 or 01010101
check_int_endpoint_link(period_head_arr, p_int_qhd);
}
void test_open_interrupt_hs_interval_3(void)
{
tusb_desc_endpoint_t int_edp_interval = desc_ept_interrupt_out;
int_edp_interval.bInterval = 3;
//------------- Code Under TEST -------------//
pipe_hdl = hcd_edpt_open(dev_addr, &int_edp_interval, TUSB_CLASS_HID);
p_int_qhd = &ehci_data.device[ pipe_hdl.dev_addr-1].qhd[ pipe_hdl.index ];
TEST_ASSERT_EQUAL(0, p_int_qhd->interval_ms);
TEST_ASSERT_EQUAL(2, tu_cardof(p_int_qhd->interrupt_smask) );
check_int_endpoint_link(period_head_arr, p_int_qhd);
}
void test_open_interrupt_hs_interval_4(void)
{
tusb_desc_endpoint_t int_edp_interval = desc_ept_interrupt_out;
int_edp_interval.bInterval = 4;
//------------- Code Under TEST -------------//
pipe_hdl = hcd_edpt_open(dev_addr, &int_edp_interval, TUSB_CLASS_HID);
p_int_qhd = &ehci_data.device[ pipe_hdl.dev_addr-1].qhd[ pipe_hdl.index ];
TEST_ASSERT_EQUAL(1, p_int_qhd->interval_ms);
TEST_ASSERT_EQUAL(1, tu_cardof(p_int_qhd->interrupt_smask) );
check_int_endpoint_link(period_head_arr, p_int_qhd);
}
void test_open_interrupt_hs_interval_5(void)
{
tusb_desc_endpoint_t int_edp_interval = desc_ept_interrupt_out;
int_edp_interval.bInterval = 5;
//------------- Code Under TEST -------------//
pipe_hdl = hcd_edpt_open(dev_addr, &int_edp_interval, TUSB_CLASS_HID);
p_int_qhd = &ehci_data.device[ pipe_hdl.dev_addr-1].qhd[ pipe_hdl.index ];
TEST_ASSERT_EQUAL(2, p_int_qhd->interval_ms);
TEST_ASSERT_EQUAL(1, tu_cardof(p_int_qhd->interrupt_smask) );
check_int_endpoint_link( get_period_head(hostid, 2), p_int_qhd );
}
void test_open_interrupt_hs_interval_6(void)
{
tusb_desc_endpoint_t int_edp_interval = desc_ept_interrupt_out;
int_edp_interval.bInterval = 6;
//------------- Code Under TEST -------------//
pipe_hdl = hcd_edpt_open(dev_addr, &int_edp_interval, TUSB_CLASS_HID);
p_int_qhd = &ehci_data.device[ pipe_hdl.dev_addr-1].qhd[ pipe_hdl.index ];
TEST_ASSERT_EQUAL(4, p_int_qhd->interval_ms);
TEST_ASSERT_EQUAL(1, tu_cardof(p_int_qhd->interrupt_smask) );
check_int_endpoint_link( get_period_head(hostid, 4), p_int_qhd);
}
void test_open_interrupt_hs_interval_7(void)
{
tusb_desc_endpoint_t int_edp_interval = desc_ept_interrupt_out;
int_edp_interval.bInterval = 7;
//------------- Code Under TEST -------------//
pipe_hdl = hcd_edpt_open(dev_addr, &int_edp_interval, TUSB_CLASS_HID);
p_int_qhd = &ehci_data.device[ pipe_hdl.dev_addr-1].qhd[ pipe_hdl.index ];
TEST_ASSERT_EQUAL(8, p_int_qhd->interval_ms);
TEST_ASSERT_EQUAL(1, tu_cardof(p_int_qhd->interrupt_smask) );
check_int_endpoint_link( get_period_head(hostid, 8), p_int_qhd);
}
void test_open_interrupt_hs_interval_8(void)
{
tusb_desc_endpoint_t int_edp_interval = desc_ept_interrupt_out;
int_edp_interval.bInterval = 16;
//------------- Code Under TEST -------------//
pipe_hdl = hcd_edpt_open(dev_addr, &int_edp_interval, TUSB_CLASS_HID);
p_int_qhd = &ehci_data.device[ pipe_hdl.dev_addr-1].qhd[ pipe_hdl.index ];
TEST_ASSERT_EQUAL(255, p_int_qhd->interval_ms);
TEST_ASSERT_EQUAL(1, tu_cardof(p_int_qhd->interrupt_smask) );
check_int_endpoint_link( get_period_head(hostid, 255), p_int_qhd);
check_int_endpoint_link( get_period_head(hostid, 8) , p_int_qhd);
}
void test_open_interrupt_qhd_non_hs(void)
{
_usbh_devices[dev_addr].speed = TUSB_SPEED_FULL;
//------------- Code Under TEST -------------//
pipe_hdl = hcd_edpt_open(dev_addr, &desc_ept_interrupt_out, TUSB_CLASS_HID);
TEST_ASSERT_EQUAL(dev_addr, pipe_hdl.dev_addr);
TEST_ASSERT_EQUAL(TUSB_XFER_INTERRUPT, pipe_hdl.xfer_type);
p_int_qhd = &ehci_data.device[ pipe_hdl.dev_addr-1].qhd[ pipe_hdl.index ];
verify_int_qhd(p_int_qhd, &desc_ept_interrupt_out, TUSB_CLASS_HID);
TEST_ASSERT_EQUAL(desc_ept_interrupt_out.bInterval, p_int_qhd->interval_ms);
TEST_ASSERT_EQUAL(1, p_int_qhd->interrupt_smask);
TEST_ASSERT_EQUAL(0x1c, p_int_qhd->non_hs_interrupt_cmask);
}
void test_open_interrupt_qhd_non_hs_9(void)
{
tusb_desc_endpoint_t int_edp_interval = desc_ept_interrupt_out;
int_edp_interval.bInterval = 32;
_usbh_devices[dev_addr].speed = TUSB_SPEED_FULL;
//------------- Code Under TEST -------------//
pipe_hdl = hcd_edpt_open(dev_addr, &int_edp_interval, TUSB_CLASS_HID);
p_int_qhd = &ehci_data.device[ pipe_hdl.dev_addr-1].qhd[ pipe_hdl.index ];
TEST_ASSERT_EQUAL(int_edp_interval.bInterval, p_int_qhd->interval_ms);
check_int_endpoint_link( get_period_head(hostid, 32), p_int_qhd);
check_int_endpoint_link( get_period_head(hostid, 8) , p_int_qhd);
}
//--------------------------------------------------------------------+
// PIPE CLOSE
//--------------------------------------------------------------------+
void test_interrupt_close(void)
{
pipe_hdl = hcd_edpt_open(dev_addr, &desc_ept_interrupt_out, TUSB_CLASS_HID);
p_int_qhd = qhd_get_from_pipe_handle(pipe_hdl);
//------------- Code Under TEST -------------//
TEST_ASSERT_EQUAL(TUSB_ERROR_NONE,
hcd_pipe_close(pipe_hdl) );
TEST_ASSERT(p_int_qhd->is_removing);
TEST_ASSERT( tu_align32(period_head_arr->next.address) != (uint32_t) p_int_qhd );
TEST_ASSERT_EQUAL_HEX( (uint32_t) period_head_arr, tu_align32(p_int_qhd->next.address ) );
TEST_ASSERT_EQUAL(EHCI_QUEUE_ELEMENT_QHD, p_int_qhd->next.type);
}
void test_interrupt_256ms_close(void)
{
tusb_desc_endpoint_t int_edp_interval = desc_ept_interrupt_out;
int_edp_interval.bInterval = 9;
pipe_hdl = hcd_edpt_open(dev_addr, &int_edp_interval, TUSB_CLASS_HID);
p_int_qhd = qhd_get_from_pipe_handle(pipe_hdl);
//------------- Code Under TEST -------------//
TEST_ASSERT_EQUAL(TUSB_ERROR_NONE,
hcd_pipe_close(pipe_hdl) );
TEST_ASSERT(p_int_qhd->is_removing);
TEST_ASSERT( tu_align32(get_period_head(hostid, 8)->address) != (uint32_t) p_int_qhd );
TEST_ASSERT_EQUAL_HEX( (uint32_t) get_period_head(hostid, 8), tu_align32(p_int_qhd->next.address ) );
TEST_ASSERT_EQUAL(EHCI_QUEUE_ELEMENT_QHD, p_int_qhd->next.type);
}

View File

@ -1,252 +0,0 @@
/*
* The MIT License (MIT)
*
* Copyright (c) 2019 Ha Thach (tinyusb.org)
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
* This file is part of the TinyUSB stack.
*/
#include <stdlib.h>
#include "unity.h"
#include "tusb_option.h"
#include "tusb_errors.h"
#include "binary.h"
#include "type_helper.h"
#include "hal.h"
#include "mock_osal.h"
#include "hcd.h"
#include "mock_usbh_hcd.h"
#include "ehci.h"
#include "ehci_controller_fake.h"
#include "host_helper.h"
usbh_device_t _usbh_devices[CFG_TUSB_HOST_DEVICE_MAX+1];
static uint8_t const hub_addr = 2;
static uint8_t const hub_port = 2;
static uint8_t dev_addr;
static uint8_t hostid;
static uint8_t xfer_data [100];
static uint8_t data2[100];
static ehci_qhd_t *period_head_arr;
static ehci_qhd_t *p_qhd_interrupt;
static pipe_handle_t pipe_hdl_interrupt;
static tusb_desc_endpoint_t const desc_ept_interrupt_in =
{
.bLength = sizeof(tusb_desc_endpoint_t),
.bDescriptorType = TUSB_DESC_TYPE_ENDPOINT,
.bEndpointAddress = 0x81,
.bmAttributes = { .xfer = TUSB_XFER_INTERRUPT },
.wMaxPacketSize = 8,
.bInterval = 2
};
static tusb_desc_endpoint_t const desc_ept_interupt_out =
{
.bLength = sizeof(tusb_desc_endpoint_t),
.bDescriptorType = TUSB_DESC_TYPE_ENDPOINT,
.bEndpointAddress = 0x01,
.bmAttributes = { .xfer = TUSB_XFER_INTERRUPT },
.wMaxPacketSize = 64,
.bInterval = 3
};
//--------------------------------------------------------------------+
// Setup/Teardown + helper declare
//--------------------------------------------------------------------+
void setUp(void)
{
ehci_controller_init();
tu_memclr(_usbh_devices, sizeof(usbh_device_t)*(CFG_TUSB_HOST_DEVICE_MAX+1));
tu_memclr(xfer_data, sizeof(xfer_data));
TEST_ASSERT_STATUS( hcd_init() );
dev_addr = 1;
hostid = RANDOM(CONTROLLER_HOST_NUMBER) + TEST_CONTROLLER_HOST_START_INDEX;
helper_usbh_device_emulate(dev_addr , hub_addr, hub_port, hostid, TUSB_SPEED_HIGH);
period_head_arr = (ehci_qhd_t*) get_period_head( hostid, 1 );
//------------- pipe open -------------//
pipe_hdl_interrupt = hcd_edpt_open(dev_addr, &desc_ept_interrupt_in, TUSB_CLASS_HID);
TEST_ASSERT_EQUAL(dev_addr, pipe_hdl_interrupt.dev_addr);
TEST_ASSERT_EQUAL(TUSB_XFER_INTERRUPT, pipe_hdl_interrupt.xfer_type);
p_qhd_interrupt = &ehci_data.device[ dev_addr -1].qhd[ pipe_hdl_interrupt.index ];
}
void tearDown(void)
{
}
//--------------------------------------------------------------------+
// BULK TRANSFER
//--------------------------------------------------------------------+
void verify_qtd(ehci_qtd_t *p_qtd, uint8_t p_data[], uint16_t length)
{
TEST_ASSERT_TRUE(p_qtd->alternate.terminate); // not used, always invalid
//------------- status -------------//
TEST_ASSERT_FALSE(p_qtd->pingstate_err);
TEST_ASSERT_FALSE(p_qtd->non_hs_split_state);
TEST_ASSERT_FALSE(p_qtd->non_hs_period_missed_uframe);
TEST_ASSERT_FALSE(p_qtd->xact_err);
TEST_ASSERT_FALSE(p_qtd->babble_err);
TEST_ASSERT_FALSE(p_qtd->buffer_err);
TEST_ASSERT_FALSE(p_qtd->halted);
TEST_ASSERT_TRUE(p_qtd->active);
TEST_ASSERT_FALSE(p_qtd->data_toggle);
TEST_ASSERT_EQUAL(3, p_qtd->cerr);
TEST_ASSERT_EQUAL(0, p_qtd->current_page);
TEST_ASSERT_EQUAL(length, p_qtd->total_bytes);
TEST_ASSERT_EQUAL(length, p_qtd->expected_bytes);
TEST_ASSERT_TRUE(p_qtd->used);
TEST_ASSERT_EQUAL_HEX( p_data, p_qtd->buffer[0] );
for(uint8_t i=1; i<5; i++)
{
TEST_ASSERT_EQUAL_HEX( tu_align4k((uint32_t) (p_data+4096*i)), tu_align4k(p_qtd->buffer[i]) );
}
}
void test_interrupt_xfer(void)
{
//------------- Code Under Test -------------//
TEST_ASSERT_STATUS( hcd_pipe_xfer(pipe_hdl_interrupt, xfer_data, sizeof(xfer_data), true) );
ehci_qtd_t* p_qtd = p_qhd_interrupt->p_qtd_list_head;
TEST_ASSERT_NOT_NULL(p_qtd);
verify_qtd( p_qtd, xfer_data, sizeof(xfer_data));
TEST_ASSERT_EQUAL_HEX(p_qhd_interrupt->qtd_overlay.next.address, p_qtd);
TEST_ASSERT_TRUE(p_qtd->next.terminate);
TEST_ASSERT_EQUAL(EHCI_PID_IN, p_qtd->pid);
TEST_ASSERT_TRUE(p_qtd->int_on_complete);
}
void test_interrupt_xfer_double(void)
{
//------------- Code Under Test -------------//
TEST_ASSERT_STATUS( hcd_pipe_xfer(pipe_hdl_interrupt, xfer_data, sizeof(xfer_data), false) );
TEST_ASSERT_STATUS( hcd_pipe_xfer(pipe_hdl_interrupt, data2, sizeof(data2), true) );
ehci_qtd_t* p_head = p_qhd_interrupt->p_qtd_list_head;
ehci_qtd_t* p_tail = p_qhd_interrupt->p_qtd_list_tail;
//------------- list head -------------//
TEST_ASSERT_NOT_NULL(p_head);
verify_qtd(p_head, xfer_data, sizeof(xfer_data));
TEST_ASSERT_EQUAL_HEX(p_qhd_interrupt->qtd_overlay.next.address, p_head);
TEST_ASSERT_EQUAL(EHCI_PID_IN, p_head->pid);
TEST_ASSERT_FALSE(p_head->next.terminate);
TEST_ASSERT_FALSE(p_head->int_on_complete);
//------------- list tail -------------//
TEST_ASSERT_NOT_NULL(p_tail);
verify_qtd(p_tail, data2, sizeof(data2));
TEST_ASSERT_EQUAL_HEX( tu_align32(p_head->next.address), p_tail);
TEST_ASSERT_EQUAL(EHCI_PID_IN, p_tail->pid);
TEST_ASSERT_TRUE(p_tail->next.terminate);
TEST_ASSERT_TRUE(p_tail->int_on_complete);
}
void check_qhd_after_complete(ehci_qhd_t *p_qhd)
{
TEST_ASSERT_TRUE(p_qhd->qtd_overlay.next.terminate);
TEST_ASSERT_NULL(p_qhd->p_qtd_list_head);
TEST_ASSERT_NULL(p_qhd->p_qtd_list_tail);
}
void test_interrupt_xfer_complete_isr_interval_less_than_1ms(void)
{
TEST_ASSERT_STATUS( hcd_pipe_xfer(pipe_hdl_interrupt, xfer_data, sizeof(xfer_data), false) );
TEST_ASSERT_STATUS( hcd_pipe_xfer(pipe_hdl_interrupt, data2, sizeof(data2), true) );
hcd_event_xfer_complete_Expect(pipe_hdl_interrupt, TUSB_CLASS_HID, XFER_RESULT_SUCCESS, sizeof(xfer_data)+sizeof(data2));
ehci_qtd_t* p_head = p_qhd_interrupt->p_qtd_list_head;
ehci_qtd_t* p_tail = p_qhd_interrupt->p_qtd_list_tail;
//------------- Code Under Test -------------//
ehci_controller_run(hostid);
TEST_ASSERT_EQUAL(0, p_qhd_interrupt->total_xferred_bytes);
check_qhd_after_complete(p_qhd_interrupt);
TEST_ASSERT_FALSE(p_head->used);
TEST_ASSERT_FALSE(p_tail->used);
}
void test_interrupt_xfer_complete_isr_interval_2ms(void)
{
tusb_desc_endpoint_t desc_endpoint_2ms = desc_ept_interrupt_in;
desc_endpoint_2ms.bInterval = 5;
pipe_handle_t pipe_hdl_2ms = hcd_edpt_open(dev_addr, &desc_endpoint_2ms, TUSB_CLASS_HID);
ehci_qhd_t * p_qhd_2ms = &ehci_data.device[ dev_addr -1].qhd[ pipe_hdl_2ms.index ];
TEST_ASSERT_STATUS( hcd_pipe_xfer(pipe_hdl_2ms, xfer_data, sizeof(xfer_data), false) );
ehci_qtd_t* p_head = p_qhd_2ms->p_qtd_list_head;
ehci_qtd_t* p_tail = p_qhd_2ms->p_qtd_list_tail;
//------------- Code Under Test -------------//
ehci_controller_run(hostid);
TEST_ASSERT_EQUAL(0, p_qhd_interrupt->total_xferred_bytes);
check_qhd_after_complete(p_qhd_2ms);
TEST_ASSERT_FALSE(p_head->used);
TEST_ASSERT_FALSE(p_tail->used);
}
void test_interrupt_xfer_error_isr(void)
{
TEST_ASSERT_STATUS( hcd_pipe_xfer(pipe_hdl_interrupt, xfer_data, sizeof(xfer_data), true) );
hcd_event_xfer_complete_Expect(pipe_hdl_interrupt, TUSB_CLASS_HID, XFER_RESULT_FAILED, 0);
//------------- Code Under TEST -------------//
ehci_controller_run_error(hostid);
TEST_ASSERT_EQUAL(0, p_qhd_interrupt->total_xferred_bytes);
}
void test_interrupt_xfer_error_stall(void)
{
TEST_ASSERT_STATUS( hcd_pipe_xfer(pipe_hdl_interrupt, xfer_data, sizeof(xfer_data), true) );
hcd_event_xfer_complete_Expect(pipe_hdl_interrupt, TUSB_CLASS_HID, XFER_RESULT_STALLED, 0);
//------------- Code Under TEST -------------//
ehci_controller_run_stall(hostid);
TEST_ASSERT_EQUAL(0, p_qhd_interrupt->total_xferred_bytes);
}

View File

@ -1,87 +0,0 @@
/*
* The MIT License (MIT)
*
* Copyright (c) 2019 Ha Thach (tinyusb.org)
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
* This file is part of the TinyUSB stack.
*/
#include "unity.h"
#include "tusb_option.h"
#include "tusb_errors.h"
#include "binary.h"
#include "type_helper.h"
#include "hal.h"
#include "mock_osal.h"
#include "hcd.h"
#include "mock_usbh_hcd.h"
#include "ehci.h"
#include "ehci_controller_fake.h"
#include "host_helper.h"
usbh_device_t _usbh_devices[CFG_TUSB_HOST_DEVICE_MAX+1];
static uint8_t const hub_addr = 2;
static uint8_t const hub_port = 2;
static uint8_t dev_addr;
static uint8_t hostid;
static ehci_qhd_t *period_head_arr;
//--------------------------------------------------------------------+
// Setup/Teardown + helper declare
//--------------------------------------------------------------------+
void setUp(void)
{
tu_memclr(_usbh_devices, sizeof(usbh_device_t)*(CFG_TUSB_HOST_DEVICE_MAX+1));
hcd_init();
dev_addr = 1;
hostid = RANDOM(CONTROLLER_HOST_NUMBER) + TEST_CONTROLLER_HOST_START_INDEX;
helper_usbh_device_emulate(dev_addr , hub_addr, hub_port, hostid, TUSB_SPEED_HIGH);
period_head_arr = get_period_head( hostid, 1 );
}
void tearDown(void)
{
}
//--------------------------------------------------------------------+
// TODO ISOCRHONOUS PIPE
//--------------------------------------------------------------------+
tusb_desc_endpoint_t const desc_ept_iso_in =
{
.bLength = sizeof(tusb_desc_endpoint_t),
.bDescriptorType = TUSB_DESC_TYPE_ENDPOINT,
.bEndpointAddress = 0x83,
.bmAttributes = { .xfer = TUSB_XFER_ISOCHRONOUS },
.wMaxPacketSize = 1024,
.bInterval = 1
};
void test_open_isochronous(void)
{
pipe_handle_t pipe_hdl = hcd_edpt_open(dev_addr, &desc_ept_iso_in, TUSB_CLASS_AUDIO);
TEST_ASSERT_EQUAL(0, pipe_hdl.dev_addr);
}

View File

@ -1,64 +0,0 @@
/*
* The MIT License (MIT)
*
* Copyright (c) 2019 Ha Thach (tinyusb.org)
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
* This file is part of the TinyUSB stack.
*/
/** \file
* \brief TBD
*
* \note TBD
*/
/** \ingroup TBD
* \defgroup TBD
* \brief TBD
*
* @{
*/
#ifndef _TUSB_HIDH_CALLBACK_H_
#define _TUSB_HIDH_CALLBACK_H_
#ifdef __cplusplus
extern "C" {
#endif
#include "common/common.h"
//------------- hidh -------------//
void tusbh_hid_keyboard_isr(uint8_t dev_addr, xfer_result_t event);
void tusbh_hid_keyboard_mounted_cb(uint8_t dev_addr);
void tusbh_hid_keyboard_unmounted_cb(uint8_t dev_addr);
void tusbh_hid_mouse_isr(uint8_t dev_addr, xfer_result_t event);
void tusbh_hid_mouse_mounted_cb(uint8_t dev_addr);
void tusbh_hid_mouse_unmounted_cb(uint8_t dev_addr);
#ifdef __cplusplus
}
#endif
#endif /* _TUSB_HIDH_CALLBACK_H_ */
/** @} */

View File

@ -1,87 +0,0 @@
/*
* The MIT License (MIT)
*
* Copyright (c) 2019 Ha Thach (tinyusb.org)
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
* This file is part of the TinyUSB stack.
*/
#include "stdlib.h"
#include "unity.h"
#include "tusb_option.h"
#include "tusb_errors.h"
#include "binary.h"
#include "type_helper.h"
#include "common/common.h"
#include "descriptor_test.h"
#include "mock_osal.h"
#include "mock_hcd.h"
#include "mock_usbh.h"
#include "hid_host.h"
#include "mock_hidh_callback.h"
uint8_t dev_addr;
pipe_handle_t pipe_hdl;
extern hidh_interface_info_t keyboardh_data[CFG_TUSB_HOST_DEVICE_MAX];
tusb_desc_interface_t const *p_kbd_interface_desc = &desc_configuration.keyboard_interface;
tusb_hid_descriptor_hid_t const *p_kbh_hid_desc = &desc_configuration.keyboard_hid;
tusb_desc_endpoint_t const *p_kdb_endpoint_desc = &desc_configuration.keyboard_endpoint;
void setUp(void)
{
dev_addr = RANDOM(CFG_TUSB_HOST_DEVICE_MAX)+1;
pipe_hdl = (pipe_handle_t) {.dev_addr = dev_addr, .xfer_type = TUSB_XFER_INTERRUPT, .index = 2};
}
void tearDown(void)
{
}
//void test_hidh_open_ok(void)
//{
// uint16_t length=0;
//
// // TODO expect get HID report descriptor
// hcd_edpt_open_IgnoreAndReturn( pipe_hdl );
//
// //------------- Code Under TEST -------------//
// TEST_ASSERT_EQUAL(TUSB_ERROR_NONE, hidh_open_subtask(dev_addr, p_kbd_interface_desc, &length) );
//
// TEST_ASSERT_EQUAL(sizeof(tusb_desc_interface_t) + sizeof(tusb_hid_descriptor_hid_t) + sizeof(tusb_desc_endpoint_t),
// length);
//}
void test_hidh_close(void)
{
keyboardh_data[dev_addr-1].pipe_hdl = pipe_hdl;
keyboardh_data[dev_addr-1].report_size = 8;
hcd_pipe_close_ExpectAndReturn(pipe_hdl, TUSB_ERROR_NONE);
tusbh_hid_keyboard_unmounted_cb_Expect(dev_addr);
//------------- Code Under TEST -------------//
hidh_close(dev_addr);
TEST_ASSERT_MEM_ZERO(&keyboardh_data[dev_addr-1], sizeof(hidh_interface_info_t));
}

View File

@ -1,85 +0,0 @@
/*
* The MIT License (MIT)
*
* Copyright (c) 2019 Ha Thach (tinyusb.org)
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
* This file is part of the TinyUSB stack.
*/
#include "stdlib.h"
#include "unity.h"
#include "type_helper.h"
#include "tusb_errors.h"
#include "common/common.h"
#include "hid_host.h"
#include "mock_osal.h"
#include "mock_cdc_host.h"
#include "mock_msc_host.h"
#include "mock_hub.h"
#include "mock_hcd.h"
#include "usbh.h"
#include "mock_hidh_callback.h"
#include "descriptor_test.h"
#include "host_helper.h"
extern hidh_interface_info_t mouseh_data[CFG_TUSB_HOST_DEVICE_MAX];
hidh_interface_info_t *p_hidh_mouse;
hid_mouse_report_t report;
tusb_desc_interface_t const *p_mouse_interface_desc = &desc_configuration.mouse_interface;
tusb_desc_endpoint_t const *p_mouse_endpoint_desc = &desc_configuration.mouse_endpoint;
uint8_t dev_addr;
void setUp(void)
{
helper_usbh_init_expect();
usbh_init();
dev_addr = RANDOM(CFG_TUSB_HOST_DEVICE_MAX)+1;
// uint16_t length;
// TEST_ASSERT_STATUS( hidh_open_subtask(dev_addr, p_mouse_interface_desc, &length) );
//
// p_hidh_mouse = &mouse_data[dev_addr-1];
//
// p_hidh_mouse->report_size = sizeof(hid_mouse_report_t);
// p_hidh_mouse->pipe_hdl = (pipe_handle_t) {
// .dev_addr = dev_addr,
// .xfer_type = TUSB_XFER_INTERRUPT,
// .index = 1
// };
}
void tearDown(void)
{
}
//void test_generic_init(void)
//{
// hidh_init();
//
// TEST_ASSERT_MEM_ZERO(mouse_data, sizeof(hidh_interface_info_t)*CFG_TUSB_HOST_DEVICE_MAX);
//}

View File

@ -1,216 +0,0 @@
/*
* The MIT License (MIT)
*
* Copyright (c) 2019 Ha Thach (tinyusb.org)
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
* This file is part of the TinyUSB stack.
*/
#include "stdlib.h"
#include "unity.h"
#include "type_helper.h"
#include "tusb_errors.h"
#include "common/common.h"
#include "hid_host.h"
#include "mock_osal.h"
#include "mock_usbh.h"
#include "mock_hcd.h"
#include "mock_hidh_callback.h"
#include "descriptor_test.h"
extern hidh_interface_info_t keyboardh_data[CFG_TUSB_HOST_DEVICE_MAX];
hid_keyboard_report_t sample_key[2] =
{
{
.modifier = KEYBOARD_MODIFIER_LEFTCTRL,
.keycode = {4}//{KEYBOARD_KEYCODE_a} TODO ascii to key code table
},
{
.modifier = KEYBOARD_MODIFIER_RIGHTALT,
.keycode = {5}//{KEYBOARD_KEYCODE_z}
}
};
uint8_t dev_addr;
hidh_interface_info_t *p_hidh_kbd;
hid_keyboard_report_t report;
tusb_desc_interface_t const *p_kbd_interface_desc = &desc_configuration.keyboard_interface;
tusb_desc_endpoint_t const *p_kdb_endpoint_desc = &desc_configuration.keyboard_endpoint;
void setUp(void)
{
hidh_init();
tu_memclr(&report, sizeof(hid_keyboard_report_t));
dev_addr = RANDOM(CFG_TUSB_HOST_DEVICE_MAX)+1;
p_hidh_kbd = &keyboardh_data[dev_addr-1];
p_hidh_kbd->report_size = sizeof(hid_keyboard_report_t);
p_hidh_kbd->pipe_hdl = (pipe_handle_t) {
.dev_addr = dev_addr,
.xfer_type = TUSB_XFER_INTERRUPT,
.index = 1
};
}
void tearDown(void)
{
}
void test_keyboard_init(void)
{
hidh_init();
TEST_ASSERT_MEM_ZERO(keyboardh_data, sizeof(hidh_interface_info_t)*CFG_TUSB_HOST_DEVICE_MAX);
}
//------------- is supported -------------//
void test_keyboard_is_supported_fail_unplug(void)
{
tusbh_device_get_state_IgnoreAndReturn(TUSB_DEVICE_STATE_UNPLUG);
TEST_ASSERT_FALSE( tusbh_hid_keyboard_is_mounted(dev_addr) );
}
void test_keyboard_is_supported_fail_not_opened(void)
{
hidh_init();
tusbh_device_get_state_IgnoreAndReturn(TUSB_DEVICE_STATE_CONFIGURED);
TEST_ASSERT_FALSE( tusbh_hid_keyboard_is_mounted(dev_addr) );
}
void test_keyboard_is_supported_ok(void)
{
tusbh_device_get_state_IgnoreAndReturn(TUSB_DEVICE_STATE_CONFIGURED);
TEST_ASSERT_TRUE( tusbh_hid_keyboard_is_mounted(dev_addr) );
}
tusb_error_t stub_set_idle_request(uint8_t address, tusb_control_request_t const* p_request, uint8_t* data, int num_call)
{
TEST_ASSERT_EQUAL( dev_addr, address);
//------------- expecting Set Idle with value = 0 -------------//
TEST_ASSERT_NOT_NULL( p_request );
TEST_ASSERT_EQUAL(TUSB_DIR_HOST_TO_DEV , p_request->bmRequestType_bit.direction);
TEST_ASSERT_EQUAL(TUSB_REQ_TYPE_CLASS , p_request->bmRequestType_bit.type);
TEST_ASSERT_EQUAL(TUSB_REQ_RECIPIENT_INTERFACE , p_request->bmRequestType_bit.recipient);
TEST_ASSERT_EQUAL(HID_REQ_CONTROL_SET_IDLE , p_request->bRequest);
TEST_ASSERT_EQUAL(0 , p_request->wValue);
TEST_ASSERT_EQUAL(p_kbd_interface_desc->bInterfaceNumber , p_request->wIndex);
TEST_ASSERT_NULL(data);
return TUSB_ERROR_NONE;
}
void test_keyboard_open_ok(void)
{
uint16_t length=0;
pipe_handle_t pipe_hdl = {.dev_addr = dev_addr, .xfer_type = TUSB_XFER_INTERRUPT, .index = 2};
hidh_init();
usbh_control_xfer_subtask_ExpectAndReturn(dev_addr, bm_request_type(TUSB_DIR_HOST_TO_DEV, TUSB_REQ_TYPE_CLASS, TUSB_REQ_RECIPIENT_INTERFACE),
HID_REQ_CONTROL_SET_IDLE, 0, p_kbd_interface_desc->bInterfaceNumber, 0, NULL,
TUSB_ERROR_NONE);
hcd_edpt_open_ExpectAndReturn(dev_addr, p_kdb_endpoint_desc, TUSB_CLASS_HID, pipe_hdl);
tusbh_hid_keyboard_mounted_cb_Expect(dev_addr);
//------------- Code Under TEST -------------//
TEST_ASSERT_EQUAL(TUSB_ERROR_NONE, hidh_open_subtask(dev_addr, p_kbd_interface_desc, &length));
TEST_ASSERT_PIPE_HANDLE(pipe_hdl, p_hidh_kbd->pipe_hdl);
TEST_ASSERT_EQUAL(8, p_hidh_kbd->report_size);
TEST_ASSERT_EQUAL(sizeof(tusb_desc_interface_t) + sizeof(tusb_hid_descriptor_hid_t) + sizeof(tusb_desc_endpoint_t),
length);
TEST_ASSERT_EQUAL(p_kbd_interface_desc->bInterfaceNumber, p_hidh_kbd->interface_number);
tusbh_device_get_state_IgnoreAndReturn(TUSB_DEVICE_STATE_CONFIGURED);
TEST_ASSERT_TRUE( tusbh_hid_keyboard_is_mounted(dev_addr) );
// TEST_ASSERT_FALSE( tusbh_hid_keyboard_is_busy(dev_addr) );
}
//--------------------------------------------------------------------+
// keyboard_get
//--------------------------------------------------------------------+
void test_keyboard_get_invalid_address(void)
{
tusbh_device_get_state_IgnoreAndReturn(TUSB_DEVICE_STATE_CONFIGURED);
TEST_ASSERT_EQUAL(TUSB_ERROR_INVALID_PARA, tusbh_hid_keyboard_get_report(0, NULL)); // invalid address
}
void test_keyboard_get_invalid_buffer(void)
{
tusbh_device_get_state_IgnoreAndReturn(TUSB_DEVICE_STATE_CONFIGURED);
TEST_ASSERT_EQUAL(TUSB_ERROR_INVALID_PARA, tusbh_hid_keyboard_get_report(dev_addr, NULL)); // invalid buffer
}
void test_keyboard_get_device_not_ready(void)
{
tusbh_device_get_state_IgnoreAndReturn(TUSB_DEVICE_STATE_UNPLUG);
TEST_ASSERT_EQUAL(TUSB_ERROR_DEVICE_NOT_READY, tusbh_hid_keyboard_get_report(dev_addr, &report)); // device not mounted
}
void test_keyboard_get_report_xfer_failed()
{
tusbh_device_get_state_IgnoreAndReturn(TUSB_DEVICE_STATE_CONFIGURED);
hcd_edpt_busy_ExpectAndReturn(p_hidh_kbd->pipe_hdl, false);
hcd_pipe_xfer_ExpectAndReturn(p_hidh_kbd->pipe_hdl, (uint8_t*) &report, p_hidh_kbd->report_size, true, TUSB_ERROR_INVALID_PARA);
//------------- Code Under TEST -------------//
TEST_ASSERT_EQUAL(TUSB_ERROR_INVALID_PARA, tusbh_hid_keyboard_get_report(dev_addr, &report));
}
void test_keyboard_get_report_xfer_failed_busy()
{
tusbh_device_get_state_IgnoreAndReturn(TUSB_DEVICE_STATE_CONFIGURED);
hcd_edpt_busy_ExpectAndReturn(p_hidh_kbd->pipe_hdl, true);
TEST_ASSERT_EQUAL(TUSB_ERROR_INTERFACE_IS_BUSY, tusbh_hid_keyboard_get_report(dev_addr, &report));
}
void test_keyboard_get_ok()
{
tusbh_device_get_state_IgnoreAndReturn(TUSB_DEVICE_STATE_CONFIGURED);
// TEST_ASSERT_EQUAL(TUSB_INTERFACE_STATUS_READY, tusbh_hid_keyboard_status(dev_addr));
hcd_edpt_busy_ExpectAndReturn(p_hidh_kbd->pipe_hdl, false);
hcd_pipe_xfer_ExpectAndReturn(p_hidh_kbd->pipe_hdl, (uint8_t*) &report, p_hidh_kbd->report_size, true, TUSB_ERROR_NONE);
//------------- Code Under TEST -------------//
TEST_ASSERT_EQUAL(TUSB_ERROR_NONE, tusbh_hid_keyboard_get_report(dev_addr, &report));
// TEST_ASSERT_EQUAL(TUSB_INTERFACE_STATUS_BUSY, tusbh_hid_keyboard_status(dev_addr));
}
void test_keyboard_isr_event_complete(void)
{
tusbh_hid_keyboard_isr_Expect(dev_addr, XFER_RESULT_SUCCESS);
//------------- Code Under TEST -------------//
hidh_isr(p_hidh_kbd->pipe_hdl, XFER_RESULT_SUCCESS, 8);
// tusbh_device_get_state_IgnoreAndReturn(TUSB_DEVICE_STATE_CONFIGURED);
// TEST_ASSERT_EQUAL(TUSB_INTERFACE_STATUS_COMPLETE, tusbh_hid_keyboard_status(dev_addr));
}

View File

@ -1,201 +0,0 @@
/*
* The MIT License (MIT)
*
* Copyright (c) 2019 Ha Thach (tinyusb.org)
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
* This file is part of the TinyUSB stack.
*/
#include "stdlib.h"
#include "unity.h"
#include "type_helper.h"
#include "tusb_errors.h"
#include "common/common.h"
#include "hid_host.h"
#include "mock_osal.h"
#include "mock_usbh.h"
#include "mock_hcd.h"
#include "mock_hidh_callback.h"
#include "descriptor_test.h"
extern hidh_interface_info_t mouseh_data[CFG_TUSB_HOST_DEVICE_MAX];
hidh_interface_info_t *p_hidh_mouse;
hid_mouse_report_t report;
tusb_desc_interface_t const *p_mouse_interface_desc = &desc_configuration.mouse_interface;
tusb_desc_endpoint_t const *p_mouse_endpoint_desc = &desc_configuration.mouse_endpoint;
uint8_t dev_addr;
void setUp(void)
{
hidh_init();
tu_memclr(&report, sizeof(hid_mouse_report_t));
dev_addr = RANDOM(CFG_TUSB_HOST_DEVICE_MAX)+1;
p_hidh_mouse = &mouseh_data[dev_addr-1];
p_hidh_mouse->report_size = sizeof(hid_mouse_report_t);
p_hidh_mouse->pipe_hdl = (pipe_handle_t) {
.dev_addr = dev_addr,
.xfer_type = TUSB_XFER_INTERRUPT,
.index = 1
};
}
void tearDown(void)
{
}
void test_mouse_init(void)
{
hidh_init();
TEST_ASSERT_MEM_ZERO(mouseh_data, sizeof(hidh_interface_info_t)*CFG_TUSB_HOST_DEVICE_MAX);
}
//------------- is supported -------------//
void test_mouse_is_supported_fail_unplug(void)
{
tusbh_device_get_state_IgnoreAndReturn(TUSB_DEVICE_STATE_UNPLUG);
TEST_ASSERT_FALSE( tusbh_hid_mouse_is_mounted(dev_addr) );
}
void test_mouse_is_supported_fail_not_opened(void)
{
hidh_init();
tusbh_device_get_state_IgnoreAndReturn(TUSB_DEVICE_STATE_CONFIGURED);
TEST_ASSERT_FALSE( tusbh_hid_mouse_is_mounted(dev_addr) );
}
void test_mouse_is_supported_ok(void)
{
tusbh_device_get_state_IgnoreAndReturn(TUSB_DEVICE_STATE_CONFIGURED);
TEST_ASSERT_TRUE( tusbh_hid_mouse_is_mounted(dev_addr) );
}
void test_mouse_open_ok(void)
{
uint16_t length=0;
pipe_handle_t pipe_hdl = {.dev_addr = dev_addr, .xfer_type = TUSB_XFER_INTERRUPT, .index = 2};
hidh_init();
usbh_control_xfer_subtask_ExpectAndReturn(dev_addr, bm_request_type(TUSB_DIR_HOST_TO_DEV, TUSB_REQ_TYPE_CLASS, TUSB_REQ_RECIPIENT_INTERFACE),
HID_REQ_CONTROL_SET_IDLE, 0, p_mouse_interface_desc->bInterfaceNumber, 0, NULL,
TUSB_ERROR_NONE);
hcd_edpt_open_ExpectAndReturn(dev_addr, p_mouse_endpoint_desc, TUSB_CLASS_HID, pipe_hdl);
tusbh_hid_mouse_mounted_cb_Expect(dev_addr);
//------------- Code Under TEST -------------//
TEST_ASSERT_STATUS( hidh_open_subtask(dev_addr, p_mouse_interface_desc, &length));
TEST_ASSERT_PIPE_HANDLE(pipe_hdl, p_hidh_mouse->pipe_hdl);
TEST_ASSERT_EQUAL(8, p_hidh_mouse->report_size);
TEST_ASSERT_EQUAL(sizeof(tusb_desc_interface_t) + sizeof(tusb_hid_descriptor_hid_t) + sizeof(tusb_desc_endpoint_t),
length);
TEST_ASSERT_EQUAL(p_mouse_interface_desc->bInterfaceNumber, p_hidh_mouse->interface_number);
tusbh_device_get_state_IgnoreAndReturn(TUSB_DEVICE_STATE_CONFIGURED);
TEST_ASSERT_TRUE( tusbh_hid_mouse_is_mounted(dev_addr) );
// TEST_ASSERT_FALSE( tusbh_hid_mouse_is_busy(dev_addr) );
}
//--------------------------------------------------------------------+
// mouse_get
//--------------------------------------------------------------------+
void test_mouse_get_invalid_address(void)
{
tusbh_device_get_state_IgnoreAndReturn(TUSB_DEVICE_STATE_CONFIGURED);
TEST_ASSERT_EQUAL(TUSB_ERROR_INVALID_PARA, tusbh_hid_mouse_get_report(0, NULL)); // invalid address
}
void test_mouse_get_invalid_buffer(void)
{
tusbh_device_get_state_IgnoreAndReturn(TUSB_DEVICE_STATE_CONFIGURED);
TEST_ASSERT_EQUAL(TUSB_ERROR_INVALID_PARA, tusbh_hid_mouse_get_report(dev_addr, NULL)); // invalid buffer
}
void test_mouse_get_device_not_ready(void)
{
tusbh_device_get_state_IgnoreAndReturn(TUSB_DEVICE_STATE_UNPLUG);
TEST_ASSERT_EQUAL(TUSB_ERROR_DEVICE_NOT_READY, tusbh_hid_mouse_get_report(dev_addr, &report)); // device not mounted
}
void test_mouse_get_report_xfer_failed()
{
tusbh_device_get_state_IgnoreAndReturn(TUSB_DEVICE_STATE_CONFIGURED);
hcd_edpt_busy_ExpectAndReturn(p_hidh_mouse->pipe_hdl, false);
hcd_pipe_xfer_ExpectAndReturn(p_hidh_mouse->pipe_hdl, (uint8_t*) &report, p_hidh_mouse->report_size, true, TUSB_ERROR_INVALID_PARA);
//------------- Code Under TEST -------------//
TEST_ASSERT_EQUAL(TUSB_ERROR_INVALID_PARA, tusbh_hid_mouse_get_report(dev_addr, &report));
}
void test_mouse_get_report_xfer_failed_busy()
{
tusbh_device_get_state_IgnoreAndReturn(TUSB_DEVICE_STATE_CONFIGURED);
hcd_edpt_busy_ExpectAndReturn(p_hidh_mouse->pipe_hdl, true);
TEST_ASSERT_EQUAL(TUSB_ERROR_INTERFACE_IS_BUSY, tusbh_hid_mouse_get_report(dev_addr, &report));
}
void test_mouse_get_ok()
{
tusbh_device_get_state_IgnoreAndReturn(TUSB_DEVICE_STATE_CONFIGURED);
// TEST_ASSERT_EQUAL(TUSB_INTERFACE_STATUS_READY, tusbh_hid_mouse_status(dev_addr));
hcd_edpt_busy_ExpectAndReturn(p_hidh_mouse->pipe_hdl, false);
hcd_pipe_xfer_ExpectAndReturn(p_hidh_mouse->pipe_hdl, (uint8_t*) &report, p_hidh_mouse->report_size, true, TUSB_ERROR_NONE);
//------------- Code Under TEST -------------//
TEST_ASSERT_STATUS( tusbh_hid_mouse_get_report(dev_addr, &report));
// TEST_ASSERT_EQUAL(TUSB_INTERFACE_STATUS_BUSY, tusbh_hid_mouse_status(dev_addr));
}
void test_mouse_isr_event_xfer_complete(void)
{
tusbh_hid_mouse_isr_Expect(dev_addr, XFER_RESULT_SUCCESS);
//------------- Code Under TEST -------------//
hidh_isr(p_hidh_mouse->pipe_hdl, XFER_RESULT_SUCCESS, 8);
tusbh_device_get_state_IgnoreAndReturn(TUSB_DEVICE_STATE_CONFIGURED);
// TEST_ASSERT_EQUAL(TUSB_INTERFACE_STATUS_COMPLETE, tusbh_hid_mouse_status(dev_addr));
}
void test_mouse_isr_event_xfer_error(void)
{
tusbh_hid_mouse_isr_Expect(dev_addr, XFER_RESULT_FAILED);
//------------- Code Under TEST -------------//
hidh_isr(p_hidh_mouse->pipe_hdl, XFER_RESULT_FAILED, 0);
tusbh_device_get_state_IgnoreAndReturn(TUSB_DEVICE_STATE_CONFIGURED);
// TEST_ASSERT_EQUAL(TUSB_INTERFACE_STATUS_ERROR, tusbh_hid_mouse_status(dev_addr));
}

View File

@ -1,71 +0,0 @@
/*
* The MIT License (MIT)
*
* Copyright (c) 2019 Ha Thach (tinyusb.org)
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
* This file is part of the TinyUSB stack.
*/
#include "common/common.h"
#include "host/usbh.h"
#include "host/usbh_hcd.h"
static inline void helper_class_init_expect(void)
{ // class code number order
#if CFG_TUH_CDC
cdch_init_Expect();
#endif
#if HOST_CLASS_HID
hidh_init_Expect();
#endif
#if CFG_TUH_MSC
msch_init_Expect();
#endif
//TODO update more classes
}
static inline void helper_usbh_init_expect(void)
{
osal_queue_create_IgnoreAndReturn( (osal_queue_handle_t) 0x4566 );
osal_task_create_IgnoreAndReturn(TUSB_ERROR_NONE);
osal_semaphore_create_IgnoreAndReturn( (osal_semaphore_handle_t) 0x1234);
osal_mutex_create_IgnoreAndReturn((osal_mutex_handle_t) 0x789a);
}
static inline void helper_usbh_device_emulate(uint8_t dev_addr, uint8_t hub_addr, uint8_t hub_port, uint8_t hostid, tusb_speed_t speed)
{
_usbh_devices[dev_addr].rhport = hostid;
_usbh_devices[dev_addr].hub_addr = hub_addr;
_usbh_devices[dev_addr].hub_port = hub_port;
_usbh_devices[dev_addr].speed = speed;
_usbh_devices[dev_addr].state = dev_addr ? TUSB_DEVICE_STATE_CONFIGURED : TUSB_DEVICE_STATE_UNPLUG;
}

View File

@ -1,40 +0,0 @@
/*
* The MIT License (MIT)
*
* Copyright (c) 2019 Ha Thach (tinyusb.org)
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
* This file is part of the TinyUSB stack.
*/
#include "unity.h"
void setUp(void)
{
}
void tearDown(void)
{
}
void test_()
{
// TEST_IGNORE();
}

View File

@ -1,120 +0,0 @@
/*
* The MIT License (MIT)
*
* Copyright (c) 2019 Ha Thach (tinyusb.org)
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
* This file is part of the TinyUSB stack.
*/
//#include "stdlib.h"
//#include "unity.h"
//#include "type_helper.h"
//#include "tusb_option.h"
//#include "tusb_errors.h"
//
//#include "mock_osal.h"
//#include "hcd.h"
//#include "usbh.h"
//#include "tusb.h"
//#include "hid_host.h"
////#include "ehci_controller_fake.h"
//
//#include "descriptor_test.h"
//
//uint8_t dev_addr;
//uint8_t hostid;
//
void setUp(void)
{
// dev_addr = RANDOM(CFG_TUSB_HOST_DEVICE_MAX)+1;
// hostid = RANDOM(CONTROLLER_HOST_NUMBER) + TEST_CONTROLLER_HOST_START_INDEX;
//
//// ehci_controller_init();
// tusb_init();
//
}
//
void tearDown(void)
{
}
//
//osal_semaphore_handle_t sem_create_stub(osal_semaphore_t * const sem, int num_call)
//{
// (*p_sem) = 0;
// return (osal_semaphore_handle_t) p_sem;
//}
//void sem_wait_stub(osal_semaphore_handle_t const sem_hdl, uint32_t msec, tusb_error_t *p_error, int num_call)
//{
//
//}
//tusb_error_t sem_post_stub(osal_semaphore_handle_t const sem_hdl, int num_call)
//{
// (*sem_hdl)++;
//
// return TUSB_ERROR_NONE;
//}
//void sem_reset_stub(osal_semaphore_handle_t const sem_hdl, int num_call)
//{
// (*sem_hdl) = 0;
//}
//
//osal_queue_handle_t queue_create_stub (osal_queue_t *p_queue, int num_call)
//{
// p_queue->count = p_queue->wr_idx = p_queue->rd_idx = 0;
// return (osal_queue_handle_t) p_queue;
//}
//void queue_receive_stub (osal_queue_handle_t const queue_hdl, uint32_t *p_data, uint32_t msec, tusb_error_t *p_error, int num_call)
//{
//
//}
//tusb_error_t queue_send_stub (osal_queue_handle_t const queue_hdl, uint32_t data, int num_call)
//{
// //TODO mutex lock hal_interrupt_disable
//
// queue_hdl->buffer[queue_hdl->wr_idx] = data;
// queue_hdl->wr_idx = (queue_hdl->wr_idx + 1) % queue_hdl->depth;
//
// if (queue_hdl->depth == queue_hdl->count) // queue is full, 1st rd is overwritten
// {
// queue_hdl->rd_idx = queue_hdl->wr_idx; // keep full state
// }else
// {
// queue_hdl->count++;
// }
//
// //TODO mutex unlock hal_interrupt_enable
//
// return TUSB_ERROR_NONE;
//}
//void queue_flush_stub(osal_queue_handle_t const queue_hdl, int num_call)
//{
// queue_hdl->count = queue_hdl->rd_idx = queue_hdl->wr_idx = 0;
//}
//
//void test_(void)
//{
// ehci_controller_device_plug(hostid, TUSB_SPEED_HIGH);
//
// tusb_task_runner(); // get 8-byte descriptor
// ehci_controller_control_xfer_proceed(0, &desc_device);
//
// tusb_task_runner(); // get 8-byte descriptor
//}

View File

@ -1,54 +0,0 @@
/*
* The MIT License (MIT)
*
* Copyright (c) 2019 Ha Thach (tinyusb.org)
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
* This file is part of the TinyUSB stack.
*/
/** \ingroup TBD
* \defgroup TBD
* \brief TBD
*
* @{
*/
#ifndef _TUSB_MSCH_CALLBACK_H_
#define _TUSB_MSCH_CALLBACK_H_
#ifdef __cplusplus
extern "C" {
#endif
#include "common/common.h"
void tusbh_msc_mounted_cb(uint8_t dev_addr);
void tusbh_msc_unmounted_cb(uint8_t dev_addr);
void tusbh_msc_isr(uint8_t dev_addr, xfer_result_t event, uint32_t xferred_bytes);
#ifdef __cplusplus
}
#endif
#endif /* _TUSB_MSCH_CALLBACK_H_ */
/** @} */

View File

@ -1,139 +0,0 @@
/*
* The MIT License (MIT)
*
* Copyright (c) 2019 Ha Thach (tinyusb.org)
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
* This file is part of the TinyUSB stack.
*/
#include "stdlib.h"
#include "unity.h"
#include "tusb_option.h"
#include "tusb_errors.h"
#include "binary.h"
#include "type_helper.h"
#include "descriptor_test.h"
#include "mock_osal.h"
#include "mock_hcd.h"
#include "mock_usbh.h"
#include "mock_msch_callback.h"
#include "msc_host.h"
extern msch_interface_t msch_data[CFG_TUSB_HOST_DEVICE_MAX];
static tusb_desc_interface_t const *p_msc_interface_desc = &desc_configuration.msc_interface;
static tusb_desc_endpoint_t const *p_edp_in = &desc_configuration.msc_endpoint_in;
static tusb_desc_endpoint_t const *p_edp_out = &desc_configuration.msc_endpoint_out;
static msch_interface_t* p_msc;
static uint8_t dev_addr;
static pipe_handle_t pipe_in, pipe_out;
static pipe_handle_t const pipe_null = { 0 };
static uint16_t length;
void setUp(void)
{
dev_addr = RANDOM(CFG_TUSB_HOST_DEVICE_MAX)+1;
osal_semaphore_create_IgnoreAndReturn( (osal_semaphore_handle_t) 0x1234);
msch_init();
TEST_ASSERT_MEM_ZERO(msch_data, sizeof(msch_interface_t)*CFG_TUSB_HOST_DEVICE_MAX);
p_msc = &msch_data[dev_addr-1];
pipe_in = (pipe_handle_t) {.dev_addr = dev_addr, .xfer_type = TUSB_XFER_BULK, .index = 1};
pipe_out = (pipe_handle_t) {.dev_addr = dev_addr, .xfer_type = TUSB_XFER_BULK, .index = 2};
}
void tearDown(void)
{
length = 0;
}
void test_open_pipe_in_failed(void)
{
hcd_edpt_open_ExpectAndReturn(dev_addr, p_edp_in, TUSB_CLASS_MSC, pipe_null);
TEST_ASSERT(TUSB_ERROR_NONE != msch_open(dev_addr, p_msc_interface_desc, &length));
}
void test_open_pipe_out_failed(void)
{
hcd_edpt_open_ExpectAndReturn(dev_addr, p_edp_in, TUSB_CLASS_MSC, (pipe_handle_t) {1} );
hcd_edpt_open_ExpectAndReturn(dev_addr, p_edp_out, TUSB_CLASS_MSC, pipe_null);
TEST_ASSERT(TUSB_ERROR_NONE != msch_open(dev_addr, p_msc_interface_desc, &length));
}
tusb_error_t stub_control_xfer(uint8_t dev_addr, uint8_t bmRequestType, uint8_t bRequest,
uint16_t wValue, uint16_t wIndex, uint16_t wLength, uint8_t* data, int num_call)
{
switch ( num_call )
{
case 0: // get max lun
TEST_ASSERT_EQUAL(bm_request_type(TUSB_DIR_DEV_TO_HOST, TUSB_REQ_TYPE_CLASS, TUSB_REQ_RECIPIENT_INTERFACE),
bmRequestType);
TEST_ASSERT_EQUAL(MSC_REQ_GET_MAX_LUN, bRequest);
TEST_ASSERT_EQUAL(p_msc_interface_desc->bInterfaceNumber, wIndex);
TEST_ASSERT_EQUAL(1, wLength);
*data = 1; // TODO multiple LUN support
break;
default:
TEST_FAIL();
return TUSB_ERROR_FAILED;
}
return TUSB_ERROR_NONE;
}
#if 0 // TODO TEST enable this
void test_open_desc_length(void)
{
hcd_edpt_open_ExpectAndReturn(dev_addr, p_edp_in, TUSB_CLASS_MSC, pipe_in);
hcd_edpt_open_ExpectAndReturn(dev_addr, p_edp_out, TUSB_CLASS_MSC, pipe_out);
usbh_control_xfer_subtask_IgnoreAndReturn(TUSB_ERROR_NONE);
hcd_pipe_xfer_IgnoreAndReturn(TUSB_ERROR_NONE);
hcd_pipe_queue_xfer_IgnoreAndReturn(TUSB_ERROR_NONE);
//------------- Code Under Test -------------//
TEST_ASSERT_STATUS( msch_open(dev_addr, p_msc_interface_desc, &length) );
TEST_ASSERT_EQUAL(sizeof(tusb_desc_interface_t) + 2*sizeof(tusb_desc_endpoint_t),
length);
}
void test_open_ok(void)
{
hcd_edpt_open_ExpectAndReturn(dev_addr, p_edp_in, TUSB_CLASS_MSC, pipe_in);
hcd_edpt_open_ExpectAndReturn(dev_addr, p_edp_out, TUSB_CLASS_MSC, pipe_out);
//------------- get max lun -------------//
usbh_control_xfer_subtask_StubWithCallback(stub_control_xfer);
//------------- Code Under Test -------------//
TEST_ASSERT_STATUS( msch_open(dev_addr, p_msc_interface_desc, &length) );
TEST_ASSERT_EQUAL(p_msc_interface_desc->bInterfaceNumber, p_msc->interface_number);
}
#endif

View File

@ -1,327 +0,0 @@
/*
* The MIT License (MIT)
*
* Copyright (c) 2019 Ha Thach (tinyusb.org)
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
* This file is part of the TinyUSB stack.
*/
#include "unity.h"
#include "tusb_errors.h"
#include "descriptor_test.h"
#include "mock_osal.h"
#include "usbh.h"
#include "mock_hcd.h"
#include "mock_hub.h"
#include "usbh_hcd.h"
#include "mock_tusb_callback.h"
#include "mock_hid_host.h"
#include "mock_cdc_host.h"
#include "mock_msc_host.h"
extern usbh_device_t _usbh_devices[CFG_TUSB_HOST_DEVICE_MAX+1];
extern uint8_t enum_data_buffer[CFG_TUSB_HOST_ENUM_BUFFER_SIZE];
usbh_enumerate_t const enum_connect = {
.rhport = 0,
.hub_addr = 0,
.hub_port = 0,
};
tusb_speed_t device_speed = TUSB_SPEED_FULL;
void queue_recv_stub (osal_queue_handle_t const queue_hdl, uint32_t *p_data, uint32_t msec, tusb_error_t *p_error, int num_call);
void semaphore_wait_success_stub(osal_semaphore_handle_t const sem_hdl, uint32_t msec, tusb_error_t *p_error, int num_call);
tusb_error_t control_xfer_stub(uint8_t dev_addr, const tusb_control_request_t * const p_request, uint8_t data[], int num_call);
enum {
POWER_STABLE_DELAY = 500,
RESET_DELAY = 200 // USB specs say only 50ms though many devices requires a longer time
};
void setUp(void)
{
tu_memclr(_usbh_devices, sizeof(usbh_device_t)*(CFG_TUSB_HOST_DEVICE_MAX+1));
osal_queue_receive_StubWithCallback(queue_recv_stub);
osal_semaphore_wait_StubWithCallback(semaphore_wait_success_stub);
osal_semaphore_post_IgnoreAndReturn(TUSB_ERROR_NONE);
osal_mutex_wait_StubWithCallback(semaphore_wait_success_stub);
osal_mutex_release_IgnoreAndReturn(TUSB_ERROR_NONE);
hcd_pipe_control_xfer_StubWithCallback(control_xfer_stub);
hcd_port_connect_status_ExpectAndReturn(enum_connect.rhport, true);
osal_task_delay_Expect(POWER_STABLE_DELAY);
hcd_port_connect_status_ExpectAndReturn(enum_connect.rhport, true);
hcd_port_reset_Expect(enum_connect.rhport);
osal_task_delay_Expect(RESET_DELAY);
hcd_port_speed_get_ExpectAndReturn(enum_connect.rhport, device_speed);
osal_semaphore_reset_Expect( _usbh_devices[0].control.sem_hdl );
osal_mutex_reset_Expect( _usbh_devices[0].control.mutex_hdl );
hcd_pipe_control_open_ExpectAndReturn(0, 8, TUSB_ERROR_NONE);
}
void tearDown(void)
{
}
//--------------------------------------------------------------------+
// STUB & HELPER
//--------------------------------------------------------------------+
void queue_recv_stub (osal_queue_handle_t const queue_hdl, uint32_t *p_data, uint32_t msec, tusb_error_t *p_error, int num_call)
{
(*p_data) = ( *((uint32_t*) &enum_connect) );
(*p_error) = TUSB_ERROR_NONE;
}
void semaphore_wait_success_stub(osal_semaphore_handle_t const sem_hdl, uint32_t msec, tusb_error_t *p_error, int num_call)
{
(*p_error) = TUSB_ERROR_NONE;
}
#define semaphore_wait_timeout_stub(n) semaphore_wait_timeout_##n
#define semaphore_wait_timeout(n) \
void semaphore_wait_timeout_##n(osal_semaphore_handle_t const sem_hdl, uint32_t msec, tusb_error_t *p_error, int num_call) {\
if (num_call >= n)\
(*p_error) = TUSB_ERROR_OSAL_TIMEOUT;\
else \
(*p_error) = TUSB_ERROR_NONE;\
}
semaphore_wait_timeout(0)
semaphore_wait_timeout(1)
semaphore_wait_timeout(2)
semaphore_wait_timeout(3)
semaphore_wait_timeout(4)
semaphore_wait_timeout(5)
semaphore_wait_timeout(6)
semaphore_wait_timeout(7)
semaphore_wait_timeout(8)
tusb_error_t control_xfer_stub(uint8_t dev_addr, const tusb_control_request_t * const p_request, uint8_t data[], int num_call)
{
switch (num_call)
{
case 0: // get 8 bytes of device descriptor
TEST_ASSERT_EQUAL(TUSB_REQ_GET_DESCRIPTOR, p_request->bRequest);
TEST_ASSERT_EQUAL(TUSB_DESC_TYPE_DEVICE, p_request->wValue >> 8);
TEST_ASSERT_EQUAL(8, p_request->wLength);
memcpy(data, &desc_device, p_request->wLength);
break;
case 1: // set device address
TEST_ASSERT_EQUAL(TUSB_REQ_SET_ADDRESS, p_request->bRequest);
TEST_ASSERT_EQUAL(p_request->wValue, 1);
break;
case 2: // get full device decriptor for new address
TEST_ASSERT_EQUAL(TUSB_REQ_GET_DESCRIPTOR, p_request->bRequest);
TEST_ASSERT_EQUAL(TUSB_DESC_TYPE_DEVICE, p_request->wValue >> 8);
TEST_ASSERT_EQUAL(18, p_request->wLength);
memcpy(data, &desc_device, p_request->wLength);
break;
case 3: // get 9 bytes of configuration descriptor
TEST_ASSERT_EQUAL(TUSB_REQ_GET_DESCRIPTOR, p_request->bRequest);
TEST_ASSERT_EQUAL(TUSB_DESC_TYPE_CONFIGURATION, p_request->wValue >> 8);
TEST_ASSERT_EQUAL(9, p_request->wLength);
memcpy(data, &desc_configuration, p_request->wLength);
break;
case 4: // get full-length configuration descriptor
TEST_ASSERT_EQUAL(TUSB_REQ_GET_DESCRIPTOR, p_request->bRequest);
TEST_ASSERT_EQUAL(TUSB_DESC_TYPE_CONFIGURATION, p_request->wValue >> 8);
TEST_ASSERT_EQUAL(CFG_TUSB_HOST_ENUM_BUFFER_SIZE, p_request->wLength);
memcpy(data, &desc_configuration, p_request->wLength);
break;
case 5: // set configure
TEST_ASSERT_EQUAL(TUSB_REQ_SET_CONFIGURATION, p_request->bRequest);
TEST_ASSERT_EQUAL(1, p_request->wValue);
TEST_ASSERT_EQUAL(0, p_request->wIndex);
TEST_ASSERT_EQUAL(0, p_request->wLength);
break;
default:
return TUSB_ERROR_OSAL_TIMEOUT;
}
hcd_event_xfer_complete(
(pipe_handle_t) { .dev_addr = (num_call > 1 ? 1 : 0), .xfer_type = TUSB_XFER_CONTROL },
0, XFER_RESULT_SUCCESS, 0);
return TUSB_ERROR_NONE;
}
tusb_error_t stub_hidh_open(uint8_t dev_addr, tusb_desc_interface_t const *descriptor, uint16_t *p_length, int num_call)
{
*p_length = sizeof(tusb_desc_interface_t) + sizeof(tusb_hid_descriptor_hid_t) + sizeof(tusb_desc_endpoint_t);
return TUSB_ERROR_NONE;
}
tusb_error_t stub_msch_open(uint8_t dev_addr, tusb_desc_interface_t const *descriptor, uint16_t *p_length, int num_call)
{
*p_length = sizeof(tusb_desc_interface_t) + 2*sizeof(tusb_desc_endpoint_t);
return TUSB_ERROR_NONE;
}
tusb_error_t stub_cdch_open(uint8_t dev_addr, tusb_desc_interface_t const *descriptor, uint16_t *p_length, int num_call)
{
*p_length =
//------------- Comm Interface -------------//
sizeof(tusb_desc_interface_t) + sizeof(cdc_desc_func_header_t) +
sizeof(cdc_desc_func_acm_t) + sizeof(cdc_desc_func_union_t) +
sizeof(tusb_desc_endpoint_t) +
//------------- Data Interface -------------//
sizeof(tusb_desc_interface_t) + 2*sizeof(tusb_desc_endpoint_t);
return TUSB_ERROR_NONE;
}
//--------------------------------------------------------------------+
// enumeration
//--------------------------------------------------------------------+
void test_addr0_failed_dev_desc(void)
{
osal_semaphore_wait_StubWithCallback(semaphore_wait_timeout_stub(0));
// tusbh_device_mount_failed_cb_Expect(TUSB_ERROR_USBH_MOUNT_DEVICE_NOT_RESPOND, NULL);
usbh_enumeration_task(NULL);
TEST_ASSERT_EQUAL(TUSB_DEVICE_STATE_ADDRESSED, _usbh_devices[0].state);
}
void test_addr0_failed_set_address(void)
{
osal_semaphore_wait_StubWithCallback(semaphore_wait_timeout_stub(1));
hcd_port_reset_Expect( _usbh_devices[0].rhport );
osal_task_delay_Expect(RESET_DELAY);
// tusbh_device_mount_failed_cb_Expect(TUSB_ERROR_USBH_MOUNT_DEVICE_NOT_RESPOND, NULL);
usbh_enumeration_task(NULL);
TEST_ASSERT_EQUAL(TUSB_DEVICE_STATE_ADDRESSED, _usbh_devices[0].state);
TEST_ASSERT_EQUAL_MEMORY(&desc_device, enum_data_buffer, 8);
}
void test_enum_failed_get_full_dev_desc(void)
{
osal_semaphore_wait_StubWithCallback(semaphore_wait_timeout_stub(2));
hcd_port_reset_Expect( _usbh_devices[0].rhport );
osal_task_delay_Expect(RESET_DELAY);
hcd_pipe_control_close_ExpectAndReturn(0, TUSB_ERROR_NONE);
osal_semaphore_reset_Expect( _usbh_devices[0].control.sem_hdl );
osal_mutex_reset_Expect( _usbh_devices[0].control.mutex_hdl );
hcd_pipe_control_open_ExpectAndReturn(1, desc_device.bMaxPacketSize0, TUSB_ERROR_NONE);
// tusbh_device_mount_failed_cb_Expect(TUSB_ERROR_USBH_MOUNT_DEVICE_NOT_RESPOND, NULL);
usbh_enumeration_task(NULL);
TEST_ASSERT_EQUAL(TUSB_DEVICE_STATE_UNPLUG, _usbh_devices[0].state);
TEST_ASSERT_EQUAL(TUSB_DEVICE_STATE_ADDRESSED, _usbh_devices[1].state);
TEST_ASSERT_EQUAL(TUSB_SPEED_FULL, _usbh_devices[1].speed);
TEST_ASSERT_EQUAL(enum_connect.rhport, _usbh_devices[1].rhport);
TEST_ASSERT_EQUAL(enum_connect.hub_addr, _usbh_devices[1].hub_addr);
TEST_ASSERT_EQUAL(enum_connect.hub_port, _usbh_devices[1].hub_port);
}
void test_enum_failed_get_9byte_config_desc(void)
{
osal_semaphore_wait_StubWithCallback(semaphore_wait_timeout_stub(3));
hcd_port_reset_Expect( _usbh_devices[0].rhport );
osal_task_delay_Expect(RESET_DELAY);
hcd_pipe_control_close_ExpectAndReturn(0, TUSB_ERROR_NONE);
osal_semaphore_reset_Expect( _usbh_devices[0].control.sem_hdl );
osal_mutex_reset_Expect( _usbh_devices[0].control.mutex_hdl );
hcd_pipe_control_open_ExpectAndReturn(1, desc_device.bMaxPacketSize0, TUSB_ERROR_NONE);
tusbh_device_attached_cb_ExpectAndReturn((tusb_desc_device_t*) enum_data_buffer, 1);
// tusbh_device_mount_failed_cb_Expect(TUSB_ERROR_USBH_MOUNT_DEVICE_NOT_RESPOND, NULL);
usbh_enumeration_task(NULL);
TEST_ASSERT_EQUAL(desc_device.idVendor, _usbh_devices[1].vendor_id);
TEST_ASSERT_EQUAL(desc_device.idProduct, _usbh_devices[1].product_id);
TEST_ASSERT_EQUAL(desc_device.bNumConfigurations, _usbh_devices[1].configure_count);
}
void test_enum_failed_get_full_config_desc(void)
{
osal_semaphore_wait_StubWithCallback(semaphore_wait_timeout_stub(4));
hcd_port_reset_Expect( _usbh_devices[0].rhport );
osal_task_delay_Expect(RESET_DELAY);
hcd_pipe_control_close_ExpectAndReturn(0, TUSB_ERROR_NONE);
osal_semaphore_reset_Expect( _usbh_devices[0].control.sem_hdl );
osal_mutex_reset_Expect( _usbh_devices[0].control.mutex_hdl );
hcd_pipe_control_open_ExpectAndReturn(1, desc_device.bMaxPacketSize0, TUSB_ERROR_NONE);
tusbh_device_attached_cb_ExpectAndReturn((tusb_desc_device_t*) enum_data_buffer, 1);
// tusbh_device_mount_failed_cb_Expect(TUSB_ERROR_USBH_MOUNT_DEVICE_NOT_RESPOND, NULL);
usbh_enumeration_task(NULL);
}
void test_enum_parse_config_desc(void)
{
osal_semaphore_wait_StubWithCallback(semaphore_wait_timeout_stub(5));
hcd_port_reset_Expect( _usbh_devices[0].rhport );
osal_task_delay_Expect(RESET_DELAY);
hcd_pipe_control_close_ExpectAndReturn(0, TUSB_ERROR_NONE);
osal_semaphore_reset_Expect( _usbh_devices[0].control.sem_hdl );
osal_mutex_reset_Expect( _usbh_devices[0].control.mutex_hdl );
hcd_pipe_control_open_ExpectAndReturn(1, desc_device.bMaxPacketSize0, TUSB_ERROR_NONE);
tusbh_device_attached_cb_ExpectAndReturn((tusb_desc_device_t*) enum_data_buffer, 1);
// tusbh_device_mount_failed_cb_Expect(TUSB_ERROR_USBH_MOUNT_DEVICE_NOT_RESPOND, NULL); // fail to set configure
usbh_enumeration_task(NULL);
TEST_ASSERT_EQUAL(desc_configuration.configuration.bNumInterfaces, _usbh_devices[1].interface_count);
}
void test_enum_set_configure(void)
{
osal_semaphore_wait_StubWithCallback(semaphore_wait_timeout_stub(6));
hcd_port_reset_Expect( _usbh_devices[0].rhport );
osal_task_delay_Expect(RESET_DELAY);
hcd_pipe_control_close_ExpectAndReturn(0, TUSB_ERROR_NONE);
osal_semaphore_reset_Expect( _usbh_devices[0].control.sem_hdl );
osal_mutex_reset_Expect( _usbh_devices[0].control.mutex_hdl );
hcd_pipe_control_open_ExpectAndReturn(1, desc_device.bMaxPacketSize0, TUSB_ERROR_NONE);
tusbh_device_attached_cb_ExpectAndReturn((tusb_desc_device_t*) enum_data_buffer, 1);
// class open TODO more class expect
hidh_open_subtask_StubWithCallback(stub_hidh_open);
msch_open_subtask_StubWithCallback(stub_msch_open);
cdch_open_subtask_StubWithCallback(stub_cdch_open);
tusbh_device_mount_succeed_cb_Expect(1);
usbh_enumeration_task(NULL);
TEST_ASSERT_EQUAL( TU_BIT(TUSB_CLASS_HID) | TU_BIT(TUSB_CLASS_MSC) | TU_BIT(TUSB_CLASS_CDC),
_usbh_devices[1].flag_supported_class); // TODO change later
}

View File

@ -1,241 +0,0 @@
/*
* The MIT License (MIT)
*
* Copyright (c) 2019 Ha Thach (tinyusb.org)
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
* This file is part of the TinyUSB stack.
*/
#include <stdlib.h>
#include "unity.h"
#include "tusb_errors.h"
#include "type_helper.h"
#include "mock_osal.h"
#include "usbh.h"
#include "mock_hub.h"
#include "usbh_hcd.h"
#include "mock_hcd.h"
#include "mock_tusb_callback.h"
#include "mock_hid_host.h"
#include "mock_cdc_host.h"
#include "mock_msc_host.h"
#include "host_helper.h"
uint8_t dev_addr;
void setUp(void)
{
dev_addr = RANDOM(CFG_TUSB_HOST_DEVICE_MAX)+1;
}
void tearDown(void)
{
}
//--------------------------------------------------------------------+
// get_status
//--------------------------------------------------------------------+
void test_usbh_status_get_fail(void)
{
_usbh_devices[dev_addr].state = 0;
TEST_ASSERT_EQUAL( TUSB_DEVICE_STATE_INVALID_PARAMETER, tusbh_device_get_state(CFG_TUSB_HOST_DEVICE_MAX+1) );
TEST_ASSERT_EQUAL( TUSB_DEVICE_STATE_UNPLUG, tusbh_device_get_state(dev_addr) );
}
void test_usbh_status_get_succeed(void)
{
_usbh_devices[dev_addr].state = TUSB_DEVICE_STATE_CONFIGURED;
TEST_ASSERT_EQUAL( TUSB_DEVICE_STATE_CONFIGURED, tusbh_device_get_state(dev_addr) );
}
//--------------------------------------------------------------------+
// Init
//--------------------------------------------------------------------+
void test_usbh_init_hcd_failed(void)
{
hcd_init_IgnoreAndReturn(TUSB_ERROR_HCD_FAILED);
TEST_ASSERT_EQUAL(TUSB_ERROR_HCD_FAILED, usbh_init());
}
void test_usbh_init_enum_queue_create_failed(void)
{
hcd_init_ExpectAndReturn(TUSB_ERROR_NONE);
osal_queue_create_IgnoreAndReturn(NULL);
TEST_ASSERT_EQUAL(TUSB_ERROR_OSAL_QUEUE_FAILED, usbh_init());
}
void test_usbh_init_enum_task_create_failed(void)
{
hcd_init_ExpectAndReturn(TUSB_ERROR_NONE);
osal_queue_create_IgnoreAndReturn((osal_queue_handle_t) 0x1234);
osal_task_create_IgnoreAndReturn(TUSB_ERROR_OSAL_TASK_FAILED);
TEST_ASSERT_EQUAL(TUSB_ERROR_OSAL_TASK_FAILED, usbh_init());
}
void test_usbh_init_semaphore_create_failed(void)
{
hcd_init_ExpectAndReturn(TUSB_ERROR_NONE);
osal_queue_create_IgnoreAndReturn((osal_queue_handle_t) 0x1234);
osal_task_create_IgnoreAndReturn(TUSB_ERROR_NONE);
osal_semaphore_create_IgnoreAndReturn(NULL);
TEST_ASSERT_EQUAL(TUSB_ERROR_OSAL_SEMAPHORE_FAILED, usbh_init());
}
void test_usbh_init_mutex_create_failed(void)
{
hcd_init_ExpectAndReturn(TUSB_ERROR_NONE);
osal_queue_create_IgnoreAndReturn((osal_queue_handle_t) 0x1234);
osal_task_create_IgnoreAndReturn(TUSB_ERROR_NONE);
osal_semaphore_create_IgnoreAndReturn((osal_semaphore_handle_t) 0x1234);
osal_mutex_create_IgnoreAndReturn(NULL);
TEST_ASSERT_EQUAL(TUSB_ERROR_OSAL_MUTEX_FAILED, usbh_init());
}
void test_usbh_init_ok(void)
{
hcd_init_ExpectAndReturn(TUSB_ERROR_NONE);
helper_usbh_init_expect();
helper_class_init_expect();
//------------- code under test -------------//
TEST_ASSERT_EQUAL(TUSB_ERROR_NONE, usbh_init());
for (uint8_t i=0; i<CFG_TUSB_HOST_DEVICE_MAX+1; i++)
{
TEST_ASSERT_NOT_NULL(_usbh_devices[i].control.sem_hdl);
}
}
#if 0 // TODO TEST enable this
// device is not mounted before, even the control pipe is not open, do nothing
void test_hcd_event_device_remove_device_not_previously_mounted(void)
{
uint8_t dev_addr = 1;
_usbh_devices[dev_addr].state = TUSB_DEVICE_STATE_UNPLUG;
_usbh_devices[dev_addr].core_id = 0;
_usbh_devices[dev_addr].hub_addr = 0;
_usbh_devices[dev_addr].hub_port = 0;
hcd_event_device_remove(0);
}
void test_hcd_event_device_remove(void)
{
uint8_t dev_addr = 1;
_usbh_devices[dev_addr].state = TUSB_DEVICE_STATE_CONFIGURED;
_usbh_devices[dev_addr].core_id = 0;
_usbh_devices[dev_addr].hub_addr = 0;
_usbh_devices[dev_addr].hub_port = 0;
_usbh_devices[dev_addr].flag_supported_class = TU_BIT(TUSB_CLASS_HID);
hidh_close_Expect(dev_addr);
hcd_pipe_control_close_ExpectAndReturn(dev_addr, TUSB_ERROR_NONE);
//------------- Code Under Test -------------//
hcd_event_device_remove(0);
TEST_ASSERT_EQUAL(TUSB_DEVICE_STATE_REMOVING, _usbh_devices[dev_addr].state);
}
void test_usbh_device_unplugged_multple_class(void)
{
uint8_t dev_addr = 1;
_usbh_devices[dev_addr].state = TUSB_DEVICE_STATE_CONFIGURED;
_usbh_devices[dev_addr].core_id = 0;
_usbh_devices[dev_addr].hub_addr = 0;
_usbh_devices[dev_addr].hub_port = 0;
_usbh_devices[dev_addr].flag_supported_class = TU_BIT(TUSB_CLASS_HID) | TU_BIT(TUSB_CLASS_MSC) | TU_BIT(TUSB_CLASS_CDC);
cdch_close_Expect(dev_addr);
hidh_close_Expect(dev_addr);
msch_close_Expect(dev_addr);
hcd_pipe_control_close_ExpectAndReturn(dev_addr, TUSB_ERROR_NONE);
//------------- Code Under Test -------------//
hcd_event_device_remove(0);
TEST_ASSERT_EQUAL(TUSB_DEVICE_STATE_REMOVING, _usbh_devices[dev_addr].state);
}
#endif
void semaphore_wait_success_stub(osal_mutex_handle_t const sem_hdl, uint32_t msec, tusb_error_t *p_error, int num_call)
{
(*p_error) = TUSB_ERROR_NONE;
}
static void mutex_wait_failed_stub(osal_mutex_handle_t const sem_hdl, uint32_t msec, tusb_error_t *p_error, int num_call)
{
(*p_error) = TUSB_ERROR_OSAL_TIMEOUT;
}
void test_usbh_control_xfer_mutex_failed(void)
{
tusb_control_request_t a_request =
{
.bmRequestType = 1,
.bRequest = 2,
.wValue = 3,
.wIndex = 4,
.wLength = 0
};
osal_mutex_wait_StubWithCallback(mutex_wait_failed_stub);
osal_mutex_release_ExpectAndReturn(_usbh_devices[dev_addr].control.mutex_hdl, TUSB_ERROR_NONE);
//------------- Code Under Test -------------//
usbh_control_xfer(dev_addr, 1, 2, 3, 4, 0, NULL);
}
void test_usbh_control_xfer_ok(void)
{
tusb_control_request_t a_request =
{
.bmRequestType = 1,
.bRequest = 2,
.wValue = 3,
.wIndex = 4,
.wLength = 0
};
osal_mutex_wait_StubWithCallback(semaphore_wait_success_stub);
hcd_pipe_control_xfer_ExpectAndReturn(dev_addr, &a_request, NULL, TUSB_ERROR_NONE);
osal_semaphore_wait_StubWithCallback(semaphore_wait_success_stub);
osal_mutex_release_ExpectAndReturn(_usbh_devices[dev_addr].control.mutex_hdl, TUSB_ERROR_NONE);
//------------- Code Under Test -------------//
usbh_control_xfer(dev_addr, 1, 2, 3, 4, 0, NULL);
}
//void test_hcd_event_xfer_complete_non_control_stalled(void) // do nothing for stall on control
//{
//
//}

View File

@ -1,286 +0,0 @@
/*
* The MIT License (MIT)
*
* Copyright (c) 2019 Ha Thach (tinyusb.org)
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
* This file is part of the TinyUSB stack.
*/
#define _TEST_ASSERT_
#include <stdint.h>
#include <stdio.h>
#include <stdbool.h>
#include "unity.h"
#include "CException.h"
#include "binary.h"
#include "common/assertion.h"
#include "tusb_errors.h"
CEXCEPTION_T e;
void setUp(void)
{
e = 0;
}
void tearDown(void)
{
}
//--------------------------------------------------------------------+
// Error Status
//--------------------------------------------------------------------+
void test_assert_status(void)
{
Try
{
ASSERT_STATUS(TUSB_ERROR_NONE);
ASSERT_STATUS(TUSB_ERROR_INVALID_PARA);
}
Catch (e)
{
}
}
//--------------------------------------------------------------------+
// Logical
//--------------------------------------------------------------------+
void test_assert_logical_true(void)
{
Try
{
ASSERT (true , __LINE__);
ASSERT_TRUE (true , __LINE__);
ASSERT_TRUE (false, 0);
}
Catch(e)
{
TEST_ASSERT_EQUAL(0, e);
}
}
void test_assert_logical_false(void)
{
Try
{
ASSERT_FALSE (false, __LINE__);
ASSERT_FALSE (true , 0);
}
Catch(e)
{
TEST_ASSERT_EQUAL(0, e);
}
}
//--------------------------------------------------------------------+
// Pointer
//--------------------------------------------------------------------+
void test_assert_pointer_not_null(void)
{
uint32_t n;
Try
{
ASSERT_PTR_NOT_NULL(&n, __LINE__);
ASSERT_PTR(&n, __LINE__);
ASSERT_PTR(NULL, 0);
}
Catch(e)
{
TEST_ASSERT_EQUAL(0, e);
}
}
void test_assert_pointer_null(void)
{
uint32_t n;
Try
{
ASSERT_PTR_NULL(NULL, __LINE__);
ASSERT_PTR_NULL(&n, 0);
}
Catch(e)
{
TEST_ASSERT_EQUAL(0, e);
}
}
//--------------------------------------------------------------------+
// Integer
//--------------------------------------------------------------------+
void test_assert_int_eqal(void)
{
Try
{
ASSERT_INT (1, 1, __LINE__);
ASSERT_INT_EQUAL (1, 1, __LINE__);
// test side effect
uint32_t x = 0;
uint32_t y = 0;
ASSERT_INT (x++, y++, __LINE__);
TEST_ASSERT_EQUAL(1, x);
TEST_ASSERT_EQUAL(1, y);
ASSERT_INT (1, 0, 0);
}
Catch(e)
{
TEST_ASSERT_EQUAL(0, e);
}
}
void test_assert_int_within(void)
{
Try
{
ASSERT_INT_WITHIN (1, 5, 3, __LINE__);
ASSERT_INT_WITHIN (1, 5, 1, __LINE__);
ASSERT_INT_WITHIN (1, 5, 5, __LINE__);
ASSERT_INT_WITHIN (1, 5, 0, 0);
ASSERT_INT_WITHIN (1, 5, 10, 0);
}
Catch(e)
{
TEST_ASSERT_EQUAL(0, e);
}
}
void test_assert_int_within_greater(void)
{
Try
{
ASSERT_INT_WITHIN (1, 5, 10, 0);
}
Catch(e)
{
TEST_ASSERT_EQUAL(0, e);
}
}
void test_assert_int_within_less(void)
{
Try
{
ASSERT_INT_WITHIN (1, 5, 0, 0);
}
Catch(e)
{
TEST_ASSERT_EQUAL(0, e);
}
}
//--------------------------------------------------------------------+
// HEX
//--------------------------------------------------------------------+
void test_assert_hex_equal(void)
{
Try
{
ASSERT_HEX (0xffee, 0xffee, __LINE__);
ASSERT_HEX_EQUAL (0xffee, 0xffee, __LINE__);
// test side effect
uint32_t x = 0xf0f0;
uint32_t y = 0xf0f0;
ASSERT_HEX (x++, y++, __LINE__);
TEST_ASSERT_EQUAL(0xf0f1, x);
TEST_ASSERT_EQUAL(0xf0f1, y);
ASSERT_HEX(0x1234, 0x4321, 0);
}
Catch(e)
{
TEST_ASSERT_EQUAL(0, e);
}
}
void test_assert_hex_within(void)
{
Try
{
ASSERT_HEX_WITHIN (0xff00, 0xffff, 0xff11, __LINE__);
ASSERT_HEX_WITHIN (0xff00, 0xffff, 0xff00, __LINE__);
ASSERT_HEX_WITHIN (0xff00, 0xffff, 0xffff, __LINE__);
}
Catch (e)
{
TEST_ASSERT_EQUAL(0, e);
}
}
void test_assert_hex_within_less(void)
{
Try
{
ASSERT_HEX_WITHIN (0xff00, 0xffff, 0xeeee, 0);
}
Catch(e)
{
TEST_ASSERT_EQUAL(0, e);
}
}
void test_assert_hex_within_greater(void)
{
Try
{
ASSERT_HEX_WITHIN (0xff00, 0xffff, 0x1eeee, 0);
}
Catch(e)
{
TEST_ASSERT_EQUAL(0, e);
}
}
//--------------------------------------------------------------------+
// BIN
//--------------------------------------------------------------------+
void test_assert_bin_equal(void)
{
Try
{
ASSERT_BIN8 (TU_BIN8(11110000), TU_BIN8(11110000), __LINE__);
ASSERT_BIN8_EQUAL (TU_BIN8(00001111), TU_BIN8(00001111), __LINE__);
// test side effect
uint32_t x = TU_BIN8(11001100);
uint32_t y = TU_BIN8(11001100);
ASSERT_BIN8 (x++, y++, __LINE__);
TEST_ASSERT_EQUAL(TU_BIN8(11001101), x);
TEST_ASSERT_EQUAL(TU_BIN8(11001101), y);
ASSERT_BIN8(TU_BIN8(11001111), TU_BIN8(11111100), 0);
}
Catch(e)
{
TEST_ASSERT_EQUAL(0, e);
}
}

View File

@ -1,90 +0,0 @@
/*
* The MIT License (MIT)
*
* Copyright (c) 2019 Ha Thach (tinyusb.org)
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
* This file is part of the TinyUSB stack.
*/
#include <stdio.h>
#include "unity.h"
#include "common/binary.h"
void setUp(void)
{
}
void tearDown(void)
{
}
void test_binary_8(void)
{
TEST_ASSERT_EQUAL_HEX8(0x00, TU_BIN8(00000000));
TEST_ASSERT_EQUAL_HEX8(0x01, TU_BIN8(00000001));
TEST_ASSERT_EQUAL_HEX8(0x02, TU_BIN8(00000010));
TEST_ASSERT_EQUAL_HEX8(0x04, TU_BIN8(00000100));
TEST_ASSERT_EQUAL_HEX8(0x08, TU_BIN8(00001000));
TEST_ASSERT_EQUAL_HEX8(0x10, TU_BIN8(00010000));
TEST_ASSERT_EQUAL_HEX8(0x20, TU_BIN8(00100000));
TEST_ASSERT_EQUAL_HEX8(0x40, TU_BIN8(01000000));
TEST_ASSERT_EQUAL_HEX8(0x80, TU_BIN8(10000000));
TEST_ASSERT_EQUAL_HEX8(0x0f, TU_BIN8(00001111));
TEST_ASSERT_EQUAL_HEX8(0xf0, TU_BIN8(11110000));
TEST_ASSERT_EQUAL_HEX8(0xff, TU_BIN8(11111111));
}
void test_binary_16(void)
{
TEST_ASSERT_EQUAL_HEX16(0x0000, TU_BIN16(00000000, 00000000));
TEST_ASSERT_EQUAL_HEX16(0x000f, TU_BIN16(00000000, 00001111));
TEST_ASSERT_EQUAL_HEX16(0x00f0, TU_BIN16(00000000, 11110000));
TEST_ASSERT_EQUAL_HEX16(0x0f00, TU_BIN16(00001111, 00000000));
TEST_ASSERT_EQUAL_HEX16(0xf000, TU_BIN16(11110000, 00000000));
TEST_ASSERT_EQUAL_HEX16(0xffff, TU_BIN16(11111111, 11111111));
}
void test_binary_32(void)
{
TEST_ASSERT_EQUAL_HEX32(0x00000000, TU_BIN32(00000000, 00000000, 00000000, 00000000));
TEST_ASSERT_EQUAL_HEX32(0x0000000f, TU_BIN32(00000000, 00000000, 00000000, 00001111));
TEST_ASSERT_EQUAL_HEX32(0x000000f0, TU_BIN32(00000000, 00000000, 00000000, 11110000));
TEST_ASSERT_EQUAL_HEX32(0x00000f00, TU_BIN32(00000000, 00000000, 00001111, 00000000));
TEST_ASSERT_EQUAL_HEX32(0x0000f000, TU_BIN32(00000000, 00000000, 11110000, 00000000));
TEST_ASSERT_EQUAL_HEX32(0x000f0000, TU_BIN32(00000000, 00001111, 00000000, 00000000));
TEST_ASSERT_EQUAL_HEX32(0x00f00000, TU_BIN32(00000000, 11110000, 00000000, 00000000));
TEST_ASSERT_EQUAL_HEX32(0x0f000000, TU_BIN32(00001111, 00000000, 00000000, 00000000));
TEST_ASSERT_EQUAL_HEX32(0xf0000000, TU_BIN32(11110000, 00000000, 00000000, 00000000));
TEST_ASSERT_EQUAL_HEX32(0xffffffff, TU_BIN32(11111111, 11111111, 11111111, 11111111));
}
void test_bit_set(void)
{
TEST_ASSERT_EQUAL_HEX32( TU_BIN8(00001101), tu_bit_set( TU_BIN8(00001001), 2));
TEST_ASSERT_EQUAL_HEX32( TU_BIN8(10001101), tu_bit_set( TU_BIN8(00001101), 7));
}
void test_bit_clear(void)
{
TEST_ASSERT_EQUAL_HEX32( TU_BIN8(00001001), tu_bit_clear( TU_BIN8(00001101), 2));
TEST_ASSERT_EQUAL_HEX32( TU_BIN8(00001101), tu_bit_clear( TU_BIN8(10001101), 7));
}

View File

@ -1,73 +0,0 @@
/*
* The MIT License (MIT)
*
* Copyright (c) 2019 Ha Thach (tinyusb.org)
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
* This file is part of the TinyUSB stack.
*/
#include "unity.h"
#include "tusb_errors.h"
//#include "freeRTOS.h"
//#include "osal_freeRTOS.h"
//#include "mock_task.h"
//#include "queue.h"
//#include "mock_portmacro.h"
//#include "mock_portable.h"
//#include "mock_list.h"
//
//#define QUEUE_DEPTH 10
//
//uint32_t statements[10];
//
//OSAL_SEM_DEF(sem);
//osal_semaphore_handle_t sem_hdl;
//
//OSAL_QUEUE_DEF(queue, QUEUE_DEPTH, uin32_t);
//osal_queue_handle_t queue_hdl;
void setUp(void)
{
// memset(statements, 0, sizeof(statements));
// sem_hdl = osal_semaphore_create(OSAL_SEM_REF(sem));
// queue_hdl = osal_queue_create(&queue);
}
void tearDown(void)
{
}
void test_(void)
{
tusb_error_t error = TUSB_ERROR_NONE;
uint32_t data;
// TEST_IGNORE();
//
// osal_semaphore_post(sem_hdl);
// osal_semaphore_wait(sem_hdl, OSAL_TIMEOUT_WAIT_FOREVER, &error);
//
// uint32_t item = 0x1234;
// osal_queue_send(queue_hdl, &item);
// osal_queue_receive(queue_hdl, &data, OSAL_TIMEOUT_NORMAL, &error);
}

View File

@ -1,433 +0,0 @@
/*
* The MIT License (MIT)
*
* Copyright (c) 2019 Ha Thach (tinyusb.org)
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
* This file is part of the TinyUSB stack.
*/
#ifdef CFG_TUSB_OS
#undef CFG_TUSB_OS
#endif
void setUp(void)
{
}
void tearDown(void)
{
}
#if 0 // TODO enable
#include "unity.h"
#include "tusb_errors.h"
#include "osal_none.h"
#define QUEUE_DEPTH 10
uint32_t statements[10];
OSAL_SEM_DEF(sem);
osal_semaphore_handle_t sem_hdl;
OSAL_QUEUE_DEF(queue, QUEUE_DEPTH, uint32_t);
osal_queue_handle_t queue_hdl;
OSAL_MUTEX_DEF(mutex);
osal_mutex_handle_t mutex_hdl;
void setUp(void)
{
memset(statements, 0, sizeof(statements));
sem_hdl = osal_semaphore_create (OSAL_SEM_REF(sem));
queue_hdl = osal_queue_create (OSAL_QUEUE_REF(queue));
mutex_hdl = osal_mutex_create (OSAL_MUTEX_REF(mutex));
}
void tearDown(void)
{
}
//--------------------------------------------------------------------+
// Semaphore
//--------------------------------------------------------------------+
void test_semaphore_create(void)
{
TEST_ASSERT_EQUAL_PTR(&sem, sem_hdl);
TEST_ASSERT_EQUAL(0, sem);
}
void test_semaphore_post(void)
{
osal_semaphore_post(sem_hdl);
TEST_ASSERT_EQUAL(1, sem);
}
// blocking service such as semaphore wait need to be invoked within a task's loop
//--------------------------------------------------------------------+
// Mutex
//--------------------------------------------------------------------+
void test_mutex_create(void)
{
TEST_ASSERT_EQUAL_PTR(&mutex, mutex_hdl);
TEST_ASSERT_EQUAL(1, mutex);
}
void test_mutex_release(void)
{
osal_mutex_release(mutex_hdl);
TEST_ASSERT_EQUAL(1, mutex);
}
//--------------------------------------------------------------------+
// Queue
//--------------------------------------------------------------------+
void test_queue_create(void)
{
TEST_ASSERT_EQUAL_PTR(&queue, queue_hdl);
TEST_ASSERT_EQUAL(QUEUE_DEPTH, queue_hdl->depth);
TEST_ASSERT_EQUAL_PTR(queue_buffer, queue_hdl->buffer);
TEST_ASSERT_EQUAL(0, queue_hdl->count);
TEST_ASSERT_EQUAL(0, queue_hdl->wr_idx);
TEST_ASSERT_EQUAL(0, queue_hdl->rd_idx);
}
void test_queue_send(void)
{
uint32_t const item = 0x1234;
osal_queue_send(queue_hdl, &item);
TEST_ASSERT_EQUAL(1, queue_hdl->count);
TEST_ASSERT_EQUAL_MEMORY(&item, queue_hdl->buffer + (queue_hdl->rd_idx * queue_hdl->item_size), 4);
}
// blocking service such as semaphore wait need to be invoked within a task's loop
//--------------------------------------------------------------------+
// TASK SEMAPHORE
//--------------------------------------------------------------------+
tusb_error_t sample_task_semaphore(void)
{
tusb_error_t error = TUSB_ERROR_NONE;
OSAL_TASK_LOOP_BEGIN
statements[0]++;
osal_semaphore_wait(sem_hdl, OSAL_TIMEOUT_WAIT_FOREVER, &error);
statements[1]++;
osal_semaphore_wait(sem_hdl, OSAL_TIMEOUT_WAIT_FOREVER, &error);
statements[2]++;
osal_semaphore_wait(sem_hdl, OSAL_TIMEOUT_WAIT_FOREVER, &error);
statements[3]++;
osal_semaphore_wait(sem_hdl, OSAL_TIMEOUT_NORMAL, &error);
statements[4]++;
TEST_ASSERT_EQUAL(TUSB_ERROR_OSAL_TIMEOUT, error);
OSAL_TASK_LOOP_END
}
void test_task_with_semaphore(void)
{
// several invoke before sempahore is available
for(uint32_t i=0; i<10; i++)
sample_task_semaphore();
TEST_ASSERT_EQUAL(1, statements[0]);
// invoke after posting semaphore
osal_semaphore_post(sem_hdl);
sample_task_semaphore();
TEST_ASSERT_EQUAL(1, statements[1]);
// post 2 consecutive times
osal_semaphore_post(sem_hdl);
osal_semaphore_post(sem_hdl);
sample_task_semaphore();
TEST_ASSERT_EQUAL(1, statements[2]);
TEST_ASSERT_EQUAL(1, statements[3]);
// timeout
for(uint32_t i=0; i<(OSAL_TIMEOUT_NORMAL*CFG_TUSB_OS_TICKS_PER_SECOND)/1000 - 1 ; i++) // not enough time
osal_tick_tock();
sample_task_semaphore();
TEST_ASSERT_EQUAL(0, statements[4]);
osal_tick_tock();
sample_task_semaphore();
// reach end of task loop, back to beginning
sample_task_semaphore();
TEST_ASSERT_EQUAL(2, statements[0]);
}
//--------------------------------------------------------------------+
// TASK MUTEX
//--------------------------------------------------------------------+
tusb_error_t mutex_sample_task1(void) // occupy mutex and not release it
{
tusb_error_t error = TUSB_ERROR_NONE;
OSAL_TASK_LOOP_BEGIN
statements[0]++;
osal_mutex_wait(mutex_hdl, OSAL_TIMEOUT_WAIT_FOREVER, &error);
statements[2]++;
OSAL_TASK_LOOP_END
}
tusb_error_t mutex_sample_task2(void)
{
tusb_error_t error = TUSB_ERROR_NONE;
OSAL_TASK_LOOP_BEGIN
statements[1]++;
osal_mutex_wait(mutex_hdl, OSAL_TIMEOUT_WAIT_FOREVER, &error);
statements[3]++;
osal_mutex_wait(mutex_hdl, OSAL_TIMEOUT_NORMAL, &error);
statements[5]++;
TEST_ASSERT_EQUAL(TUSB_ERROR_OSAL_TIMEOUT, error);
OSAL_TASK_LOOP_END
}
void test_task_with_mutex(void)
{
// several invoke before mutex is available
mutex_sample_task1();
for(uint32_t i=0; i<10; i++) {
mutex_sample_task2();
}
TEST_ASSERT_EQUAL(1, statements[0]);
TEST_ASSERT_EQUAL(1, statements[2]);
TEST_ASSERT_EQUAL(1, statements[1]);
TEST_ASSERT_EQUAL(0, statements[3]);
// invoke after posting mutex
osal_mutex_release(mutex_hdl);
for(uint32_t i=0; i<10; i++) {
mutex_sample_task2();
}
TEST_ASSERT_EQUAL(1, statements[3]);
TEST_ASSERT_EQUAL(0, statements[5]);
// timeout
for(uint32_t i=0; i<(OSAL_TIMEOUT_NORMAL*CFG_TUSB_OS_TICKS_PER_SECOND)/1000 - 1 ; i++){ // one tick less
osal_tick_tock();
}
mutex_sample_task2();
TEST_ASSERT_EQUAL(0, statements[5]);
osal_tick_tock();
mutex_sample_task2();
TEST_ASSERT_EQUAL(1, statements[5]);
}
//--------------------------------------------------------------------+
// TASK QUEUE
//--------------------------------------------------------------------+
tusb_error_t sample_task_with_queue(void)
{
uint32_t data;
tusb_error_t error;
OSAL_TASK_LOOP_BEGIN
statements[0]++;
osal_queue_receive(queue_hdl, &data, OSAL_TIMEOUT_WAIT_FOREVER, &error);
TEST_ASSERT_EQUAL(0x1111, data);
statements[1]++;
osal_queue_receive(queue_hdl, &data, OSAL_TIMEOUT_WAIT_FOREVER, &error);
TEST_ASSERT_EQUAL(0x2222, data);
statements[2]++;
osal_queue_receive(queue_hdl, &data, OSAL_TIMEOUT_WAIT_FOREVER, &error);
TEST_ASSERT_EQUAL(0x3333, data);
statements[3]++;
osal_queue_receive(queue_hdl, &data, OSAL_TIMEOUT_NORMAL, &error);
statements[4]++;
TEST_ASSERT_EQUAL(TUSB_ERROR_OSAL_TIMEOUT, error);
OSAL_TASK_LOOP_END
}
void test_task_with_queue(void)
{
uint32_t i = 0;
uint32_t item;
sample_task_with_queue();
// several invoke before queue is available
for(i=0; i<10; i++)
sample_task_with_queue();
TEST_ASSERT_EQUAL(1, statements[0]);
// invoke after sending to queue
item = 0x1111;
osal_queue_send(queue_hdl, &item);
sample_task_with_queue();
TEST_ASSERT_EQUAL(1, statements[1]);
sample_task_with_queue();
TEST_ASSERT_EQUAL(1, statements[1]);
item = 0x2222;
osal_queue_send(queue_hdl, &item);
item = 0x3333;
osal_queue_send(queue_hdl, &item);
sample_task_with_queue();
TEST_ASSERT_EQUAL(1, statements[2]);
TEST_ASSERT_EQUAL(1, statements[3]);
// timeout
for(uint32_t i=0; i<(OSAL_TIMEOUT_NORMAL*CFG_TUSB_OS_TICKS_PER_SECOND)/1000 - 1 ; i++) // not enough time
osal_tick_tock();
sample_task_with_queue();
TEST_ASSERT_EQUAL(0, statements[4]);
osal_tick_tock();
sample_task_with_queue();
// reach end of task loop, back to beginning
sample_task_with_queue();
TEST_ASSERT_EQUAL(2, statements[0]);
}
//--------------------------------------------------------------------+
// TASK DELAY
//--------------------------------------------------------------------+
tusb_error_t sample_task_with_delay(void)
{
tusb_error_t error;
OSAL_TASK_LOOP_BEGIN
osal_task_delay(1000);
statements[0]++;
OSAL_TASK_LOOP_END
}
void test_task_with_delay(void)
{
sample_task_with_delay();
TEST_ASSERT_EQUAL(0, statements[0]);
for(uint32_t i=0; i<CFG_TUSB_OS_TICKS_PER_SECOND*1000; i++) // not enough time
osal_tick_tock();
sample_task_with_delay();
TEST_ASSERT_EQUAL(1, statements[0]);
}
//--------------------------------------------------------------------+
// TASK FLOW CONTROL
//--------------------------------------------------------------------+
void flow_control_error_handler(void)
{
statements[5]++;
}
tusb_error_t sample_flow_control_subtask2(void)
{
tusb_error_t error;
OSAL_SUBTASK_BEGIN
statements[0]++;
osal_semaphore_wait(sem_hdl, OSAL_TIMEOUT_NORMAL, &error);
SUBTASK_ASSERT(TUSB_ERROR_NONE == error);
statements[1]++;
osal_semaphore_wait(sem_hdl, OSAL_TIMEOUT_NORMAL, &error);
SUBTASK_ASSERT_STATUS(error);
statements[2]++;
osal_semaphore_wait(sem_hdl, OSAL_TIMEOUT_NORMAL, &error);
SUBTASK_ASSERT_STATUS_HDLR(error, flow_control_error_handler());
statements[3]++;
OSAL_SUBTASK_END
}
tusb_error_t sample_flow_control_subtask(void)
{
OSAL_SUBTASK_BEGIN
sample_flow_control_subtask2();
OSAL_SUBTASK_END
}
tusb_error_t sample_task_flow_control(void)
{
OSAL_TASK_LOOP_BEGIN
sample_flow_control_subtask();
OSAL_TASK_LOOP_END
}
void test_task_flow_control_assert(void)
{
sample_task_flow_control();
for(uint32_t i=0; i<(OSAL_TIMEOUT_NORMAL*CFG_TUSB_OS_TICKS_PER_SECOND)/1000 + 1; i++) osal_tick_tock();
sample_task_flow_control();
TEST_ASSERT_EQUAL(0, statements[1]);
}
void test_task_flow_control_assert_status(void)
{
for (uint8_t i=0; i<1; i++) osal_semaphore_post(sem_hdl);
sample_task_flow_control();
for(uint32_t i=0; i<(OSAL_TIMEOUT_NORMAL*CFG_TUSB_OS_TICKS_PER_SECOND)/1000 + 1; i++) osal_tick_tock();
sample_task_flow_control();
TEST_ASSERT_EQUAL(0, statements[2]);
}
void test_task_flow_control_assert_status_hanlder(void)
{
for (uint8_t i=0; i<2; i++) osal_semaphore_post(sem_hdl);
sample_task_flow_control();
for(uint32_t i=0; i<(OSAL_TIMEOUT_NORMAL*CFG_TUSB_OS_TICKS_PER_SECOND)/1000 + 1; i++) osal_tick_tock();
sample_task_flow_control();
TEST_ASSERT_EQUAL(0, statements[3]);
TEST_ASSERT_EQUAL(1, statements[5]);
}
#endif

View File

@ -1,18 +0,0 @@
# Test-Driven Development
[Test-Driven Development (TDD)](http://en.wikipedia.org/wiki/Test-driven_development) is a development process that relies on the repetition of a very short development cycle: first the developer writes an (initially failing) automated test case that defines a desired improvement or new function, then produces the minimum amount of code to pass that test, and finally refactors the new code to acceptable standards.
In this project, TDD is performed by the help of Ceedling, Unity & CMock as a testing framework. However, due to my limited time, not all the code base is tested yet, and it will be indeed an challenging to keep the test up to the code.
More detail on TDD can be found at
- [James W. Grenning's book "Test Driven Development for Embedded C"](http://www.amazon.com/Driven-Development-Embedded-Pragmatic-Programmers/dp/193435662X)
- [throwtheswitch's Ceedling, CMock & Unity](http://throwtheswitch.org/)
## Continuous Integration
Continuous Integration (CI) is used to automatically run all the tests whenever there is a change in the code base. This makes sure that a modification of a file won't break any tests or functionality of others, verifying they all passed.
As many other open source project, tinyusb uses Travis-CI server (free for OOS). You can find my project on Travis here https://travis-ci.org/hathach/tinyusb
![Build Status](https://travis-ci.org/hathach/tinyusb.svg?branch=master)

View File

@ -1,132 +0,0 @@
/*
FreeRTOS V7.3.0 - Copyright (C) 2012 Real Time Engineers Ltd.
FEATURES AND PORTS ARE ADDED TO FREERTOS ALL THE TIME. PLEASE VISIT
http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
***************************************************************************
* *
* FreeRTOS tutorial books are available in pdf and paperback. *
* Complete, revised, and edited pdf reference manuals are also *
* available. *
* *
* Purchasing FreeRTOS documentation will not only help you, by *
* ensuring you get running as quickly as possible and with an *
* in-depth knowledge of how to use FreeRTOS, it will also help *
* the FreeRTOS project to continue with its mission of providing *
* professional grade, cross platform, de facto standard solutions *
* for microcontrollers - completely free of charge! *
* *
* >>> See http://www.FreeRTOS.org/Documentation for details. <<< *
* *
* Thank you for using FreeRTOS, and thank you for your support! *
* *
***************************************************************************
This file is part of the FreeRTOS distribution.
FreeRTOS is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License (version 2) as published by the
Free Software Foundation AND MODIFIED BY the FreeRTOS exception.
>>>NOTE<<< The modification to the GPL is included to allow you to
distribute a combined work that includes FreeRTOS without being obliged to
provide the source code for proprietary components outside of the FreeRTOS
kernel. FreeRTOS is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
more details. You should have received a copy of the GNU General Public
License and the FreeRTOS license exception along with FreeRTOS; if not it
can be viewed here: http://www.freertos.org/a00114.html and also obtained
by writing to Richard Barry, contact details for whom are available on the
FreeRTOS WEB site.
1 tab == 4 spaces!
***************************************************************************
* *
* Having a problem? Start by reading the FAQ "My application does *
* not run, what could be wrong?" *
* *
* http://www.FreeRTOS.org/FAQHelp.html *
* *
***************************************************************************
http://www.FreeRTOS.org - Documentation, training, latest versions, license
and contact details.
http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
including FreeRTOS+Trace - an indispensable productivity tool.
Real Time Engineers ltd license FreeRTOS to High Integrity Systems, who sell
the code with commercial support, indemnification, and middleware, under
the OpenRTOS brand: http://www.OpenRTOS.com. High Integrity Systems also
provide a safety engineered and independently SIL3 certified version under
the SafeRTOS brand: http://www.SafeRTOS.com.
*/
#ifndef FREERTOS_CONFIG_H
#define FREERTOS_CONFIG_H
/*
* The following #error directive is to remind users that a batch file must be
* executed prior to this project being built. The batch file *cannot* be
* executed from within the IDE! Once it has been executed, re-open or refresh
* the Eclipse project and remove the #error line below.
*/
//#error Ensure CreateProjectDirectoryStructure.bat has been executed before building. See comment immediately above.
/*-----------------------------------------------------------
* Application specific definitions.
*
* These definitions should be adjusted for your particular hardware and
* application requirements.
*
* THESE PARAMETERS ARE DESCRIBED WITHIN THE 'CONFIGURATION' SECTION OF THE
* FreeRTOS API DOCUMENTATION AVAILABLE ON THE FreeRTOS.org WEB SITE.
*----------------------------------------------------------*/
#define configUSE_PREEMPTION 1
#define configUSE_IDLE_HOOK 1
#define configUSE_TICK_HOOK 0
#define configTICK_RATE_HZ ( 50 ) /* In this non-real time simulated environment the tick frequency has to be at least a multiple of the Win32 tick frequency, and therefore very slow. */
#define configMINIMAL_STACK_SIZE ( ( unsigned portSHORT ) 20 ) /* In this simulated case, the stack only has to hold one small structure as the real stack is part of the win32 thread. */
#define configTOTAL_HEAP_SIZE ( ( size_t ) 0 ) /* This parameter has no effect when heap_3.c is included in the project. */
#define configMAX_TASK_NAME_LEN ( 12 )
#define configUSE_TRACE_FACILITY 1
#define configUSE_16_BIT_TICKS 0
#define configIDLE_SHOULD_YIELD 1
#define configUSE_CO_ROUTINES 0
#define configUSE_MUTEXES 1
#define configGENERATE_RUN_TIME_STATS 0
#define configCHECK_FOR_STACK_OVERFLOW 0
#define configUSE_RECURSIVE_MUTEXES 1
#define configQUEUE_REGISTRY_SIZE 0
#define configUSE_MALLOC_FAILED_HOOK 1
#define configUSE_APPLICATION_TASK_TAG 0
#define configMAX_PRIORITIES ( ( unsigned portBASE_TYPE ) 7 )
#define configMAX_CO_ROUTINE_PRIORITIES ( 2 )
/* Co-routine definitions. */
#define configUSE_CO_ROUTINES 0
#define configMAX_CO_ROUTINE_PRIORITIES ( 2 )
/* Set the following definitions to 1 to include the API function, or zero
to exclude the API function. */
#define INCLUDE_vTaskPrioritySet 1
#define INCLUDE_uxTaskPriorityGet 1
#define INCLUDE_vTaskDelete 1
#define INCLUDE_vTaskCleanUpResources 0
#define INCLUDE_vTaskSuspend 1
#define INCLUDE_vTaskDelayUntil 1
#define INCLUDE_vTaskDelay 1
#define INCLUDE_uxTaskGetStackHighWaterMark 1
#define INCLUDE_xTaskGetSchedulerState 1
#endif /* FREERTOS_CONFIG_H */

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,342 +0,0 @@
/*
* The MIT License (MIT)
*
* Copyright (c) 2019 Ha Thach (tinyusb.org)
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
* This file is part of the TinyUSB stack.
*/
#include "tusb_option.h"
#include "descriptor_test.h"
CFG_TUSB_MEM_SECTION TU_ATTR_ALIGNED(4)
const uint8_t keyboard_report_descriptor[] = {
HID_USAGE_PAGE ( HID_USAGE_PAGE_DESKTOP ),
HID_USAGE ( HID_USAGE_DESKTOP_KEYBOARD ),
HID_COLLECTION ( HID_COLLECTION_APPLICATION ),
HID_USAGE_PAGE ( HID_USAGE_PAGE_KEYBOARD ),
HID_USAGE_MIN ( 224 ),
HID_USAGE_MAX ( 231 ),
HID_LOGICAL_MIN ( 0 ),
HID_LOGICAL_MAX ( 1 ),
HID_REPORT_COUNT ( 8 ), /* 8 bits */
HID_REPORT_SIZE ( 1 ),
HID_INPUT ( HID_DATA | HID_VARIABLE | HID_ABSOLUTE ), /* maskable modifier key */
HID_REPORT_COUNT ( 1 ),
HID_REPORT_SIZE ( 8 ),
HID_INPUT ( HID_CONSTANT ), /* reserved */
HID_USAGE_PAGE ( HID_USAGE_PAGE_LED ),
HID_USAGE_MIN ( 1 ),
HID_USAGE_MAX ( 5 ),
HID_REPORT_COUNT ( 5 ),
HID_REPORT_SIZE ( 1 ),
HID_OUTPUT ( HID_DATA | HID_VARIABLE | HID_ABSOLUTE ), /* 5-bit Led report */
HID_REPORT_COUNT ( 1 ),
HID_REPORT_SIZE ( 3 ), /* led padding */
HID_OUTPUT ( HID_CONSTANT ),
HID_USAGE_PAGE (HID_USAGE_PAGE_KEYBOARD),
HID_USAGE_MIN ( 0 ),
HID_USAGE_MAX ( 101 ),
HID_LOGICAL_MIN ( 0 ),
HID_LOGICAL_MAX ( 101 ),
HID_REPORT_COUNT ( 6 ),
HID_REPORT_SIZE ( 8 ),
HID_INPUT ( HID_DATA | HID_ARRAY | HID_ABSOLUTE ), /* keycodes array 6 items */
HID_COLLECTION_END
};
CFG_TUSB_MEM_SECTION TU_ATTR_ALIGNED(4)
const uint8_t mouse_report_descriptor[] = {
HID_USAGE_PAGE ( HID_USAGE_PAGE_DESKTOP ),
HID_USAGE ( HID_USAGE_DESKTOP_MOUSE ),
HID_COLLECTION ( HID_COLLECTION_APPLICATION ),
HID_USAGE (HID_USAGE_DESKTOP_POINTER),
HID_COLLECTION ( HID_COLLECTION_PHYSICAL ),
HID_USAGE_PAGE ( HID_USAGE_PAGE_BUTTON ),
HID_USAGE_MIN ( 1 ),
HID_USAGE_MAX ( 3 ),
HID_LOGICAL_MIN ( 0 ),
HID_LOGICAL_MAX ( 1 ),
HID_REPORT_COUNT ( 3 ), /* Left, Right and Middle mouse*/
HID_REPORT_SIZE ( 1 ),
HID_INPUT ( HID_DATA | HID_VARIABLE | HID_ABSOLUTE ),
HID_REPORT_COUNT ( 1 ),
HID_REPORT_SIZE ( 5 ),
HID_INPUT ( HID_CONSTANT ), /* reserved */
HID_USAGE_PAGE ( HID_USAGE_PAGE_DESKTOP ),
HID_USAGE ( HID_USAGE_DESKTOP_X ),
HID_USAGE ( HID_USAGE_DESKTOP_Y ),
HID_LOGICAL_MIN ( 0x81 ), /* -127 */
HID_LOGICAL_MAX ( 0x7f ), /* 127 */
HID_REPORT_COUNT ( 2 ), /* X, Y position */
HID_REPORT_SIZE ( 8 ),
HID_INPUT ( HID_DATA | HID_VARIABLE | HID_RELATIVE ), /* relative values */
HID_COLLECTION_END,
HID_COLLECTION_END
};
CFG_TUSB_MEM_SECTION TU_ATTR_ALIGNED(4)
tusb_desc_device_t const desc_device =
{
.bLength = sizeof(tusb_desc_device_t),
.bDescriptorType = TUSB_DESC_TYPE_DEVICE,
.bcdUSB = 0x0200,
.bDeviceClass = 0x00,
.bDeviceSubClass = 0x00,
.bDeviceProtocol = 0x00,
.bMaxPacketSize0 = 64,
.idVendor = 0x1FC9,
.idProduct = 0x4000,
.bcdDevice = 0x0100,
.iManufacturer = 0x01,
.iProduct = 0x02,
.iSerialNumber = 0x03,
.bNumConfigurations = 0x02
} ;
CFG_TUSB_MEM_SECTION TU_ATTR_ALIGNED(4)
const app_configuration_desc_t desc_configuration =
{
.configuration =
{
.bLength = sizeof(tusb_desc_configuration_t),
.bDescriptorType = TUSB_DESC_TYPE_CONFIGURATION,
.wTotalLength = sizeof(app_configuration_desc_t) - 1, // exclude termination
.bNumInterfaces = 5,
.bConfigurationValue = 1,
.iConfiguration = 0x00,
.bmAttributes = TUSB_DESC_CONFIG_ATT_BUS_POWER,
.bMaxPower = TUSB_DESC_CONFIG_POWER_MA(100)
},
//------------- HID Keyboard -------------//
.keyboard_interface =
{
.bLength = sizeof(tusb_desc_interface_t),
.bDescriptorType = TUSB_DESC_TYPE_INTERFACE,
.bInterfaceNumber = 1,
.bAlternateSetting = 0x00,
.bNumEndpoints = 1,
.bInterfaceClass = TUSB_CLASS_HID,
.bInterfaceSubClass = HID_SUBCLASS_BOOT,
.bInterfaceProtocol = HID_PROTOCOL_KEYBOARD,
.iInterface = 0x00
},
.keyboard_hid =
{
.bLength = sizeof(tusb_hid_descriptor_hid_t),
.bDescriptorType = HID_DESC_TYPE_HID,
.bcdHID = 0x0111,
.bCountryCode = HID_LOCAL_NotSupported,
.bNumDescriptors = 1,
.bReportType = HID_DESC_TYPE_REPORT,
.wReportLength = sizeof(keyboard_report_descriptor)
},
.keyboard_endpoint =
{
.bLength = sizeof(tusb_desc_endpoint_t),
.bDescriptorType = TUSB_DESC_TYPE_ENDPOINT,
.bEndpointAddress = 0x81,
.bmAttributes = { .xfer = TUSB_XFER_INTERRUPT },
.wMaxPacketSize = 0x08,
.bInterval = 0x0A
},
//------------- HID Mouse -------------//
.mouse_interface =
{
.bLength = sizeof(tusb_desc_interface_t),
.bDescriptorType = TUSB_DESC_TYPE_INTERFACE,
.bInterfaceNumber = 2,
.bAlternateSetting = 0x00,
.bNumEndpoints = 1,
.bInterfaceClass = TUSB_CLASS_HID,
.bInterfaceSubClass = HID_SUBCLASS_BOOT,
.bInterfaceProtocol = HID_PROTOCOL_MOUSE,
.iInterface = 0x00
},
.mouse_hid =
{
.bLength = sizeof(tusb_hid_descriptor_hid_t),
.bDescriptorType = HID_DESC_TYPE_HID,
.bcdHID = 0x0111,
.bCountryCode = HID_LOCAL_NotSupported,
.bNumDescriptors = 1,
.bReportType = HID_DESC_TYPE_REPORT,
.wReportLength = sizeof(mouse_report_descriptor)
},
.mouse_endpoint =
{
.bLength = sizeof(tusb_desc_endpoint_t),
.bDescriptorType = TUSB_DESC_TYPE_ENDPOINT,
.bEndpointAddress = 0x82,
.bmAttributes = { .xfer = TUSB_XFER_INTERRUPT },
.wMaxPacketSize = 0x08,
.bInterval = 0x0A
},
//------------- Mass Storage -------------//
.msc_interface =
{
.bLength = sizeof(tusb_desc_interface_t),
.bDescriptorType = TUSB_DESC_TYPE_INTERFACE,
.bInterfaceNumber = 3,
.bAlternateSetting = 0x00,
.bNumEndpoints = 2,
.bInterfaceClass = TUSB_CLASS_MSC,
.bInterfaceSubClass = MSC_SUBCLASS_SCSI,
.bInterfaceProtocol = MSC_PROTOCOL_BOT,
.iInterface = 0x00
},
.msc_endpoint_in =
{
.bLength = sizeof(tusb_desc_endpoint_t),
.bDescriptorType = TUSB_DESC_TYPE_ENDPOINT,
.bEndpointAddress = 0x83,
.bmAttributes = { .xfer = TUSB_XFER_BULK },
.wMaxPacketSize = 512,
.bInterval = 1
},
.msc_endpoint_out =
{
.bLength = sizeof(tusb_desc_endpoint_t),
.bDescriptorType = TUSB_DESC_TYPE_ENDPOINT,
.bEndpointAddress = 0x03,
.bmAttributes = { .xfer = TUSB_XFER_BULK },
.wMaxPacketSize = 512,
.bInterval = 1
},
//------------- CDC Serial -------------//
.cdc_comm_interface =
{
.bLength = sizeof(tusb_desc_interface_t),
.bDescriptorType = TUSB_DESC_TYPE_INTERFACE,
.bInterfaceNumber = 4,
.bAlternateSetting = 0,
.bNumEndpoints = 1,
.bInterfaceClass = TUSB_CLASS_CDC,
.bInterfaceSubClass = CDC_COMM_SUBCLASS_ABSTRACT_CONTROL_MODEL,
.bInterfaceProtocol = CDC_COMM_PROTOCOL_ATCOMMAND,
.iInterface = 0x00
},
.cdc_header =
{
.bLength = sizeof(cdc_desc_func_header_t),
.bDescriptorType = TUSB_DESC_TYPE_INTERFACE_CLASS_SPECIFIC,
.bDescriptorSubType = CDC_FUNC_DESC_HEADER,
.bcdCDC = 0x0120
},
.cdc_acm =
{
.bLength = sizeof(cdc_desc_func_acm_t),
.bDescriptorType = TUSB_DESC_TYPE_INTERFACE_CLASS_SPECIFIC,
.bDescriptorSubType = CDC_FUNC_DESC_ABSTRACT_CONTROL_MANAGEMENT,
.bmCapabilities = { // 0x06
.support_line_request = 1,
.support_send_break = 1
}
},
.cdc_union =
{
.bLength = sizeof(cdc_desc_func_union_t), // plus number of
.bDescriptorType = TUSB_DESC_TYPE_INTERFACE_CLASS_SPECIFIC,
.bDescriptorSubType = CDC_FUNC_DESC_UNION,
.bControlInterface = 1,
.bSubordinateInterface = 2,
},
.cdc_endpoint_notification =
{
.bLength = sizeof(tusb_desc_endpoint_t),
.bDescriptorType = TUSB_DESC_TYPE_ENDPOINT,
.bEndpointAddress = 0x84,
.bmAttributes = { .xfer = TUSB_XFER_INTERRUPT },
.wMaxPacketSize = 8,
.bInterval = 0x0a // lowest polling rate
},
//------------- CDC Data Interface -------------//
.cdc_data_interface =
{
.bLength = sizeof(tusb_desc_interface_t),
.bDescriptorType = TUSB_DESC_TYPE_INTERFACE,
.bInterfaceNumber = 5,
.bAlternateSetting = 0x00,
.bNumEndpoints = 2,
.bInterfaceClass = TUSB_CLASS_CDC_DATA,
.bInterfaceSubClass = 0,
.bInterfaceProtocol = 0,
.iInterface = 0x00
},
.cdc_endpoint_out =
{
.bLength = sizeof(tusb_desc_endpoint_t),
.bDescriptorType = TUSB_DESC_TYPE_ENDPOINT,
.bEndpointAddress = 5,
.bmAttributes = { .xfer = TUSB_XFER_BULK },
.wMaxPacketSize = 64,
.bInterval = 0
},
.cdc_endpoint_in =
{
.bLength = sizeof(tusb_desc_endpoint_t),
.bDescriptorType = TUSB_DESC_TYPE_ENDPOINT,
.bEndpointAddress = 0x85,
.bmAttributes = { .xfer = TUSB_XFER_BULK },
.wMaxPacketSize = 64,
.bInterval = 0
},
// TODO CDC & RNDIS
.ConfigDescTermination = 0,
};

View File

@ -1,117 +0,0 @@
/*
* The MIT License (MIT)
*
* Copyright (c) 2019 Ha Thach (tinyusb.org)
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
* This file is part of the TinyUSB stack.
*/
/** \file
* \brief TBD
*
* \note TBD
*/
/** \ingroup TBD
* \defgroup TBD
* \brief TBD
*
* @{
*/
#ifndef _TUSB_TEST_DESCRIPTOR_H_
#define _TUSB_TEST_DESCRIPTOR_H_
#ifdef __cplusplus
extern "C" {
#endif
#include "common/common.h"
#include "class/hid.h"
#include "class/msc.h"
#include "class/cdc.h"
typedef struct
{
tusb_desc_configuration_t configuration;
#if 0 //&& IAD_DESC_REQUIRED
tusb_desc_interface_assoc_t CDC_IAD;
#endif
#if 0 //&& CFG_TUD_CDC
//CDC - Serial
//CDC Control Interface
tusb_desc_interface_t CDC_CCI_Interface;
CDC_HEADER_DESCRIPTOR CDC_Header;
CDC_ABSTRACT_CONTROL_MANAGEMENT_DESCRIPTOR CDC_ACM;
CDC_UNION_1SLAVE_DESCRIPTOR CDC_Union;
tusb_desc_endpoint_t CDC_NotificationEndpoint;
//CDC Data Interface
tusb_desc_interface_t CDC_DCI_Interface;
tusb_desc_endpoint_t CDC_DataOutEndpoint;
tusb_desc_endpoint_t CDC_DataInEndpoint;
#endif
//------------- HID Keyboard -------------//
tusb_desc_interface_t keyboard_interface;
tusb_hid_descriptor_hid_t keyboard_hid;
tusb_desc_endpoint_t keyboard_endpoint;
//------------- HID Mouse -------------//
tusb_desc_interface_t mouse_interface;
tusb_hid_descriptor_hid_t mouse_hid;
tusb_desc_endpoint_t mouse_endpoint;
//------------- Mass Storage -------------//
tusb_desc_interface_t msc_interface;
tusb_desc_endpoint_t msc_endpoint_in;
tusb_desc_endpoint_t msc_endpoint_out;
//------------- CDC Serial -------------//
//CDC Control Interface
tusb_desc_interface_t cdc_comm_interface;
cdc_desc_func_header_t cdc_header;
cdc_desc_func_acm_t cdc_acm;
cdc_desc_func_union_t cdc_union;
tusb_desc_endpoint_t cdc_endpoint_notification;
//CDC Data Interface
tusb_desc_interface_t cdc_data_interface;
tusb_desc_endpoint_t cdc_endpoint_out;
tusb_desc_endpoint_t cdc_endpoint_in;
unsigned char ConfigDescTermination;
} app_configuration_desc_t;
extern tusb_desc_device_t const desc_device;
extern app_configuration_desc_t const desc_configuration;
extern const uint8_t keyboard_report_descriptor[];
#ifdef __cplusplus
}
#endif
#endif /* _TUSB_TEST_DESCRIPTOR_H_ */
/** @} */

View File

@ -1,219 +0,0 @@
/*
* The MIT License (MIT)
*
* Copyright (c) 2019 Ha Thach (tinyusb.org)
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
* This file is part of the TinyUSB stack.
*/
//--------------------------------------------------------------------+
// INCLUDE
//--------------------------------------------------------------------+
#include "unity.h"
#include "common/common.h"
#include "hal.h"
#include "usbh_hcd.h"
#include "ehci.h"
#include "ehci_controller_fake.h"
//--------------------------------------------------------------------+
// MACRO CONSTANT TYPEDEF
//--------------------------------------------------------------------+
LPC_USB0_Type lpc_usb0;
LPC_USB1_Type lpc_usb1;
extern usbh_device_t _usbh_devices[CFG_TUSB_HOST_DEVICE_MAX+1];
//--------------------------------------------------------------------+
// IMPLEMENTATION
//--------------------------------------------------------------------+
void ehci_controller_init(void)
{
tu_memclr(&lpc_usb0, sizeof(LPC_USB0_Type));
tu_memclr(&lpc_usb1, sizeof(LPC_USB1_Type));
}
void ehci_controller_control_xfer_proceed(uint8_t dev_addr, uint8_t p_data[])
{
ehci_registers_t* const regs = get_operational_register( _usbh_devices[dev_addr].rhport );
ehci_qhd_t * p_qhd = get_control_qhd(dev_addr);
ehci_qtd_t * p_qtd_setup = get_control_qtds(dev_addr);
ehci_qtd_t * p_qtd_data = p_qtd_setup + 1;
ehci_qtd_t * p_qtd_status = p_qtd_setup + 2;
tusb_control_request_t const *p_request = (tusb_control_request_t *) p_qtd_setup->buffer[0];
if (p_request->wLength > 0 && p_request->bmRequestType_bit.direction == TUSB_DIR_DEV_TO_HOST)
{
memcpy(p_qtd_data, p_data, p_request->wLength);
}
//------------- retire all QTDs -------------//
p_qtd_setup->active = p_qtd_data->active = p_qtd_status->active = 0;
p_qhd->qtd_overlay = *p_qtd_status;
regs->usb_sts = EHCI_INT_MASK_NXP_ASYNC | EHCI_INT_MASK_NXP_PERIODIC;
hcd_isr( _usbh_devices[dev_addr].rhport );
}
void complete_qtd_in_qhd(ehci_qhd_t *p_qhd)
{
if ( !p_qhd->qtd_overlay.halted )
{
while(!p_qhd->qtd_overlay.next.terminate)
{
ehci_qtd_t* p_qtd = (ehci_qtd_t*) tu_align32(p_qhd->qtd_overlay.next.address);
p_qtd->active = 0;
p_qtd->total_bytes = 0;
p_qhd->qtd_overlay = *p_qtd;
}
}
}
bool complete_all_qtd_in_async(ehci_qhd_t *head)
{
ehci_qhd_t *p_qhd = head;
do
{
complete_qtd_in_qhd(p_qhd);
p_qhd = (ehci_qhd_t*) tu_align32(p_qhd->next.address);
}while(p_qhd != head); // stop if loop around
return true;
}
bool complete_all_qtd_in_period(ehci_link_t *head)
{
while(!head->terminate)
{
uint32_t queue_type = head->type;
head = (ehci_link_t*) tu_align32(head->address);
if ( queue_type == EHCI_QUEUE_ELEMENT_QHD)
{
complete_qtd_in_qhd( (ehci_qhd_t*) head );
}
}
return true;
}
void ehci_controller_run(uint8_t hostid)
{
//------------- Async List -------------//
ehci_registers_t* const regs = get_operational_register(hostid);
complete_all_qtd_in_async((ehci_qhd_t*) regs->async_list_base);
//------------- Period List -------------//
for(uint8_t i=1; i <= EHCI_FRAMELIST_SIZE; i *= 2)
{
complete_all_qtd_in_period( get_period_head(hostid, i) );
}
regs->usb_sts = EHCI_INT_MASK_NXP_ASYNC | EHCI_INT_MASK_NXP_PERIODIC;
hcd_isr(hostid);
}
void complete_1st_qtd_with_error(ehci_qhd_t* p_qhd, bool halted, bool xact_err)
{
if ( !p_qhd->qtd_overlay.halted )
{
if(!p_qhd->qtd_overlay.next.terminate) // TODO add active check
{
ehci_qtd_t* p_qtd = (ehci_qtd_t*) tu_align32(p_qhd->qtd_overlay.next.address);
p_qtd->active = 0;
p_qtd->halted = halted ? 1 : 0;
p_qtd->xact_err = xact_err ? 1 : 0;
p_qhd->qtd_overlay = *p_qtd;
}
}
}
void complete_list_with_error(uint8_t hostid, bool halted, bool xact_err)
{
//------------- Async List -------------//
ehci_registers_t* const regs = get_operational_register(hostid);
ehci_qhd_t *p_qhd = (ehci_qhd_t*) regs->async_list_base;
do
{
complete_1st_qtd_with_error(p_qhd, halted, xact_err);
p_qhd = (ehci_qhd_t*) tu_align32(p_qhd->next.address);
}while(p_qhd != get_async_head(hostid)); // stop if loop around
//------------- Period List -------------//
for(uint8_t i=1; i <= EHCI_FRAMELIST_SIZE; i *= 2)
{
ehci_link_t *head = get_period_head(hostid, i);
while(!head->terminate)
{
uint32_t queue_type = head->type;
head = (ehci_link_t*) tu_align32(head->address);
if ( queue_type == EHCI_QUEUE_ELEMENT_QHD)
{
complete_1st_qtd_with_error((ehci_qhd_t*) head, halted, xact_err);
}
}
}
regs->usb_sts = EHCI_INT_MASK_ERROR;
hcd_isr(hostid);
}
void ehci_controller_run_stall(uint8_t hostid)
{
complete_list_with_error(hostid, true, false);
}
void ehci_controller_run_error(uint8_t hostid)
{
complete_list_with_error(hostid, true, true);
}
void ehci_controller_device_plug(uint8_t hostid, tusb_speed_t speed)
{
ehci_registers_t* const regs = get_operational_register(hostid);
regs->usb_sts_bit.port_change_detect = 1;
regs->portsc_bit.connect_status_change = 1;
regs->portsc_bit.current_connect_status = 1;
regs->portsc_bit.nxp_port_speed = speed;
hcd_isr(hostid);
}
void ehci_controller_device_unplug(uint8_t hostid)
{
ehci_registers_t* const regs = get_operational_register(hostid);
regs->usb_sts_bit.port_change_detect = 1;
regs->portsc_bit.connect_status_change = 1;
regs->portsc_bit.current_connect_status = 0;
hcd_isr(hostid);
}

View File

@ -1,72 +0,0 @@
/*
* The MIT License (MIT)
*
* Copyright (c) 2019 Ha Thach (tinyusb.org)
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
* This file is part of the TinyUSB stack.
*/
/** \file
* \brief TBD
*
* \note TBD
*/
/** \ingroup TBD
* \defgroup TBD
* \brief TBD
*
* @{
*/
#ifndef _TUSB_EHCI_CONTROLLER_H_
#define _TUSB_EHCI_CONTROLLER_H_
#include "host/hcd.h"
#ifdef __cplusplus
extern "C" {
#endif
extern ehci_data_t ehci_data;
void ehci_controller_init(void);
void ehci_controller_run(uint8_t hostid);
void ehci_controller_run_error(uint8_t hostid);
void ehci_controller_control_xfer_proceed(uint8_t dev_addr, uint8_t p_data[]);
void ehci_controller_device_plug(uint8_t hostid, tusb_speed_t speed);
void ehci_controller_device_unplug(uint8_t hostid);
ehci_registers_t* get_operational_register(uint8_t hostid);
ehci_link_t* get_period_frame_list(uint8_t hostid);
ehci_qhd_t* get_async_head(uint8_t hostid);
ehci_link_t* get_period_head(uint8_t hostid, uint8_t interval_ms);
ehci_qhd_t* get_control_qhd(uint8_t dev_addr);
ehci_qtd_t* get_control_qtds(uint8_t dev_addr);
ehci_qhd_t* qhd_get_from_pipe_handle(pipe_handle_t pipe_hdl);
#ifdef __cplusplus
}
#endif
#endif /* _TUSB_EHCI_CONTROLLER_H_ */
/** @} */

View File

@ -1,61 +0,0 @@
/*
* The MIT License (MIT)
*
* Copyright (c) 2019 Ha Thach (tinyusb.org)
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
* This file is part of the TinyUSB stack.
*/
/** \file
* \brief TBD
*
* \note TBD
*/
/** \ingroup TBD
* \defgroup TBD
* \brief TBD
*
* @{
*/
#ifndef _TUSB_TUSB_CALLBACK_H_
#define _TUSB_TUSB_CALLBACK_H_
#ifdef __cplusplus
extern "C" {
#endif
#include "common/common.h"
#include "usbh.h"
//------------- core -------------//
uint8_t tusbh_device_attached_cb (tusb_desc_device_t const *p_desc_device) TU_ATTR_WEAK;
void tusbh_device_mount_succeed_cb (uint8_t dev_addr) TU_ATTR_WEAK;
void tusbh_device_mount_failed_cb(tusb_error_t error, tusb_desc_device_t const *p_desc_device) TU_ATTR_WEAK;
#ifdef __cplusplus
}
#endif
#endif /* _TUSB_TUSB_CALLBACK_H_ */
/** @} */

View File

@ -1,88 +0,0 @@
/*
* The MIT License (MIT)
*
* Copyright (c) 2019 Ha Thach (tinyusb.org)
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
* This file is part of the TinyUSB stack.
*/
#ifndef _TUSB_CONFIG_H_
#define _TUSB_CONFIG_H_
#ifdef __cplusplus
extern "C" {
#endif
//--------------------------------------------------------------------+
// CONTROLLER CONFIGURATION
//--------------------------------------------------------------------+
#define CFG_TUSB_RHPORT0_MODE (OPT_MODE_HOST | OPT_MODE_DEVICE)
#define CFG_TUSB_RHPORT1_MODE (OPT_MODE_NONE)
//--------------------------------------------------------------------+
// HOST CONFIGURATION
//--------------------------------------------------------------------+
#define CFG_TUSB_HOST_DEVICE_MAX 5 // TODO be a part of HUB config
//------------- CLASS -------------//
#define CFG_TUH_HUB 1
#define CFG_TUH_HID_KEYBOARD 1
#define CFG_TUH_HID_MOUSE 1
#define CFG_TUH_MSC 1
#define CFG_TUSB_HOST_HID_GENERIC 0
#define CFG_TUH_CDC 1
#define CFG_TUH_CDC_RNDIS 0
// Test support
#define TEST_CONTROLLER_HOST_START_INDEX \
( ((CONTROLLER_HOST_NUMBER == 1) && (CFG_TUSB_RHPORT1_MODE & OPT_MODE_HOST)) ? 1 : 0)
//--------------------------------------------------------------------+
// DEVICE CONFIGURATION
//--------------------------------------------------------------------+
#define CFG_TUD_ENDOINT0_SIZE 64
//------------- CLASS -------------//
#define CFG_TUD_CDC 1
#define CFG_TUD_MSC 1
#define CFG_TUD_HID_KEYBOARD 1
#define CFG_TUD_HID_MOUSE 1
//--------------------------------------------------------------------+
// COMMON CONFIGURATION
//--------------------------------------------------------------------+
#define CFG_TUSB_DEBUG 1
#define CFG_TUSB_OS OPT_OS_NONE
#define CFG_TUSB_MEM_SECTION
#ifdef __cplusplus
}
#endif
#define RANDOM(n) (rand()%(n))
#endif /* _TUSB_CONFIG_H_ */
/** @} */

View File

@ -1,86 +0,0 @@
/*
* The MIT License (MIT)
*
* Copyright (c) 2019 Ha Thach (tinyusb.org)
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
* This file is part of the TinyUSB stack.
*/
/** \file
* \brief TBD
*
* \note TBD
*/
/** \ingroup TBD
* \defgroup TBD
* \brief TBD
*
* @{
*/
#ifndef _TUSB_TYPE_HELPER_H_
#define _TUSB_TYPE_HELPER_H_
#ifdef __cplusplus
extern "C" {
#endif
#define TEST_ASSERT_PIPE_HANDLE(expected, actual)\
TEST_ASSERT_EQUAL(expected.dev_addr, actual.dev_addr);\
TEST_ASSERT_EQUAL(expected.xfer_type, actual.xfer_type);\
TEST_ASSERT_EQUAL(expected.index, actual.index);\
#define TEST_ASSERT_MEM_ZERO(buffer, size)\
do{\
for (uint32_t i=0; i<size; i++)\
TEST_ASSERT_EQUAL_HEX8(0, ((uint8_t*)buffer)[i]);\
}while(0)
#define TEST_ASSERT_STATUS( actual )\
TEST_ASSERT_EQUAL( TUSB_ERROR_NONE, (actual) )
// tu_log2 a value is equivalent to its highest set bit's position
#define BITFIELD_OFFSET_OF_MEMBER(struct_type, member, bitfield_member) \
({\
uint32_t value=0;\
struct_type str;\
tu_memclr((void*)&str, sizeof(struct_type));\
str.member.bitfield_member = 1;\
memcpy(&value, (void*)&str.member, sizeof(str.member));\
tu_log2( value );\
})
#define BITFIELD_OFFSET_OF_UINT32(struct_type, offset, bitfield_member) \
({\
struct_type str;\
tu_memclr(&str, sizeof(struct_type));\
str.bitfield_member = 1;\
tu_log2( ((uint32_t*) &str)[offset] );\
})
#ifdef __cplusplus
}
#endif
#endif /* _TUSB_TYPE_HELPER_H_ */
/** @} */

View File

@ -1,27 +0,0 @@
require 'constants'
class BuildInvokerUtils
constructor :configurator, :streaminator
def process_exception(exception, context, test_build=true)
if (exception.message =~ /Don't know how to build task '(.+)'/i)
error_header = "ERROR: Rake could not find file referenced in source"
error_header += " or test" if (test_build)
error_header += ": '#{$1}'. Possible stale dependency."
@streaminator.stderr_puts( error_header )
if (@configurator.project_use_deep_dependencies)
help_message = "Try fixing #include statements or adding missing file. Then run '#{REFRESH_TASK_ROOT}#{context.to_s}' task and try again."
@streaminator.stderr_puts( help_message )
end
raise ''
else
raise exception
end
end
end

View File

@ -1,42 +0,0 @@
class Cacheinator
constructor :cacheinator_helper, :file_path_utils, :file_wrapper, :yaml_wrapper
def cache_test_config(hash)
@yaml_wrapper.dump( @file_path_utils.form_test_build_cache_path( INPUT_CONFIGURATION_CACHE_FILE), hash )
end
def cache_release_config(hash)
@yaml_wrapper.dump( @file_path_utils.form_release_build_cache_path( INPUT_CONFIGURATION_CACHE_FILE ), hash )
end
def diff_cached_test_file( filepath )
cached_filepath = @file_path_utils.form_test_build_cache_path( filepath )
if (@file_wrapper.exist?( cached_filepath ) and (!@file_wrapper.compare( filepath, cached_filepath )))
@file_wrapper.cp(filepath, cached_filepath, {:preserve => false})
return filepath
elsif (!@file_wrapper.exist?( cached_filepath ))
@file_wrapper.cp(filepath, cached_filepath, {:preserve => false})
return filepath
end
return cached_filepath
end
def diff_cached_test_config?(hash)
cached_filepath = @file_path_utils.form_test_build_cache_path(INPUT_CONFIGURATION_CACHE_FILE)
return @cacheinator_helper.diff_cached_config?( cached_filepath, hash )
end
def diff_cached_release_config?(hash)
cached_filepath = @file_path_utils.form_release_build_cache_path(INPUT_CONFIGURATION_CACHE_FILE)
return @cacheinator_helper.diff_cached_config?( cached_filepath, hash )
end
end

View File

@ -1,12 +0,0 @@
class CacheinatorHelper
constructor :file_wrapper, :yaml_wrapper
def diff_cached_config?(cached_filepath, hash)
return true if ( not @file_wrapper.exist?(cached_filepath) )
return true if ( (@file_wrapper.exist?(cached_filepath)) and (!(@yaml_wrapper.load(cached_filepath) == hash)) )
return false
end
end

View File

@ -1,27 +0,0 @@
require 'rake'
ERR_MSG = <<EOF
I expected to see a project.yml file in the current directoy. Please create one
by hand or by using the 'ceedling' shell command.
EOF
def ceedling_dir
File.join(
File.dirname(__FILE__),
'..')
end
def builtin_ceedling_plugins_path
File.join(
ceedling_dir,
'plugins')
end
ceeling_lib_rakefile = File.join( ceedling_dir,
'lib',
'rakefile.rb')
if File.exists? "./project.yml"
load ceeling_lib_rakefile
else
$stderr.puts ERR_MSG
end

View File

@ -1,16 +0,0 @@
# @private
module Ceedling
module Version
# @private
GEM = "0.13.0"
# @private
CEEDLING = GEM
# @private
CEXCEPTION = "1.2.17"
# @private
CMOCK = "2.0.215"
# @private
UNITY = "2.1.0"
end
end

View File

@ -1,16 +0,0 @@
# @private
module Ceedling
module Version
# @private
GEM = "0.11.2"
# @private
CEEDLING = "<%= versions["CEEDLING"] %>"
# @private
CEXCEPTION = "<%= versions["CEXCEPTION"] %>"
# @private
CMOCK = "<%= versions["CMOCK"] %>"
# @private
UNITY = "<%= versions["UNITY"] %>"
end
end

View File

@ -1,15 +0,0 @@
require 'cmock'
class CmockBuilder
attr_accessor :cmock
def setup
@cmock = nil
end
def manufacture(cmock_config)
@cmock = CMock.new(cmock_config)
end
end

View File

@ -1,329 +0,0 @@
require 'defaults'
require 'constants'
require 'file_path_utils'
require 'deep_merge'
class Configurator
attr_reader :project_config_hash, :script_plugins, :rake_plugins
attr_accessor :project_logging, :project_debug, :project_verbosity, :sanity_checks
constructor(:configurator_setup, :configurator_builder, :configurator_plugins, :cmock_builder, :yaml_wrapper, :system_wrapper) do
@project_logging = false
@project_debug = false
@project_verbosity = Verbosity::NORMAL
@sanity_checks = TestResultsSanityChecks::NORMAL
end
def setup
# special copy of cmock config to provide to cmock for construction
@cmock_config_hash = {}
# note: project_config_hash is an instance variable so constants and accessors created
# in eval() statements in build() have something of proper scope and persistence to reference
@project_config_hash = {}
@project_config_hash_backup = {}
@script_plugins = []
@rake_plugins = []
end
def replace_flattened_config(config)
@project_config_hash.merge!(config)
@configurator_setup.build_constants_and_accessors(@project_config_hash, binding())
end
def store_config
@project_config_hash_backup = @project_config_hash.clone
end
def restore_config
@project_config_hash = @project_config_hash_backup
@configurator_setup.build_constants_and_accessors(@project_config_hash, binding())
end
def reset_defaults(config)
[:test_compiler,
:test_linker,
:test_fixture,
:test_includes_preprocessor,
:test_file_preprocessor,
:test_dependencies_generator,
:release_compiler,
:release_assembler,
:release_linker,
:release_dependencies_generator].each do |tool|
config[:tools].delete(tool) if (not (config[:tools][tool].nil?))
end
end
def populate_defaults(config)
new_config = DEFAULT_CEEDLING_CONFIG.deep_clone
new_config.deep_merge!(config)
config.replace(new_config)
@configurator_builder.populate_defaults( config, DEFAULT_TOOLS_TEST )
@configurator_builder.populate_defaults( config, DEFAULT_TOOLS_TEST_PREPROCESSORS ) if (config[:project][:use_test_preprocessor])
@configurator_builder.populate_defaults( config, DEFAULT_TOOLS_TEST_DEPENDENCIES ) if (config[:project][:use_deep_dependencies])
@configurator_builder.populate_defaults( config, DEFAULT_TOOLS_RELEASE ) if (config[:project][:release_build])
@configurator_builder.populate_defaults( config, DEFAULT_TOOLS_RELEASE_ASSEMBLER ) if (config[:project][:release_build] and config[:release_build][:use_assembly])
@configurator_builder.populate_defaults( config, DEFAULT_TOOLS_RELEASE_DEPENDENCIES ) if (config[:project][:release_build] and config[:project][:use_deep_dependencies])
end
def populate_cmock_defaults(config)
# cmock has its own internal defaults handling, but we need to set these specific values
# so they're present for the build environment to access;
# note: these need to end up in the hash given to initialize cmock for this to be successful
cmock = config[:cmock] || {}
# yes, we're duplicating the default mock_prefix in cmock, but it's because we need CMOCK_MOCK_PREFIX always available in Ceedling's environment
cmock[:mock_prefix] = 'Mock' if (cmock[:mock_prefix].nil?)
# just because strict ordering is the way to go
cmock[:enforce_strict_ordering] = true if (cmock[:enforce_strict_ordering].nil?)
cmock[:mock_path] = File.join(config[:project][:build_root], TESTS_BASE_PATH, 'mocks') if (cmock[:mock_path].nil?)
cmock[:verbosity] = @project_verbosity if (cmock[:verbosity].nil?)
cmock[:plugins] = [] if (cmock[:plugins].nil?)
cmock[:plugins].map! { |plugin| plugin.to_sym }
cmock[:plugins] << (:cexception) if (!cmock[:plugins].include?(:cexception) and (config[:project][:use_exceptions]))
cmock[:plugins].uniq!
cmock[:unity_helper] = false if (cmock[:unity_helper].nil?)
if (cmock[:unity_helper])
cmock[:includes] << File.basename(cmock[:unity_helper])
cmock[:includes].uniq!
end
@runner_config = cmock.merge(config[:test_runner] || {})
@cmock_builder.manufacture(cmock)
end
def get_runner_config
@runner_config
end
# grab tool names from yaml and insert into tool structures so available for error messages
# set up default values
def tools_setup(config)
config[:tools].each_key do |name|
tool = config[:tools][name]
# populate name if not given
tool[:name] = name.to_s if (tool[:name].nil?)
# populate stderr redirect option
tool[:stderr_redirect] = StdErrRedirect::NONE if (tool[:stderr_redirect].nil?)
# populate background execution option
tool[:background_exec] = BackgroundExec::NONE if (tool[:background_exec].nil?)
# populate optional option to control verification of executable in search paths
tool[:optional] = false if (tool[:optional].nil?)
end
end
def tools_supplement_arguments(config)
tools_name_prefix = 'tools_'
config[:tools].each_key do |name|
tool = @project_config_hash[(tools_name_prefix + name.to_s).to_sym]
# smoosh in extra arguments if specified at top-level of config (useful for plugins & default gcc tools)
# arguments are squirted in at beginning of list
top_level_tool = (tools_name_prefix + name.to_s).to_sym
if (not config[top_level_tool].nil?)
# adding and flattening is not a good idea: might over-flatten if there's array nesting in tool args
# use _with_index to preserve order
config[top_level_tool][:arguments].each_with_index { |arg, index| tool[:arguments].insert( index, arg ) }
end
end
end
def find_and_merge_plugins(config)
# plugins must be loaded before generic path evaluation & magic that happen later;
# perform path magic here as discrete step
config[:plugins][:load_paths].each do |path|
path.replace(@system_wrapper.module_eval(path)) if (path =~ RUBY_STRING_REPLACEMENT_PATTERN)
FilePathUtils::standardize(path)
end
paths_hash = @configurator_plugins.add_load_paths(config)
@rake_plugins = @configurator_plugins.find_rake_plugins(config)
@script_plugins = @configurator_plugins.find_script_plugins(config)
config_plugins = @configurator_plugins.find_config_plugins(config)
plugin_defaults = @configurator_plugins.find_plugin_defaults(config)
config_plugins.each do |plugin|
config.deep_merge( @yaml_wrapper.load(plugin) )
end
plugin_defaults.each do |defaults|
@configurator_builder.populate_defaults( config, @yaml_wrapper.load(defaults) )
end
# special plugin setting for results printing
config[:plugins][:display_raw_test_results] = true if (config[:plugins][:display_raw_test_results].nil?)
paths_hash.each_pair { |name, path| config[:plugins][name] = path }
end
def eval_environment_variables(config)
config[:environment].each do |hash|
key = hash.keys[0]
value = hash[key]
items = []
interstitial = ((key == :path) ? File::PATH_SEPARATOR : '')
items = ((value.class == Array) ? hash[key] : [value])
items.each { |item| item.replace( @system_wrapper.module_eval( item ) ) if (item =~ RUBY_STRING_REPLACEMENT_PATTERN) }
hash[key] = items.join( interstitial )
@system_wrapper.env_set( key.to_s.upcase, hash[key] )
end
end
def eval_paths(config)
# [:plugins]:[load_paths] already handled
paths = [ # individual paths that don't follow convention processed below
config[:project][:build_root],
config[:release_build][:artifacts]]
eval_path_list( paths )
config[:paths].each_pair { |collection, paths| eval_path_list( paths ) }
config[:files].each_pair { |collection, files| eval_path_list( paths ) }
# all other paths at secondary hash key level processed by convention:
# ex. [:toplevel][:foo_path] & [:toplevel][:bar_paths] are evaluated
config.each_pair { |parent, child| eval_path_list( collect_path_list( child ) ) }
end
def standardize_paths(config)
# [:plugins]:[load_paths] already handled
paths = [ # individual paths that don't follow convention processed below
config[:project][:build_root],
config[:release_build][:artifacts]] # cmock path in case it was explicitly set in config
paths.flatten.each { |path| FilePathUtils::standardize( path ) }
config[:paths].each_pair do |collection, paths|
paths.each{|path| FilePathUtils::standardize( path )}
# ensure that list is an array (i.e. handle case of list being a single string)
config[:paths][collection] = [paths].flatten
end
config[:files].each_pair { |collection, files| files.each{ |path| FilePathUtils::standardize( path ) } }
config[:tools].each_pair { |tool, config| FilePathUtils::standardize( config[:executable] ) }
# all other paths at secondary hash key level processed by convention:
# ex. [:toplevel][:foo_path] & [:toplevel][:bar_paths] are standardized
config.each_pair do |parent, child|
collect_path_list( child ).each { |path| FilePathUtils::standardize( path ) }
end
end
def validate(config)
# collect felonies and go straight to jail
raise if (not @configurator_setup.validate_required_sections( config ))
# collect all misdemeanors, everybody on probation
blotter = []
blotter << @configurator_setup.validate_required_section_values( config )
blotter << @configurator_setup.validate_paths( config )
blotter << @configurator_setup.validate_tools( config )
blotter << @configurator_setup.validate_plugins( config )
raise if (blotter.include?( false ))
end
# create constants and accessors (attached to this object) from given hash
def build(config, *keys)
# create flattened & expanded configuration hash
built_config = @configurator_setup.build_project_config( config, @configurator_builder.flattenify( config ) )
@project_config_hash = built_config.clone
store_config()
@configurator_setup.build_constants_and_accessors(built_config, binding())
# top-level keys disappear when we flatten, so create global constants & accessors to any specified keys
keys.each do |key|
hash = { key => config[key] }
@configurator_setup.build_constants_and_accessors(hash, binding())
end
end
# add to constants and accessors as post build step
def build_supplement(config_base, config_more)
# merge in our post-build additions to base configuration hash
config_base.deep_merge!( config_more )
# flatten our addition hash
config_more_flattened = @configurator_builder.flattenify( config_more )
# merge our flattened hash with built hash from previous build
@project_config_hash.deep_merge!( config_more_flattened )
store_config()
# create more constants and accessors
@configurator_setup.build_constants_and_accessors(config_more_flattened, binding())
# recreate constants & update accessors with new merged, base values
config_more.keys.each do |key|
hash = { key => config_base[key] }
@configurator_setup.build_constants_and_accessors(hash, binding())
end
end
def insert_rake_plugins(plugins)
plugins.each do |plugin|
@project_config_hash[:project_rakefile_component_files] << plugin
end
end
### private ###
private
def collect_path_list( container )
paths = []
container.each_key { |key| paths << container[key] if (key.to_s =~ /_path(s)?$/) } if (container.class == Hash)
return paths.flatten
end
def eval_path_list( paths )
paths.flatten.each do |path|
path.replace( @system_wrapper.module_eval( path ) ) if (path =~ RUBY_STRING_REPLACEMENT_PATTERN)
end
end
end

View File

@ -1,437 +0,0 @@
require 'rubygems'
require 'rake' # for ext() method
require 'file_path_utils' # for class methods
require 'defaults'
require 'constants' # for Verbosity constants class & base file paths
class ConfiguratorBuilder
constructor :file_system_utils, :file_wrapper, :system_wrapper
def build_global_constants(config)
config.each_pair do |key, value|
formatted_key = key.to_s.upcase
# undefine global constant if it already exists
Object.send(:remove_const, formatted_key.to_sym) if @system_wrapper.constants_include?(formatted_key)
# create global constant
Object.module_eval("#{formatted_key} = value")
end
end
def build_accessor_methods(config, context)
config.each_pair do |key, value|
# fill configurator object with accessor methods
eval("def #{key.to_s.downcase}() return @project_config_hash[:#{key.to_s}] end", context)
end
end
# create a flattened hash from the original configuration structure
def flattenify(config)
new_hash = {}
config.each_key do | parent |
# gracefully handle empty top-level entries
next if (config[parent].nil?)
case config[parent]
when Array
config[parent].each do |hash|
key = "#{parent.to_s.downcase}_#{hash.keys[0].to_s.downcase}".to_sym
new_hash[key] = hash[hash.keys[0]]
end
when Hash
config[parent].each_pair do | child, value |
key = "#{parent.to_s.downcase}_#{child.to_s.downcase}".to_sym
new_hash[key] = value
end
# handle entries with no children, only values
else
new_hash["#{parent.to_s.downcase}".to_sym] = config[parent]
end
end
return new_hash
end
def populate_defaults(config, defaults)
defaults.keys.sort.each do |section|
defaults[section].keys.sort.each do |entry|
config[section][entry] = defaults[section][entry].deep_clone if (config[section].nil? or config[section][entry].nil?)
end
end
end
def clean(in_hash)
# ensure that include files inserted into test runners have file extensions & proper ones at that
in_hash[:test_runner_includes].map!{|include| include.ext(in_hash[:extension_header])}
end
def set_build_paths(in_hash)
out_hash = {}
project_build_artifacts_root = File.join(in_hash[:project_build_root], 'artifacts')
project_build_tests_root = File.join(in_hash[:project_build_root], TESTS_BASE_PATH)
project_build_release_root = File.join(in_hash[:project_build_root], RELEASE_BASE_PATH)
paths = [
[:project_build_artifacts_root, project_build_artifacts_root, true ],
[:project_build_tests_root, project_build_tests_root, true ],
[:project_build_release_root, project_build_release_root, in_hash[:project_release_build] ],
[:project_test_artifacts_path, File.join(project_build_artifacts_root, TESTS_BASE_PATH), true ],
[:project_test_runners_path, File.join(project_build_tests_root, 'runners'), true ],
[:project_test_results_path, File.join(project_build_tests_root, 'results'), true ],
[:project_test_build_output_path, File.join(project_build_tests_root, 'out'), true ],
[:project_test_build_cache_path, File.join(project_build_tests_root, 'cache'), true ],
[:project_test_dependencies_path, File.join(project_build_tests_root, 'dependencies'), true ],
[:project_release_artifacts_path, File.join(project_build_artifacts_root, RELEASE_BASE_PATH), in_hash[:project_release_build] ],
[:project_release_build_cache_path, File.join(project_build_release_root, 'cache'), in_hash[:project_release_build] ],
[:project_release_build_output_path, File.join(project_build_release_root, 'out'), in_hash[:project_release_build] ],
[:project_release_build_output_asm_path, File.join(project_build_release_root, 'out', 'asm'), in_hash[:project_release_build] ],
[:project_release_build_output_c_path, File.join(project_build_release_root, 'out', 'c'), in_hash[:project_release_build] ],
[:project_release_dependencies_path, File.join(project_build_release_root, 'dependencies'), in_hash[:project_release_build] ],
[:project_log_path, File.join(in_hash[:project_build_root], 'logs'), true ],
[:project_temp_path, File.join(in_hash[:project_build_root], 'temp'), true ],
[:project_test_preprocess_includes_path, File.join(project_build_tests_root, 'preprocess/includes'), in_hash[:project_use_test_preprocessor] ],
[:project_test_preprocess_files_path, File.join(project_build_tests_root, 'preprocess/files'), in_hash[:project_use_test_preprocessor] ],
]
out_hash[:project_build_paths] = []
# fetch already set mock path
out_hash[:project_build_paths] << in_hash[:cmock_mock_path] if (in_hash[:project_use_mocks])
paths.each do |path|
build_path_name = path[0]
build_path = path[1]
build_path_add_condition = path[2]
# insert path into build paths if associated with true condition
out_hash[:project_build_paths] << build_path if build_path_add_condition
# set path symbol name and path for each entry in paths array
out_hash[build_path_name] = build_path
end
return out_hash
end
def set_force_build_filepaths(in_hash)
out_hash = {}
out_hash[:project_test_force_rebuild_filepath] = File.join( in_hash[:project_test_dependencies_path], 'force_build' )
out_hash[:project_release_force_rebuild_filepath] = File.join( in_hash[:project_release_dependencies_path], 'force_build' ) if (in_hash[:project_release_build])
return out_hash
end
def set_rakefile_components(in_hash)
out_hash = {
:project_rakefile_component_files =>
[File.join(CEEDLING_LIB, 'tasks_base.rake'),
File.join(CEEDLING_LIB, 'tasks_filesystem.rake'),
File.join(CEEDLING_LIB, 'tasks_tests.rake'),
File.join(CEEDLING_LIB, 'tasks_vendor.rake'),
File.join(CEEDLING_LIB, 'rules_tests.rake')]}
out_hash[:project_rakefile_component_files] << File.join(CEEDLING_LIB, 'rules_cmock.rake') if (in_hash[:project_use_mocks])
out_hash[:project_rakefile_component_files] << File.join(CEEDLING_LIB, 'rules_preprocess.rake') if (in_hash[:project_use_test_preprocessor])
out_hash[:project_rakefile_component_files] << File.join(CEEDLING_LIB, 'rules_tests_deep_dependencies.rake') if (in_hash[:project_use_deep_dependencies])
out_hash[:project_rakefile_component_files] << File.join(CEEDLING_LIB, 'tasks_tests_deep_dependencies.rake') if (in_hash[:project_use_deep_dependencies])
out_hash[:project_rakefile_component_files] << File.join(CEEDLING_LIB, 'rules_release_deep_dependencies.rake') if (in_hash[:project_release_build] and in_hash[:project_use_deep_dependencies])
out_hash[:project_rakefile_component_files] << File.join(CEEDLING_LIB, 'rules_release.rake') if (in_hash[:project_release_build])
out_hash[:project_rakefile_component_files] << File.join(CEEDLING_LIB, 'tasks_release_deep_dependencies.rake') if (in_hash[:project_release_build] and in_hash[:project_use_deep_dependencies])
out_hash[:project_rakefile_component_files] << File.join(CEEDLING_LIB, 'tasks_release.rake') if (in_hash[:project_release_build])
return out_hash
end
def set_library_build_info_filepaths(hash)
# Notes:
# - Dependency on a change to our input configuration hash is handled elsewhere as it is
# dynamically formed during ceedling's execution
# - Compiled vendor dependencies like cmock.o, unity.o, cexception.o are handled below;
# here we're interested only in ceedling-based code generation dependencies
ceedling_build_info_filepath = File.join(CEEDLING_RELEASE, 'build.info')
cmock_build_info_filepath = FilePathUtils::form_ceedling_vendor_path('cmock/release', 'build.info')
out_hash = {
:ceedling_build_info_filepath => ceedling_build_info_filepath,
:cmock_build_info_filepath => cmock_build_info_filepath
}
return out_hash
end
def set_release_target(in_hash)
return {} if (not in_hash[:project_release_build])
release_target_file = ((in_hash[:release_build_output].nil?) ? (DEFAULT_RELEASE_TARGET_NAME.ext(in_hash[:extension_executable])) : in_hash[:release_build_output])
release_map_file = ((in_hash[:release_build_output].nil?) ? (DEFAULT_RELEASE_TARGET_NAME.ext(in_hash[:extension_map])) : in_hash[:release_build_output].ext(in_hash[:extension_map]))
return {
# tempted to make a helper method in file_path_utils? stop right there, pal. you'll introduce a cyclical dependency
:project_release_build_target => File.join(in_hash[:project_build_release_root], release_target_file),
:project_release_build_map => File.join(in_hash[:project_build_release_root], release_map_file)
}
end
def collect_project_options(in_hash)
options = []
in_hash[:project_options_paths].each do |path|
options << @file_wrapper.directory_listing( File.join(path, '*.yml') )
end
return {
:collection_project_options => options.flatten
}
end
def expand_all_path_globs(in_hash)
out_hash = {}
path_keys = []
in_hash.each_key do |key|
next if (not key.to_s[0..4] == 'paths')
path_keys << key
end
# sorted to provide assured order of traversal in test calls on mocks
path_keys.sort.each do |key|
out_hash["collection_#{key.to_s}".to_sym] = @file_system_utils.collect_paths( in_hash[key] )
end
return out_hash
end
def collect_source_and_include_paths(in_hash)
return {
:collection_paths_source_and_include =>
( in_hash[:collection_paths_source] +
in_hash[:collection_paths_include] ).select {|x| File.directory?(x)}
}
end
def collect_source_include_vendor_paths(in_hash)
extra_paths = []
extra_paths << FilePathUtils::form_ceedling_vendor_path(CEXCEPTION_LIB_PATH) if (in_hash[:project_use_exceptions])
return {
:collection_paths_source_include_vendor =>
in_hash[:collection_paths_source_and_include] +
extra_paths
}
end
def collect_test_support_source_include_paths(in_hash)
return {
:collection_paths_test_support_source_include =>
(in_hash[:collection_paths_test] +
in_hash[:collection_paths_support] +
in_hash[:collection_paths_source] +
in_hash[:collection_paths_include] ).select {|x| File.directory?(x)}
}
end
def collect_vendor_paths(in_hash)
return {:collection_paths_vendor => get_vendor_paths(in_hash)}
end
def collect_test_support_source_include_vendor_paths(in_hash)
return {
:collection_paths_test_support_source_include_vendor =>
in_hash[:collection_paths_test_support_source_include] +
get_vendor_paths(in_hash)
}
end
def collect_tests(in_hash)
all_tests = @file_wrapper.instantiate_file_list
in_hash[:collection_paths_test].each do |path|
all_tests.include( File.join(path, "#{in_hash[:project_test_file_prefix]}*#{in_hash[:extension_source]}") )
end
@file_system_utils.revise_file_list( all_tests, in_hash[:files_test] )
return {:collection_all_tests => all_tests}
end
def collect_assembly(in_hash)
all_assembly = @file_wrapper.instantiate_file_list
return {:collection_all_assembly => all_assembly} if (not in_hash[:release_build_use_assembly])
in_hash[:collection_paths_source].each do |path|
all_assembly.include( File.join(path, "*#{in_hash[:extension_assembly]}") )
end
@file_system_utils.revise_file_list( all_assembly, in_hash[:files_assembly] )
return {:collection_all_assembly => all_assembly}
end
def collect_source(in_hash)
all_source = @file_wrapper.instantiate_file_list
in_hash[:collection_paths_source].each do |path|
if File.exists?(path) and not File.directory?(path)
all_source.include( path )
else
all_source.include( File.join(path, "*#{in_hash[:extension_source]}") )
end
end
@file_system_utils.revise_file_list( all_source, in_hash[:files_source] )
return {:collection_all_source => all_source}
end
def collect_headers(in_hash)
all_headers = @file_wrapper.instantiate_file_list
paths =
in_hash[:collection_paths_test] +
in_hash[:collection_paths_support] +
in_hash[:collection_paths_source] +
in_hash[:collection_paths_include]
paths.each do |path|
all_headers.include( File.join(path, "*#{in_hash[:extension_header]}") )
end
@file_system_utils.revise_file_list( all_headers, in_hash[:files_include] )
return {:collection_all_headers => all_headers}
end
def collect_all_existing_compilation_input(in_hash)
all_input = @file_wrapper.instantiate_file_list
paths =
in_hash[:collection_paths_test] +
in_hash[:collection_paths_support] +
in_hash[:collection_paths_source] +
in_hash[:collection_paths_include] +
[FilePathUtils::form_ceedling_vendor_path(UNITY_LIB_PATH)]
paths << FilePathUtils::form_ceedling_vendor_path(CEXCEPTION_LIB_PATH) if (in_hash[:project_use_exceptions])
paths << FilePathUtils::form_ceedling_vendor_path(CMOCK_LIB_PATH) if (in_hash[:project_use_mocks])
paths.each do |path|
all_input.include( File.join(path, "*#{in_hash[:extension_header]}") )
if File.exists?(path) and not File.directory?(path)
all_input.include( path )
else
all_input.include( File.join(path, "*#{in_hash[:extension_source]}") )
end
end
@file_system_utils.revise_file_list( all_input, in_hash[:files_test] )
@file_system_utils.revise_file_list( all_input, in_hash[:files_support] )
@file_system_utils.revise_file_list( all_input, in_hash[:files_source] )
@file_system_utils.revise_file_list( all_input, in_hash[:files_include] )
# finding assembly files handled explicitly through other means
return {:collection_all_existing_compilation_input => all_input}
end
def collect_test_and_vendor_defines(in_hash)
test_defines = in_hash[:defines_test].clone
test_defines.concat(in_hash[:unity_defines])
test_defines.concat(in_hash[:cmock_defines]) if (in_hash[:project_use_mocks])
test_defines.concat(in_hash[:cexception_defines]) if (in_hash[:project_use_exceptions])
return {:collection_defines_test_and_vendor => test_defines}
end
def collect_release_and_vendor_defines(in_hash)
release_defines = in_hash[:defines_release].clone
release_defines.concat(in_hash[:cexception_defines]) if (in_hash[:project_use_exceptions])
return {:collection_defines_release_and_vendor => release_defines}
end
def collect_release_artifact_extra_link_objects(in_hash)
objects = []
# no build paths here so plugins can remap if necessary (i.e. path mapping happens at runtime)
objects << CEXCEPTION_C_FILE.ext( in_hash[:extension_object] ) if (in_hash[:project_use_exceptions])
return {:collection_release_artifact_extra_link_objects => objects}
end
def collect_test_fixture_extra_link_objects(in_hash)
# Note: Symbols passed to compiler at command line can change Unity and CException behavior / configuration;
# we also handle those dependencies elsewhere in compilation dependencies
objects = [UNITY_C_FILE]
# we don't include paths here because use of plugins or mixing different compilers may require different build paths
objects << CEXCEPTION_C_FILE if (in_hash[:project_use_exceptions])
objects << CMOCK_C_FILE if (in_hash[:project_use_mocks])
# if we're using mocks & a unity helper is defined & that unity helper includes a source file component (not only a header of macros),
# then link in the unity_helper object file too
if ( in_hash[:project_use_mocks] and
in_hash[:cmock_unity_helper] and
@file_wrapper.exist?(in_hash[:cmock_unity_helper].ext(in_hash[:extension_source])) )
objects << File.basename(in_hash[:cmock_unity_helper])
end
# no build paths here so plugins can remap if necessary (i.e. path mapping happens at runtime)
objects.map! { |object| object.ext(in_hash[:extension_object]) }
return { :collection_test_fixture_extra_link_objects => objects }
end
private
def get_vendor_paths(in_hash)
vendor_paths = []
vendor_paths << FilePathUtils::form_ceedling_vendor_path(UNITY_LIB_PATH)
vendor_paths << FilePathUtils::form_ceedling_vendor_path(CEXCEPTION_LIB_PATH) if (in_hash[:project_use_exceptions])
vendor_paths << FilePathUtils::form_ceedling_vendor_path(CMOCK_LIB_PATH) if (in_hash[:project_use_mocks])
vendor_paths << in_hash[:cmock_mock_path] if (in_hash[:project_use_mocks])
return vendor_paths
end
end

View File

@ -1,124 +0,0 @@
require 'constants'
class ConfiguratorPlugins
constructor :stream_wrapper, :file_wrapper, :system_wrapper
attr_reader :rake_plugins, :script_plugins
def setup
@rake_plugins = []
@script_plugins = []
end
def add_load_paths(config)
plugin_paths = {}
config[:plugins][:load_paths].each do |root|
@system_wrapper.add_load_path( root ) if ( not @file_wrapper.directory_listing( File.join( root, '*.rb' ) ).empty? )
config[:plugins][:enabled].each do |plugin|
path = File.join(root, plugin, "lib")
old_path = File.join( root, plugin )
if ( not @file_wrapper.directory_listing( File.join( path, '*.rb' ) ).empty? )
plugin_paths[(plugin + '_path').to_sym] = path
@system_wrapper.add_load_path( path )
elsif ( not @file_wrapper.directory_listing( File.join( old_path, '*.rb' ) ).empty? )
plugin_paths[(plugin + '_path').to_sym] = old_path
@system_wrapper.add_load_path( old_path )
end
end
end
return plugin_paths
end
# gather up and return .rake filepaths that exist on-disk
def find_rake_plugins(config)
plugins_with_path = []
config[:plugins][:load_paths].each do |root|
config[:plugins][:enabled].each do |plugin|
rake_plugin_path = File.join(root, plugin, "#{plugin}.rake")
if (@file_wrapper.exist?(rake_plugin_path))
plugins_with_path << rake_plugin_path
@rake_plugins << plugin
end
end
end
return plugins_with_path
end
# gather up and return just names of .rb classes that exist on-disk
def find_script_plugins(config)
config[:plugins][:load_paths].each do |root|
config[:plugins][:enabled].each do |plugin|
script_plugin_path = File.join(root, plugin, "lib", "#{plugin}.rb")
# Add the old path here to support legacy style. Eventaully remove.
old_script_plugin_path = File.join(root, plugin, "#{plugin}.rb")
if @file_wrapper.exist?(script_plugin_path) or @file_wrapper.exist?(old_script_plugin_path)
@script_plugins << plugin
end
# Print depreciation warning.
if @file_wrapper.exist?(old_script_plugin_path)
$stderr.puts "WARNING: Depreciated plugin style used in #{plugin}. Use new directory structure!"
end
end
end
return @script_plugins
end
# gather up and return configuration .yml filepaths that exist on-disk
def find_config_plugins(config)
plugins_with_path = []
config[:plugins][:load_paths].each do |root|
config[:plugins][:enabled].each do |plugin|
config_plugin_path = File.join(root, plugin, "config", "#{plugin}.yml")
# Add the old path here to support legacy style. Eventaully remove.
old_config_plugin_path = File.join(root, plugin, "#{plugin}.yml")
if @file_wrapper.exist?(config_plugin_path)
plugins_with_path << config_plugin_path
elsif @file_wrapper.exist?(old_config_plugin_path)
# there's a warning printed for this in find_script_plugins
plugins_with_path << old_config_plugin_path
end
end
end
return plugins_with_path
end
# gather up and return default .yml filepaths that exist on-disk
def find_plugin_defaults(config)
defaults_with_path = []
config[:plugins][:load_paths].each do |root|
config[:plugins][:enabled].each do |plugin|
default_path = File.join(root, plugin, 'config', 'defaults.yml')
old_default_path = File.join(root, plugin, 'defaults.yml')
if @file_wrapper.exist?(default_path)
defaults_with_path << default_path
elsif @file_wrapper.exist?(old_default_path)
defaults_with_path << old_default_path
end
end
end
return defaults_with_path
end
end

View File

@ -1,124 +0,0 @@
# add sort-ability to symbol so we can order keys array in hash for test-ability
class Symbol
include Comparable
def <=>(other)
self.to_s <=> other.to_s
end
end
class ConfiguratorSetup
constructor :configurator_builder, :configurator_validator, :configurator_plugins, :stream_wrapper
def build_project_config(config, flattened_config)
### flesh out config
@configurator_builder.clean(flattened_config)
### add to hash values we build up from configuration & file system contents
flattened_config.merge!(@configurator_builder.set_build_paths(flattened_config))
flattened_config.merge!(@configurator_builder.set_force_build_filepaths(flattened_config))
flattened_config.merge!(@configurator_builder.set_rakefile_components(flattened_config))
flattened_config.merge!(@configurator_builder.set_library_build_info_filepaths(flattened_config))
flattened_config.merge!(@configurator_builder.set_release_target(flattened_config))
flattened_config.merge!(@configurator_builder.collect_project_options(flattened_config))
### iterate through all entries in paths section and expand any & all globs to actual paths
flattened_config.merge!(@configurator_builder.expand_all_path_globs(flattened_config))
flattened_config.merge!(@configurator_builder.collect_vendor_paths(flattened_config))
flattened_config.merge!(@configurator_builder.collect_source_and_include_paths(flattened_config))
flattened_config.merge!(@configurator_builder.collect_source_include_vendor_paths(flattened_config))
flattened_config.merge!(@configurator_builder.collect_test_support_source_include_paths(flattened_config))
flattened_config.merge!(@configurator_builder.collect_test_support_source_include_vendor_paths(flattened_config))
flattened_config.merge!(@configurator_builder.collect_tests(flattened_config))
flattened_config.merge!(@configurator_builder.collect_assembly(flattened_config))
flattened_config.merge!(@configurator_builder.collect_source(flattened_config))
flattened_config.merge!(@configurator_builder.collect_headers(flattened_config))
flattened_config.merge!(@configurator_builder.collect_all_existing_compilation_input(flattened_config))
flattened_config.merge!(@configurator_builder.collect_test_and_vendor_defines(flattened_config))
flattened_config.merge!(@configurator_builder.collect_release_and_vendor_defines(flattened_config))
flattened_config.merge!(@configurator_builder.collect_release_artifact_extra_link_objects(flattened_config))
flattened_config.merge!(@configurator_builder.collect_test_fixture_extra_link_objects(flattened_config))
return flattened_config
end
def build_constants_and_accessors(config, context)
@configurator_builder.build_global_constants(config)
@configurator_builder.build_accessor_methods(config, context)
end
def validate_required_sections(config)
validation = []
validation << @configurator_validator.exists?(config, :project)
validation << @configurator_validator.exists?(config, :paths)
return false if (validation.include?(false))
return true
end
def validate_required_section_values(config)
validation = []
validation << @configurator_validator.exists?(config, :project, :build_root)
validation << @configurator_validator.exists?(config, :paths, :test)
validation << @configurator_validator.exists?(config, :paths, :source)
return false if (validation.include?(false))
return true
end
def validate_paths(config)
validation = []
validation << @configurator_validator.validate_filepath(config, :project, :build_root)
validation << @configurator_validator.validate_filepath(config, :cmock, :unity_helper) if config[:cmock][:unity_helper]
config[:project][:options_paths].each do |path|
validation << @configurator_validator.validate_filepath_simple( path, :project, :options_paths )
end
config[:plugins][:load_paths].each do |path|
validation << @configurator_validator.validate_filepath_simple( path, :plugins, :load_paths )
end
config[:paths].keys.sort.each do |key|
validation << @configurator_validator.validate_path_list(config, :paths, key)
end
return false if (validation.include?(false))
return true
end
def validate_tools(config)
validation = []
config[:tools].keys.sort.each do |key|
validation << @configurator_validator.exists?(config, :tools, key, :executable)
validation << @configurator_validator.validate_executable_filepath(config, :tools, key, :executable) if (not config[:tools][key][:optional])
validation << @configurator_validator.validate_tool_stderr_redirect(config, :tools, key)
end
return false if (validation.include?(false))
return true
end
def validate_plugins(config)
missing_plugins =
Set.new( config[:plugins][:enabled] ) -
Set.new( @configurator_plugins.rake_plugins ) -
Set.new( @configurator_plugins.script_plugins )
missing_plugins.each do |plugin|
@stream_wrapper.stderr_puts("ERROR: Ceedling plugin '#{plugin}' contains no rake or ruby class entry point. (Misspelled or missing files?)")
end
return ( (missing_plugins.size > 0) ? false : true )
end
end

View File

@ -1,184 +0,0 @@
require 'rubygems'
require 'rake' # for ext()
require 'constants'
require 'tool_executor' # for argument replacement pattern
require 'file_path_utils' # for glob handling class methods
class ConfiguratorValidator
constructor :file_wrapper, :stream_wrapper, :system_wrapper
# walk into config hash verify existence of data at key depth
def exists?(config, *keys)
hash = retrieve_value(config, keys)
exist = !hash[:value].nil?
if (not exist)
# no verbosity checking since this is lowest level anyhow & verbosity checking depends on configurator
@stream_wrapper.stderr_puts("ERROR: Required config file entry #{format_key_sequence(keys, hash[:depth])} does not exist.")
end
return exist
end
# walk into config hash. verify directory path(s) at given key depth
def validate_path_list(config, *keys)
hash = retrieve_value(config, keys)
list = hash[:value]
# return early if we couldn't walk into hash and find a value
return false if (list.nil?)
path_list = []
exist = true
case list
when String then path_list << list
when Array then path_list = list
end
path_list.each do |path|
base_path = FilePathUtils::extract_path(path) # lop off add/subtract notation & glob specifiers
if (not @file_wrapper.exist?(base_path))
# no verbosity checking since this is lowest level anyhow & verbosity checking depends on configurator
@stream_wrapper.stderr_puts("ERROR: Config path #{format_key_sequence(keys, hash[:depth])}['#{base_path}'] does not exist on disk.")
exist = false
end
end
return exist
end
# simple path verification
def validate_filepath_simple(path, *keys)
validate_path = path
if (not @file_wrapper.exist?(validate_path))
# no verbosity checking since this is lowest level anyhow & verbosity checking depends on configurator
@stream_wrapper.stderr_puts("ERROR: Config path '#{validate_path}' associated with #{format_key_sequence(keys, keys.size)} does not exist on disk.")
return false
end
return true
end
# walk into config hash. verify specified file exists.
def validate_filepath(config, *keys)
hash = retrieve_value(config, keys)
filepath = hash[:value]
# return early if we couldn't walk into hash and find a value
return false if (filepath.nil?)
# skip everything if we've got an argument replacement pattern
return true if (filepath =~ TOOL_EXECUTOR_ARGUMENT_REPLACEMENT_PATTERN)
if (not @file_wrapper.exist?(filepath))
# no verbosity checking since this is lowest level anyhow & verbosity checking depends on configurator
@stream_wrapper.stderr_puts("ERROR: Config filepath #{format_key_sequence(keys, hash[:depth])}['#{filepath}'] does not exist on disk.")
return false
end
return true
end
# walk into config hash. verify specified file exists.
def validate_executable_filepath(config, *keys)
exe_extension = config[:extension][:executable]
hash = retrieve_value(config, keys)
filepath = hash[:value]
# return early if we couldn't walk into hash and find a value
return false if (filepath.nil?)
# skip everything if we've got an argument replacement pattern
return true if (filepath =~ TOOL_EXECUTOR_ARGUMENT_REPLACEMENT_PATTERN)
# if there's no path included, verify file exists somewhere in system search paths
if (not filepath.include?('/'))
exists = false
@system_wrapper.search_paths.each do |path|
if (@file_wrapper.exist?( File.join(path, filepath)) )
exists = true
break
end
if (@file_wrapper.exist?( (File.join(path, filepath)).ext( exe_extension ) ))
exists = true
break
elsif (@system_wrapper.windows? and @file_wrapper.exist?( (File.join(path, filepath)).ext( EXTENSION_WIN_EXE ) ))
exists = true
break
end
end
if (not exists)
# no verbosity checking since this is lowest level anyhow & verbosity checking depends on configurator
@stream_wrapper.stderr_puts("ERROR: Config filepath #{format_key_sequence(keys, hash[:depth])}['#{filepath}'] does not exist in system search paths.")
return false
end
# if there is a path included, check that explicit filepath exists
else
if (not @file_wrapper.exist?(filepath))
# no verbosity checking since this is lowest level anyhow & verbosity checking depends on configurator
@stream_wrapper.stderr_puts("ERROR: Config filepath #{format_key_sequence(keys, hash[:depth])}['#{filepath}'] does not exist on disk.")
return false
end
end
return true
end
def validate_tool_stderr_redirect(config, tools, tool)
redirect = config[tools][tool][:stderr_redirect]
if (redirect.class == Symbol)
# map constants and force to array of strings for runtime universality across ruby versions
if (not StdErrRedirect.constants.map{|constant| constant.to_s}.include?(redirect.to_s.upcase))
error = "ERROR: [:#{tools}][:#{tool}][:stderr_redirect][:#{redirect}] is not a recognized option " +
"{#{StdErrRedirect.constants.map{|constant| ':' + constant.to_s.downcase}.join(', ')}}."
@stream_wrapper.stderr_puts(error)
return false
end
end
return true
end
private #########################################
def retrieve_value(config, keys)
value = nil
hash = config
depth = 0
# walk into hash & extract value at requested key sequence
keys.each do |symbol|
depth += 1
if (not hash[symbol].nil?)
hash = hash[symbol]
value = hash
else
value = nil
break
end
end
return {:value => value, :depth => depth}
end
def format_key_sequence(keys, depth)
walked_keys = keys.slice(0, depth)
formatted_keys = walked_keys.map{|key| "[:#{key.to_s}]"}
return formatted_keys.join
end
end

View File

@ -1,91 +0,0 @@
class Verbosity
SILENT = 0 # as silent as possible (though there are some messages that must be spit out)
ERRORS = 1 # only errors
COMPLAIN = 2 # spit out errors and warnings/notices
NORMAL = 3 # errors, warnings/notices, standard status messages
OBNOXIOUS = 4 # all messages including extra verbose output (used for lite debugging / verification)
DEBUG = 5 # special extra verbose output for hardcore debugging
end
class TestResultsSanityChecks
NONE = 0 # no sanity checking of test results
NORMAL = 1 # perform non-problematic checks
THOROUGH = 2 # perform checks that require inside knowledge of system workings
end
class StdErrRedirect
NONE = :none
AUTO = :auto
WIN = :win
UNIX = :unix
TCSH = :tcsh
end
class BackgroundExec
NONE = :none
AUTO = :auto
WIN = :win
UNIX = :unix
end
EXTENSION_WIN_EXE = '.exe'
EXTENSION_NONWIN_EXE = '.out'
CEXCEPTION_ROOT_PATH = 'c_exception'
CEXCEPTION_LIB_PATH = "#{CEXCEPTION_ROOT_PATH}/lib"
CEXCEPTION_C_FILE = 'CException.c'
CEXCEPTION_H_FILE = 'CException.h'
UNITY_ROOT_PATH = 'unity'
UNITY_LIB_PATH = "#{UNITY_ROOT_PATH}/src"
UNITY_C_FILE = 'unity.c'
UNITY_H_FILE = 'unity.h'
UNITY_INTERNALS_H_FILE = 'unity_internals.h'
CMOCK_ROOT_PATH = 'cmock'
CMOCK_LIB_PATH = "#{CMOCK_ROOT_PATH}/src"
CMOCK_C_FILE = 'cmock.c'
CMOCK_H_FILE = 'cmock.h'
DEFAULT_CEEDLING_MAIN_PROJECT_FILE = 'project.yml' # main project file
DEFAULT_CEEDLING_USER_PROJECT_FILE = 'user.yml' # supplemental user config file
INPUT_CONFIGURATION_CACHE_FILE = 'input.yml' # input configuration file dump
TEST_ROOT_NAME = 'test'
TEST_TASK_ROOT = TEST_ROOT_NAME + ':'
TEST_SYM = TEST_ROOT_NAME.to_sym
RELEASE_ROOT_NAME = 'release'
RELEASE_TASK_ROOT = RELEASE_ROOT_NAME + ':'
RELEASE_SYM = RELEASE_ROOT_NAME.to_sym
REFRESH_ROOT_NAME = 'refresh'
REFRESH_TASK_ROOT = REFRESH_ROOT_NAME + ':'
REFRESH_SYM = REFRESH_ROOT_NAME.to_sym
UTILS_ROOT_NAME = 'utils'
UTILS_TASK_ROOT = UTILS_ROOT_NAME + ':'
UTILS_SYM = UTILS_ROOT_NAME.to_sym
OPERATION_COMPILE_SYM = :compile
OPERATION_LINK_SYM = :link
RUBY_STRING_REPLACEMENT_PATTERN = /#\{.+\}/
RUBY_EVAL_REPLACEMENT_PATTERN = /^\{(.+)\}$/
TOOL_EXECUTOR_ARGUMENT_REPLACEMENT_PATTERN = /(\$\{(\d+)\})/
TEST_STDOUT_STATISTICS_PATTERN = /-+\s+(\d+)\s+Tests\s+(\d+)\s+Failures\s+(\d+)\s+Ignored\s+(OK|FAIL)\s*/i
NULL_FILE_PATH = '/dev/null'
TESTS_BASE_PATH = TEST_ROOT_NAME
RELEASE_BASE_PATH = RELEASE_ROOT_NAME

View File

@ -1,380 +0,0 @@
require 'constants'
require 'system_wrapper'
require 'file_path_utils'
DEFAULT_TEST_COMPILER_TOOL = {
:executable => FilePathUtils.os_executable_ext('gcc').freeze,
:name => 'default_test_compiler'.freeze,
:stderr_redirect => StdErrRedirect::NONE.freeze,
:background_exec => BackgroundExec::NONE.freeze,
:optional => false.freeze,
:arguments => [
{"-I\"$\"" => 'COLLECTION_PATHS_TEST_SUPPORT_SOURCE_INCLUDE_VENDOR'}.freeze,
{"-I\"$\"" => 'COLLECTION_PATHS_TEST_TOOLCHAIN_INCLUDE'}.freeze,
{"-D$" => 'COLLECTION_DEFINES_TEST_AND_VENDOR'}.freeze,
"-DGNU_COMPILER".freeze,
"-c \"${1}\"".freeze,
"-o \"${2}\"".freeze,
# gcc's list file output options are complex; no use of ${3} parameter in default config
].freeze
}
DEFAULT_TEST_LINKER_TOOL = {
:executable => FilePathUtils.os_executable_ext('gcc').freeze,
:name => 'default_test_linker'.freeze,
:stderr_redirect => StdErrRedirect::NONE.freeze,
:background_exec => BackgroundExec::NONE.freeze,
:optional => false.freeze,
:arguments => [
"\"${1}\"".freeze,
"-o \"${2}\"".freeze,
].freeze
}
DEFAULT_TEST_FIXTURE_TOOL = {
:executable => '${1}'.freeze,
:name => 'default_test_fixture'.freeze,
:stderr_redirect => StdErrRedirect::AUTO.freeze,
:background_exec => BackgroundExec::NONE.freeze,
:optional => false.freeze,
:arguments => [].freeze
}
DEFAULT_TEST_INCLUDES_PREPROCESSOR_TOOL = {
:executable => FilePathUtils.os_executable_ext('cpp').freeze,
:name => 'default_test_includes_preprocessor'.freeze,
:stderr_redirect => StdErrRedirect::NONE.freeze,
:background_exec => BackgroundExec::NONE.freeze,
:optional => false.freeze,
:arguments => [
'-MM'.freeze,
'-MG'.freeze,
# avoid some possibility of deep system lib header file complications by omitting vendor paths
# if cpp is run on *nix system, escape spaces in paths; if cpp on windows just use the paths collection as is
{"-I\"$\"" => "{SystemWrapper.windows? ? COLLECTION_PATHS_TEST_SUPPORT_SOURCE_INCLUDE : COLLECTION_PATHS_TEST_SUPPORT_SOURCE_INCLUDE.map{|path| path.gsub(\/ \/, \'\\\\ \') }}"}.freeze,
{"-D$" => 'COLLECTION_DEFINES_TEST_AND_VENDOR'}.freeze,
{"-D$" => 'DEFINES_TEST_PREPROCESS'}.freeze,
"-DGNU_PREPROCESSOR".freeze,
'-w'.freeze,
'-nostdinc'.freeze,
"\"${1}\"".freeze
].freeze
}
DEFAULT_TEST_FILE_PREPROCESSOR_TOOL = {
:executable => FilePathUtils.os_executable_ext('gcc').freeze,
:name => 'default_test_file_preprocessor'.freeze,
:stderr_redirect => StdErrRedirect::NONE.freeze,
:background_exec => BackgroundExec::NONE.freeze,
:optional => false.freeze,
:arguments => [
'-E'.freeze,
{"-I\"$\"" => 'COLLECTION_PATHS_TEST_SUPPORT_SOURCE_INCLUDE_VENDOR'}.freeze,
{"-I\"$\"" => 'COLLECTION_PATHS_TEST_TOOLCHAIN_INCLUDE'}.freeze,
{"-D$" => 'COLLECTION_DEFINES_TEST_AND_VENDOR'}.freeze,
{"-D$" => 'DEFINES_TEST_PREPROCESS'}.freeze,
"-DGNU_PREPROCESSOR".freeze,
"\"${1}\"".freeze,
"-o \"${2}\"".freeze
].freeze
}
DEFAULT_TEST_DEPENDENCIES_GENERATOR_TOOL = {
:executable => FilePathUtils.os_executable_ext('gcc').freeze,
:name => 'default_test_dependencies_generator'.freeze,
:stderr_redirect => StdErrRedirect::NONE.freeze,
:background_exec => BackgroundExec::NONE.freeze,
:optional => false.freeze,
:arguments => [
{"-I\"$\"" => 'COLLECTION_PATHS_TEST_SUPPORT_SOURCE_INCLUDE_VENDOR'}.freeze,
{"-I\"$\"" => 'COLLECTION_PATHS_TEST_TOOLCHAIN_INCLUDE'}.freeze,
{"-D$" => 'COLLECTION_DEFINES_TEST_AND_VENDOR'}.freeze,
{"-D$" => 'DEFINES_TEST_PREPROCESS'}.freeze,
"-DGNU_PREPROCESSOR".freeze,
"-MT \"${3}\"".freeze,
'-MM'.freeze,
'-MD'.freeze,
'-MG'.freeze,
"-MF \"${2}\"".freeze,
"-c \"${1}\"".freeze,
].freeze
}
DEFAULT_RELEASE_DEPENDENCIES_GENERATOR_TOOL = {
:executable => FilePathUtils.os_executable_ext('gcc').freeze,
:name => 'default_release_dependencies_generator'.freeze,
:stderr_redirect => StdErrRedirect::NONE.freeze,
:background_exec => BackgroundExec::NONE.freeze,
:optional => false.freeze,
:arguments => [
{"-I\"$\"" => 'COLLECTION_PATHS_SOURCE_INCLUDE_VENDOR'}.freeze,
{"-I\"$\"" => 'COLLECTION_PATHS_RELEASE_TOOLCHAIN_INCLUDE'}.freeze,
{"-D$" => 'COLLECTION_DEFINES_RELEASE_AND_VENDOR'}.freeze,
{"-D$" => 'DEFINES_RELEASE_PREPROCESS'}.freeze,
"-DGNU_PREPROCESSOR".freeze,
"-MT \"${3}\"".freeze,
'-MM'.freeze,
'-MD'.freeze,
'-MG'.freeze,
"-MF \"${2}\"".freeze,
"-c \"${1}\"".freeze,
].freeze
}
DEFAULT_RELEASE_COMPILER_TOOL = {
:executable => FilePathUtils.os_executable_ext('gcc').freeze,
:name => 'default_release_compiler'.freeze,
:stderr_redirect => StdErrRedirect::NONE.freeze,
:background_exec => BackgroundExec::NONE.freeze,
:optional => false.freeze,
:arguments => [
{"-I\"$\"" => 'COLLECTION_PATHS_SOURCE_INCLUDE_VENDOR'}.freeze,
{"-I\"$\"" => 'COLLECTION_PATHS_RELEASE_TOOLCHAIN_INCLUDE'}.freeze,
{"-D$" => 'COLLECTION_DEFINES_RELEASE_AND_VENDOR'}.freeze,
"-DGNU_COMPILER".freeze,
"-c \"${1}\"".freeze,
"-o \"${2}\"".freeze,
# gcc's list file output options are complex; no use of ${3} parameter in default config
].freeze
}
DEFAULT_RELEASE_ASSEMBLER_TOOL = {
:executable => FilePathUtils.os_executable_ext('as').freeze,
:name => 'default_release_assembler'.freeze,
:stderr_redirect => StdErrRedirect::NONE.freeze,
:background_exec => BackgroundExec::NONE.freeze,
:optional => false.freeze,
:arguments => [
{"-I\"$\"" => 'COLLECTION_PATHS_SOURCE_AND_INCLUDE'}.freeze,
"\"${1}\"".freeze,
"-o \"${2}\"".freeze,
].freeze
}
DEFAULT_RELEASE_LINKER_TOOL = {
:executable => FilePathUtils.os_executable_ext('gcc').freeze,
:name => 'default_release_linker'.freeze,
:stderr_redirect => StdErrRedirect::NONE.freeze,
:background_exec => BackgroundExec::NONE.freeze,
:optional => false.freeze,
:arguments => [
"\"${1}\"".freeze,
"-o \"${2}\"".freeze,
].freeze
}
DEFAULT_TOOLS_TEST = {
:tools => {
:test_compiler => DEFAULT_TEST_COMPILER_TOOL,
:test_linker => DEFAULT_TEST_LINKER_TOOL,
:test_fixture => DEFAULT_TEST_FIXTURE_TOOL,
}
}
DEFAULT_TOOLS_TEST_PREPROCESSORS = {
:tools => {
:test_includes_preprocessor => DEFAULT_TEST_INCLUDES_PREPROCESSOR_TOOL,
:test_file_preprocessor => DEFAULT_TEST_FILE_PREPROCESSOR_TOOL,
}
}
DEFAULT_TOOLS_TEST_DEPENDENCIES = {
:tools => {
:test_dependencies_generator => DEFAULT_TEST_DEPENDENCIES_GENERATOR_TOOL,
}
}
DEFAULT_TOOLS_RELEASE = {
:tools => {
:release_compiler => DEFAULT_RELEASE_COMPILER_TOOL,
:release_linker => DEFAULT_RELEASE_LINKER_TOOL,
}
}
DEFAULT_TOOLS_RELEASE_ASSEMBLER = {
:tools => {
:release_assembler => DEFAULT_RELEASE_ASSEMBLER_TOOL,
}
}
DEFAULT_TOOLS_RELEASE_DEPENDENCIES = {
:tools => {
:release_dependencies_generator => DEFAULT_RELEASE_DEPENDENCIES_GENERATOR_TOOL,
}
}
DEFAULT_RELEASE_TARGET_NAME = 'project'
DEFAULT_CEEDLING_CONFIG = {
:project => {
# :build_root must be set by user
:use_exceptions => true,
:use_mocks => true,
:compile_threads => 1,
:test_threads => 1,
:use_test_preprocessor => false,
:use_deep_dependencies => false,
:test_file_prefix => 'test_',
:options_paths => [],
:release_build => false,
},
:release_build => {
# :output is set while building configuration -- allows smart default system-dependent file extension handling
:use_assembly => false,
:artifacts => [],
},
:paths => {
:test => [], # must be populated by user
:source => [], # must be populated by user
:support => [],
:include => [],
:test_toolchain_include => [],
:release_toolchain_include => [],
},
:files => {
:test => [],
:source => [],
:assembly => [],
:support => [],
:include => [],
},
# unlike other top-level entries, environment's value is an array to preserve order
:environment => [
# when evaluated, this provides wider text field for rake task comments
{:rake_columns => '120'},
],
:defines => {
:test => [],
:test_preprocess => [],
:release => [],
:release_preprocess => [],
},
:flags => {},
:extension => {
:header => '.h',
:source => '.c',
:assembly => '.s',
:object => '.o',
:executable => ( SystemWrapper.windows? ? EXTENSION_WIN_EXE : EXTENSION_NONWIN_EXE ),
:map => '.map',
:list => '.lst',
:testpass => '.pass',
:testfail => '.fail',
:dependencies => '.d',
},
:unity => {
:defines => []
},
:cmock => {
:defines => []
},
:cexception => {
:defines => []
},
:test_runner => {
:includes => [],
:file_suffix => '_runner',
},
# all tools populated while building up config structure
:tools => {},
# empty argument lists for default tools
# (these can be overridden in project file to add arguments to tools without totally redefining tools)
:test_compiler => { :arguments => [] },
:test_linker => { :arguments => [] },
:test_fixture => {
:arguments => [],
:link_objects => [], # compiled object files to always be linked in (e.g. cmock.o if using mocks)
},
:test_includes_preprocessor => { :arguments => [] },
:test_file_preprocessor => { :arguments => [] },
:test_dependencies_generator => { :arguments => [] },
:release_compiler => { :arguments => [] },
:release_linker => { :arguments => [] },
:release_assembler => { :arguments => [] },
:release_dependencies_generator => { :arguments => [] },
:plugins => {
:load_paths => [],
:enabled => [],
}
}.freeze
DEFAULT_TESTS_RESULTS_REPORT_TEMPLATE = %q{
% ignored = hash[:results][:counts][:ignored]
% failed = hash[:results][:counts][:failed]
% stdout_count = hash[:results][:counts][:stdout]
% header_prepend = ((hash[:header].length > 0) ? "#{hash[:header]}: " : '')
% banner_width = 25 + header_prepend.length # widest message
% if (ignored > 0)
<%=@ceedling[:plugin_reportinator].generate_banner(header_prepend + 'IGNORED UNIT TEST SUMMARY')%>
% hash[:results][:ignores].each do |ignore|
% ignore[:collection].each do |item|
<%=ignore[:source][:path]%><%=File::SEPARATOR%><%=ignore[:source][:file]%>:<%=item[:line]%>:<%=item[:test]%>
% if (item[:message].length > 0)
: "<%=item[:message]%>"
% else
<%="\n"%>
% end
% end
% end
% end
% if (failed > 0)
<%=@ceedling[:plugin_reportinator].generate_banner(header_prepend + "\e[31m" 'FAILED UNIT TEST SUMMARY')%>
% hash[:results][:failures].each do |failure|
% failure[:collection].each do |item|
<%=failure[:source][:path]%><%=File::SEPARATOR%><%=failure[:source][:file]%>:<%=item[:line]%>:<%=item[:test]%>
% if (item[:message].length > 0)
: "<%=item[:message]%>"
% else
<%="\n"%>
% end
% end
% end
% end
% if (stdout_count > 0)
<%=@ceedling[:plugin_reportinator].generate_banner(header_prepend + 'UNIT TEST OTHER OUTPUT')%>
% hash[:results][:stdout].each do |string|
% string[:collection].each do |item|
<%=string[:source][:path]%><%=File::SEPARATOR%><%=string[:source][:file]%>: "<%=item%>"
% end
% end
% end
% total_string = hash[:results][:counts][:total].to_s
% format_string = "%#{total_string.length}i"
<%=@ceedling[:plugin_reportinator].generate_banner(header_prepend + 'OVERALL UNIT TEST SUMMARY')%>
% if (hash[:results][:counts][:total] > 0)
TESTED: <%=hash[:results][:counts][:total].to_s%>
PASSED: <%=sprintf(format_string, hash[:results][:counts][:passed])%>
FAILED: <%=sprintf(format_string, failed)%>
IGNORED: <%=sprintf(format_string, ignored)%>
% else
No tests executed.
% end
}

View File

@ -1,92 +0,0 @@
class Dependinator
constructor :configurator, :project_config_manager, :test_includes_extractor, :file_path_utils, :rake_wrapper, :file_wrapper
def touch_force_rebuild_files
@file_wrapper.touch( @configurator.project_test_force_rebuild_filepath )
@file_wrapper.touch( @configurator.project_release_force_rebuild_filepath ) if (@configurator.project_release_build)
end
def load_release_object_deep_dependencies(dependencies_list)
dependencies_list.each { |dependencies_file| @rake_wrapper.load_dependencies( dependencies_file ) }
end
def enhance_release_file_dependencies(files)
files.each do |filepath|
@rake_wrapper[filepath].enhance( [@configurator.project_release_force_rebuild_filepath] ) if (@project_config_manager.release_config_changed)
@rake_wrapper[filepath].enhance( [@configurator.ceedling_build_info_filepath] )
end
end
def load_test_object_deep_dependencies(files_list)
dependencies_list = @file_path_utils.form_test_dependencies_filelist(files_list)
dependencies_list.each { |dependencies_file| @rake_wrapper.load_dependencies(dependencies_file) }
end
def enhance_runner_dependencies(runner_filepath)
@rake_wrapper[runner_filepath].enhance( [@configurator.project_test_force_rebuild_filepath] ) if (@project_config_manager.test_config_changed)
@rake_wrapper[runner_filepath].enhance( [@configurator.ceedling_build_info_filepath] )
end
def enhance_shallow_include_lists_dependencies(include_lists)
include_lists.each do |include_list_filepath|
@rake_wrapper[include_list_filepath].enhance( [@configurator.project_test_force_rebuild_filepath] ) if (@project_config_manager.test_config_changed)
@rake_wrapper[include_list_filepath].enhance( [@configurator.ceedling_build_info_filepath] )
end
end
def enhance_preprocesed_file_dependencies(files)
files.each do |filepath|
@rake_wrapper[filepath].enhance( [@configurator.project_test_force_rebuild_filepath] ) if (@project_config_manager.test_config_changed)
@rake_wrapper[filepath].enhance( [@configurator.ceedling_build_info_filepath] )
end
end
def enhance_mock_dependencies(mocks_list)
# if input configuration or ceedling changes, make sure these guys get rebuilt
mocks_list.each do |mock_filepath|
@rake_wrapper[mock_filepath].enhance( [@configurator.project_test_force_rebuild_filepath] ) if (@project_config_manager.test_config_changed)
@rake_wrapper[mock_filepath].enhance( [@configurator.cmock_unity_helper] ) if (@configurator.cmock_unity_helper)
@rake_wrapper[mock_filepath].enhance( [@configurator.ceedling_build_info_filepath] )
@rake_wrapper[mock_filepath].enhance( [@configurator.cmock_build_info_filepath] )
end
end
def enhance_dependencies_dependencies(dependencies)
dependencies.each do |dependencies_filepath|
@rake_wrapper[dependencies_filepath].enhance( [@configurator.project_test_force_rebuild_filepath] ) if (@project_config_manager.test_config_changed)
@rake_wrapper[dependencies_filepath].enhance( [@configurator.ceedling_build_info_filepath] )
end
end
def enhance_test_build_object_dependencies(objects)
objects.each do |object_filepath|
@rake_wrapper[object_filepath].enhance( [@configurator.project_test_force_rebuild_filepath] ) if (@project_config_manager.test_config_changed)
@rake_wrapper[object_filepath].enhance( [@configurator.ceedling_build_info_filepath] )
end
end
def enhance_results_dependencies(result_filepath)
@rake_wrapper[result_filepath].enhance( [@configurator.project_test_force_rebuild_filepath] ) if (@project_config_manager.test_config_changed)
@rake_wrapper[result_filepath].enhance( [@configurator.ceedling_build_info_filepath] )
end
def setup_test_executable_dependencies(test, objects)
@rake_wrapper.create_file_task( @file_path_utils.form_test_executable_filepath(test), objects)
end
end

View File

@ -1,9 +0,0 @@
require 'erb'
class ErbWrapper
def generate_file(template, data, output_file)
File.open(output_file, "w") do |f|
f << ERB.new(template, 0, "<>").result(binding)
end
end
end

View File

@ -1,132 +0,0 @@
require 'rubygems'
require 'rake' # for adding ext() method to string
class FileFinder
constructor :configurator, :file_finder_helper, :cacheinator, :file_path_utils, :file_wrapper, :yaml_wrapper
def prepare_search_sources
@all_test_source_and_header_file_collection =
@configurator.collection_all_tests +
@configurator.collection_all_source +
@configurator.collection_all_headers
end
def find_header_file(mock_file)
header = File.basename(mock_file).sub(/#{@configurator.cmock_mock_prefix}/, '').ext(@configurator.extension_header)
found_path = @file_finder_helper.find_file_in_collection(header, @configurator.collection_all_headers, :error)
return found_path
end
def find_header_input_for_mock_file(mock_file)
found_path = find_header_file(mock_file)
mock_input = found_path
if (@configurator.project_use_test_preprocessor)
mock_input = @cacheinator.diff_cached_test_file( @file_path_utils.form_preprocessed_file_filepath( found_path ) )
end
return mock_input
end
def find_source_from_test(test, complain)
test_prefix = @configurator.project_test_file_prefix
source_paths = @configurator.collection_all_source
source = File.basename(test).sub(/#{test_prefix}/, '')
# we don't blow up if a test file has no corresponding source file
return @file_finder_helper.find_file_in_collection(source, source_paths, complain)
end
def find_test_from_runner_path(runner_path)
extension_source = @configurator.extension_source
test_file = File.basename(runner_path).sub(/#{@configurator.test_runner_file_suffix}#{'\\'+extension_source}/, extension_source)
found_path = @file_finder_helper.find_file_in_collection(test_file, @configurator.collection_all_tests, :error)
return found_path
end
def find_test_input_for_runner_file(runner_path)
found_path = find_test_from_runner_path(runner_path)
runner_input = found_path
if (@configurator.project_use_test_preprocessor)
runner_input = @cacheinator.diff_cached_test_file( @file_path_utils.form_preprocessed_file_filepath( found_path ) )
end
return runner_input
end
def find_test_from_file_path(file_path)
test_file = File.basename(file_path).ext(@configurator.extension_source)
found_path = @file_finder_helper.find_file_in_collection(test_file, @configurator.collection_all_tests, :error)
return found_path
end
def find_test_or_source_or_header_file(file_path)
file = File.basename(file_path)
return @file_finder_helper.find_file_in_collection(file, @all_test_source_and_header_file_collection, :error)
end
def find_compilation_input_file(file_path, complain=:error)
found_file = nil
source_file = File.basename(file_path).ext(@configurator.extension_source)
# We only collect files that already exist when we start up.
# FileLists can produce undesired results for dynamically generated files depending on when they're accessed.
# So collect mocks and runners separately and right now.
if (source_file =~ /#{@configurator.test_runner_file_suffix}/)
found_file =
@file_finder_helper.find_file_in_collection(
source_file,
@file_wrapper.directory_listing( File.join(@configurator.project_test_runners_path, '*') ),
complain)
elsif (@configurator.project_use_mocks and (source_file =~ /#{@configurator.cmock_mock_prefix}/))
found_file =
@file_finder_helper.find_file_in_collection(
source_file,
@file_wrapper.directory_listing( File.join(@configurator.cmock_mock_path, '*') ),
complain)
else
found_file =
@file_finder_helper.find_file_in_collection(
source_file,
@configurator.collection_all_existing_compilation_input,
complain)
end
return found_file
end
def find_source_file(file_path, complain)
source_file = File.basename(file_path).ext(@configurator.extension_source)
return @file_finder_helper.find_file_in_collection(source_file, @configurator.collection_all_source, complain)
end
def find_assembly_file(file_path)
assembly_file = File.basename(file_path).ext(@configurator.extension_assembly)
return @file_finder_helper.find_file_in_collection(assembly_file, @configurator.collection_all_assembly, :error)
end
end

View File

@ -1,54 +0,0 @@
require 'fileutils'
require 'constants' # for Verbosity enumeration
class FileFinderHelper
constructor :streaminator
def find_file_in_collection(file_name, file_list, complain, extra_message="")
file_to_find = nil
file_list.each do |item|
base_file = File.basename(item)
# case insensitive comparison
if (base_file.casecmp(file_name) == 0)
# case sensitive check
if (base_file == file_name)
file_to_find = item
break
else
blow_up(file_name, "However, a filename having different capitalization was found: '#{item}'.")
end
end
end
case (complain)
when :error then blow_up(file_name, extra_message) if (file_to_find.nil?)
when :warn then gripe(file_name, extra_message) if (file_to_find.nil?)
#when :ignore then
end
return file_to_find
end
private
def blow_up(file_name, extra_message="")
error = "ERROR: Found no file '#{file_name}' in search paths."
error += ' ' if (extra_message.length > 0)
@streaminator.stderr_puts(error + extra_message, Verbosity::ERRORS)
raise
end
def gripe(file_name, extra_message="")
warning = "WARNING: Found no file '#{file_name}' in search paths."
warning += ' ' if (extra_message.length > 0)
@streaminator.stderr_puts(warning + extra_message, Verbosity::COMPLAIN)
end
end

View File

@ -1,189 +0,0 @@
require 'rubygems'
require 'rake' # for ext()
require 'fileutils'
require 'system_wrapper'
# global utility methods (for plugins, project files, etc.)
def ceedling_form_filepath(destination_path, original_filepath, new_extension=nil)
filename = File.basename(original_filepath)
filename.replace(filename.ext(new_extension)) if (!new_extension.nil?)
return File.join( destination_path.gsub(/\\/, '/'), filename )
end
class FilePathUtils
GLOB_MATCHER = /[\*\?\{\}\[\]]/
constructor :configurator, :file_wrapper
######### class methods ##########
# standardize path to use '/' path separator & begin with './' & have no trailing path separator
def self.standardize(path)
path.strip!
path.gsub!(/\\/, '/')
path.gsub!(/^((\+|-):)?\.\//, '')
path.chomp!('/')
return path
end
def self.os_executable_ext(executable)
return executable.ext('.exe') if SystemWrapper.windows?
return executable
end
# extract directory path from between optional add/subtract aggregation modifiers and up to glob specifiers
# note: slightly different than File.dirname in that /files/foo remains /files/foo and does not become /files
def self.extract_path(path)
path = path.sub(/^(\+|-):/, '')
# find first occurrence of path separator followed by directory glob specifier: *, ?, {, }, [, ]
find_index = (path =~ GLOB_MATCHER)
# no changes needed (lop off final path separator)
return path.chomp('/') if (find_index.nil?)
# extract up to first glob specifier
path = path[0..(find_index-1)]
# lop off everything up to and including final path separator
find_index = path.rindex('/')
return path[0..(find_index-1)] if (not find_index.nil?)
# return string up to first glob specifier if no path separator found
return path
end
# return whether the given path is to be aggregated (no aggregation modifier defaults to same as +:)
def self.add_path?(path)
return (path =~ /^-:/).nil?
end
# get path (and glob) lopping off optional +: / -: prefixed aggregation modifiers
def self.extract_path_no_aggregation_operators(path)
return path.sub(/^(\+|-):/, '')
end
# all the globs that may be in a path string work fine with one exception;
# to recurse through all subdirectories, the glob is dir/**/** but our paths use
# convention of only dir/**
def self.reform_glob(path)
return path if (path =~ /\/\*\*$/).nil?
return path + '/**'
end
def self.form_ceedling_vendor_path(*filepaths)
return File.join( CEEDLING_VENDOR, filepaths )
end
######### instance methods ##########
def form_temp_path(filepath, prefix='')
return File.join( @configurator.project_temp_path, prefix + File.basename(filepath) )
end
### release ###
def form_release_build_cache_path(filepath)
return File.join( @configurator.project_release_build_cache_path, File.basename(filepath) )
end
def form_release_dependencies_filepath(filepath)
return File.join( @configurator.project_release_dependencies_path, File.basename(filepath).ext(@configurator.extension_dependencies) )
end
def form_release_build_c_object_filepath(filepath)
return File.join( @configurator.project_release_build_output_c_path, File.basename(filepath).ext(@configurator.extension_object) )
end
def form_release_build_asm_object_filepath(filepath)
return File.join( @configurator.project_release_build_output_asm_path, File.basename(filepath).ext(@configurator.extension_object) )
end
def form_release_build_c_objects_filelist(files)
return (@file_wrapper.instantiate_file_list(files)).pathmap("#{@configurator.project_release_build_output_c_path}/%n#{@configurator.extension_object}")
end
def form_release_build_asm_objects_filelist(files)
return (@file_wrapper.instantiate_file_list(files)).pathmap("#{@configurator.project_release_build_output_asm_path}/%n#{@configurator.extension_object}")
end
def form_release_build_c_list_filepath(filepath)
return File.join( @configurator.project_release_build_output_c_path, File.basename(filepath).ext(@configurator.extension_list) )
end
def form_release_dependencies_filelist(files)
return (@file_wrapper.instantiate_file_list(files)).pathmap("#{@configurator.project_release_dependencies_path}/%n#{@configurator.extension_dependencies}")
end
### tests ###
def form_test_build_cache_path(filepath)
return File.join( @configurator.project_test_build_cache_path, File.basename(filepath) )
end
def form_pass_results_filepath(filepath)
return File.join( @configurator.project_test_results_path, File.basename(filepath).ext(@configurator.extension_testpass) )
end
def form_fail_results_filepath(filepath)
return File.join( @configurator.project_test_results_path, File.basename(filepath).ext(@configurator.extension_testfail) )
end
def form_runner_filepath_from_test(filepath)
return File.join( @configurator.project_test_runners_path, File.basename(filepath, @configurator.extension_source)) + @configurator.test_runner_file_suffix + @configurator.extension_source
end
def form_test_filepath_from_runner(filepath)
return filepath.sub(/#{TEST_RUNNER_FILE_SUFFIX}/, '')
end
def form_runner_object_filepath_from_test(filepath)
return (form_test_build_object_filepath(filepath)).sub(/(#{@configurator.extension_object})$/, "#{@configurator.test_runner_file_suffix}\\1")
end
def form_test_build_object_filepath(filepath)
return File.join( @configurator.project_test_build_output_path, File.basename(filepath).ext(@configurator.extension_object) )
end
def form_test_executable_filepath(filepath)
return File.join( @configurator.project_test_build_output_path, File.basename(filepath).ext(@configurator.extension_executable) )
end
def form_test_build_map_filepath(filepath)
return File.join( @configurator.project_test_build_output_path, File.basename(filepath).ext(@configurator.extension_map) )
end
def form_test_build_list_filepath(filepath)
return File.join( @configurator.project_test_build_output_path, File.basename(filepath).ext(@configurator.extension_list) )
end
def form_preprocessed_file_filepath(filepath)
return File.join( @configurator.project_test_preprocess_files_path, File.basename(filepath) )
end
def form_preprocessed_includes_list_filepath(filepath)
return File.join( @configurator.project_test_preprocess_includes_path, File.basename(filepath) )
end
def form_test_build_objects_filelist(sources)
return (@file_wrapper.instantiate_file_list(sources)).pathmap("#{@configurator.project_test_build_output_path}/%n#{@configurator.extension_object}")
end
def form_preprocessed_mockable_headers_filelist(mocks)
# pathmapping note: "%{#{@configurator.cmock_mock_prefix},}n" replaces mock_prefix with nothing (signified by absence of anything after comma inside replacement brackets)
return (@file_wrapper.instantiate_file_list(mocks)).pathmap("#{@configurator.project_test_preprocess_files_path}/%{#{@configurator.cmock_mock_prefix},}n#{@configurator.extension_header}")
end
def form_mocks_source_filelist(mocks)
return (@file_wrapper.instantiate_file_list(mocks)).pathmap("#{@configurator.cmock_mock_path}/%n#{@configurator.extension_source}")
end
def form_test_dependencies_filelist(files)
return (@file_wrapper.instantiate_file_list(files)).pathmap("#{@configurator.project_test_dependencies_path}/%n#{@configurator.extension_dependencies}")
end
def form_pass_results_filelist(path, files)
return (@file_wrapper.instantiate_file_list(files)).pathmap("#{path}/%n#{@configurator.extension_testpass}")
end
end

View File

@ -1,69 +0,0 @@
require 'rubygems'
require 'rake'
require 'set'
require 'fileutils'
require 'file_path_utils.rb'
class FileSystemUtils
constructor :file_wrapper
# build up path list from input of one or more strings or arrays of (+/-) paths & globs
def collect_paths(*paths)
raw = [] # all paths and globs
plus = Set.new # all paths to expand and add
minus = Set.new # all paths to remove from plus set
# assemble all globs and simple paths, reforming our glob notation to ruby globs
paths.each do |paths_container|
case (paths_container)
when String then raw << (FilePathUtils::reform_glob(paths_container))
when Array then paths_container.each {|path| raw << (FilePathUtils::reform_glob(path))}
else raise "Don't know how to handle #{paths_container.class}"
end
end
# iterate through each path and glob
raw.each do |path|
dirs = [] # container for only (expanded) paths
# if a glob, expand it and slurp up all non-file paths
if path.include?('*')
# grab base directory only if globs are snug up to final path separator
if (path =~ /\/\*+$/)
dirs << FilePathUtils.extract_path(path)
end
# grab expanded sub-directory globs
expanded = @file_wrapper.directory_listing( FilePathUtils.extract_path_no_aggregation_operators(path) )
expanded.each do |entry|
dirs << entry if @file_wrapper.directory?(entry)
end
# else just grab simple path
# note: we could just run this through glob expansion but such an
# approach doesn't handle a path not yet on disk)
else
dirs << FilePathUtils.extract_path_no_aggregation_operators(path)
end
# add dirs to the appropriate set based on path aggregation modifier if present
FilePathUtils.add_path?(path) ? plus.merge(dirs) : minus.merge(dirs)
end
return (plus - minus).to_a.uniq
end
# given a file list, add to it or remove from it
def revise_file_list(list, revisions)
revisions.each do |revision|
# include or exclude file or glob to file list
file = FilePathUtils.extract_path_no_aggregation_operators( revision )
FilePathUtils.add_path?(revision) ? list.include(file) : list.exclude(file)
end
end
end

View File

@ -1,10 +0,0 @@
class FileSystemWrapper
def cd(path)
FileUtils.cd path do
yield
end
end
end

View File

@ -1,79 +0,0 @@
require 'rubygems'
require 'rake' # for FileList
require 'constants'
require 'fileutils'
class FileWrapper
def get_expanded_path(path)
return File.expand_path(path)
end
def basename(path, extension=nil)
return File.basename(path, extension) if extension
return File.basename(path)
end
def exist?(filepath)
return true if (filepath == NULL_FILE_PATH)
return File.exist?(filepath)
end
def directory?(path)
return File.directory?(path)
end
def dirname(path)
return File.dirname(path)
end
def directory_listing(glob)
return Dir.glob(glob)
end
def rm_f(filepath, options={})
FileUtils.rm_f(filepath, options)
end
def rm_r(filepath, options={})
FileUtils.rm_r(filepath, options={})
end
def cp(source, destination, options={})
FileUtils.cp(source, destination, options)
end
def compare(from, to)
return FileUtils.compare_file(from, to)
end
def open(filepath, flags)
File.open(filepath, flags) do |file|
yield(file)
end
end
def read(filepath)
return File.read(filepath)
end
def touch(filepath, options={})
FileUtils.touch(filepath, options)
end
def write(filepath, contents, flags='w')
File.open(filepath, flags) do |file|
file.write(contents)
end
end
def readlines(filepath)
return File.readlines(filepath)
end
def instantiate_file_list(files=[])
return FileList.new(files)
end
end

View File

@ -1,54 +0,0 @@
require 'rubygems'
require 'rake' # for ext()
require 'fileutils'
require 'constants'
# :flags:
# :release:
# :compile:
# :*: # add '-foo' to compilation of all files not main.c
# - -foo
# :main: # add '-Wall' to compilation of main.c
# - -Wall
# :test:
# :link:
# :test_main: # add '--bar --baz' to linking of test_main.exe
# - --bar
# - --baz
class Flaginator
constructor :configurator
def flag_down( operation, context, file )
# create configurator accessor method
accessor = ('flags_' + context.to_s).to_sym
# create simple filename key from whatever filename provided
file_key = File.basename( file ).ext('').to_sym
# if no entry in configuration for flags for this context, bail out
return [] if not @configurator.respond_to?( accessor )
# get flags sub hash associated with this context
flags = @configurator.send( accessor )
# if operation not represented in flags hash, bail out
return [] if not flags.include?( operation )
# redefine flags to sub hash associated with the operation
flags = flags[operation]
# if our file is in the flags hash, extract the array of flags
if (flags.include?( file_key )) then return flags[file_key]
# if our file isn't in the flags hash, but there is default for all other files, extract array of flags
elsif (flags.include?( :* )) then return flags[:*]
end
# fall through: flags were specified but none applying to present file
return []
end
end

View File

@ -1,164 +0,0 @@
require 'constants'
class Generator
constructor :configurator,
:generator_helper,
:preprocessinator,
:cmock_builder,
:generator_test_runner,
:generator_test_results,
:flaginator,
:test_includes_extractor,
:tool_executor,
:file_finder,
:file_path_utils,
:streaminator,
:plugin_manager,
:file_wrapper
def generate_shallow_includes_list(context, file)
@preprocessinator.preprocess_shallow_includes(file)
end
def generate_preprocessed_file(context, file)
@streaminator.stdout_puts("Preprocessing #{File.basename(file)}...", Verbosity::NORMAL)
@preprocessinator.preprocess_file(file)
end
def generate_dependencies_file(tool, context, source, object, dependencies)
@streaminator.stdout_puts("Generating dependencies for #{File.basename(source)}...", Verbosity::NORMAL)
command =
@tool_executor.build_command_line(
tool,
source,
dependencies,
object)
@tool_executor.exec( command[:line], command[:options] )
end
def generate_mock(context, header_filepath)
arg_hash = {:header_file => header_filepath, :context => context}
@plugin_manager.pre_mock_generate( arg_hash )
begin
@cmock_builder.cmock.setup_mocks( arg_hash[:header_file] )
rescue
raise
ensure
@plugin_manager.post_mock_generate( arg_hash )
end
end
# test_filepath may be either preprocessed test file or original test file
def generate_test_runner(context, test_filepath, runner_filepath)
arg_hash = {:context => context, :test_file => test_filepath, :runner_file => runner_filepath}
@plugin_manager.pre_runner_generate(arg_hash)
# collect info we need
module_name = File.basename(arg_hash[:test_file])
test_cases = @generator_test_runner.find_test_cases( @file_finder.find_test_from_runner_path(runner_filepath) )
mock_list = @test_includes_extractor.lookup_raw_mock_list(arg_hash[:test_file])
@streaminator.stdout_puts("Generating runner for #{module_name}...", Verbosity::NORMAL)
# build runner file
begin
@generator_test_runner.generate(module_name, runner_filepath, test_cases, mock_list)
rescue
raise
ensure
@plugin_manager.post_runner_generate(arg_hash)
end
end
def generate_object_file(tool, context, source, object, list='')
shell_result = {}
arg_hash = {:tool => tool, :context => context, :source => source, :object => object, :list => list}
@plugin_manager.pre_compile_execute(arg_hash)
@streaminator.stdout_puts("Compiling #{File.basename(arg_hash[:source])}...", Verbosity::NORMAL)
command =
@tool_executor.build_command_line( arg_hash[:tool],
arg_hash[:source],
arg_hash[:object],
arg_hash[:list],
@flaginator.flag_down( OPERATION_COMPILE_SYM, context, source ) )
begin
shell_result = @tool_executor.exec( command[:line], command[:options] )
rescue ShellExecutionException => ex
shell_result = ex.shell_result
raise ''
ensure
arg_hash[:shell_result] = shell_result
@plugin_manager.post_compile_execute(arg_hash)
end
end
def generate_executable_file(tool, context, objects, executable, map='')
shell_result = {}
arg_hash = {:tool => tool, :context => context, :objects => objects, :executable => executable, :map => map}
@plugin_manager.pre_link_execute(arg_hash)
@streaminator.stdout_puts("Linking #{File.basename(arg_hash[:executable])}...", Verbosity::NORMAL)
command =
@tool_executor.build_command_line( arg_hash[:tool],
arg_hash[:objects],
arg_hash[:executable],
arg_hash[:map],
@flaginator.flag_down( OPERATION_LINK_SYM, context, executable ) )
begin
shell_result = @tool_executor.exec( command[:line], command[:options] )
rescue ShellExecutionException => ex
notice = "\n" +
"NOTICE: If the linker reports missing symbols, the following may be to blame:\n" +
" 1. Test lacks #include statements corresponding to needed source files.\n" +
" 2. Project search paths do not contain source files corresponding to #include statements in the test.\n"
if (@configurator.project_use_mocks)
notice += " 3. Test does not #include needed mocks.\n\n"
else
notice += "\n"
end
@streaminator.stderr_puts(notice, Verbosity::COMPLAIN)
shell_result = ex.shell_result
raise ''
ensure
arg_hash[:shell_result] = shell_result
@plugin_manager.post_link_execute(arg_hash)
end
end
def generate_test_results(tool, context, executable, result)
arg_hash = {:tool => tool, :context => context, :executable => executable, :result_file => result}
@plugin_manager.pre_test_fixture_execute(arg_hash)
@streaminator.stdout_puts("Running #{File.basename(arg_hash[:executable])}...", Verbosity::NORMAL)
# Unity's exit code is equivalent to the number of failed tests, so we tell @tool_executor not to fail out if there are failures
# so that we can run all tests and collect all results
command = @tool_executor.build_command_line(arg_hash[:tool], arg_hash[:executable])
command[:options][:boom] = false
shell_result = @tool_executor.exec( command[:line], command[:options] )
@generator_helper.test_results_error_handler(executable, shell_result)
processed = @generator_test_results.process_and_write_results( shell_result,
arg_hash[:result_file],
@file_finder.find_test_from_file_path(arg_hash[:executable]) )
arg_hash[:result_file] = processed[:result_file]
arg_hash[:results] = processed[:results]
arg_hash[:shell_result] = shell_result # for raw output display if no plugins for formatted display
@plugin_manager.post_test_fixture_execute(arg_hash)
end
end

View File

@ -1,40 +0,0 @@
require 'constants'
class GeneratorHelper
constructor :streaminator
def test_results_error_handler(executable, shell_result)
notice = ''
error = false
if (shell_result[:output].nil? or shell_result[:output].strip.empty?)
error = true
# mirror style of generic tool_executor failure output
notice = "\n" +
"ERROR: Test executable \"#{File.basename(executable)}\" failed.\n" +
"> Produced no output to $stdout.\n"
elsif ((shell_result[:output] =~ TEST_STDOUT_STATISTICS_PATTERN).nil?)
error = true
# mirror style of generic tool_executor failure output
notice = "\n" +
"ERROR: Test executable \"#{File.basename(executable)}\" failed.\n" +
"> Produced no final test result counts in $stdout:\n" +
"#{shell_result[:output].strip}\n"
end
if (error)
# since we told the tool executor to ignore the exit code, handle it explicitly here
notice += "> And exited with status: [#{shell_result[:exit_code]}] (count of failed tests).\n" if (shell_result[:exit_code] != nil)
notice += "> And then likely crashed.\n" if (shell_result[:exit_code] == nil)
notice += "> This is often a symptom of a bad memory access in source or test code.\n\n"
@streaminator.stderr_puts(notice, Verbosity::COMPLAIN)
raise
end
end
end

View File

@ -1,89 +0,0 @@
require 'rubygems'
require 'rake' # for .ext()
require 'constants'
class GeneratorTestResults
constructor :configurator, :generator_test_results_sanity_checker, :yaml_wrapper
def process_and_write_results(unity_shell_result, results_file, test_file)
output_file = results_file
results = get_results_structure
results[:source][:path] = File.dirname(test_file)
results[:source][:file] = File.basename(test_file)
# process test statistics
if (unity_shell_result[:output] =~ TEST_STDOUT_STATISTICS_PATTERN)
results[:counts][:total] = $1.to_i
results[:counts][:failed] = $2.to_i
results[:counts][:ignored] = $3.to_i
results[:counts][:passed] = (results[:counts][:total] - results[:counts][:failed] - results[:counts][:ignored])
end
# remove test statistics lines
output_string = unity_shell_result[:output].sub(TEST_STDOUT_STATISTICS_PATTERN, '')
# bust up the output into individual lines
raw_unity_lines = output_string.split(/\n|\r\n/)
raw_unity_lines.each do |line|
# process unity output
case line
when /(:IGNORE)/
elements = extract_line_elements(line, results[:source][:file])
results[:ignores] << elements[0]
results[:stdout] << elements[1] if (!elements[1].nil?)
when /(:PASS$)/
elements = extract_line_elements(line, results[:source][:file])
results[:successes] << elements[0]
results[:stdout] << elements[1] if (!elements[1].nil?)
when /(:FAIL)/
elements = extract_line_elements(line, results[:source][:file])
results[:failures] << elements[0]
results[:stdout] << elements[1] if (!elements[1].nil?)
else # collect up all other
results[:stdout] << line.chomp
end
end
@generator_test_results_sanity_checker.verify(results, unity_shell_result[:exit_code])
output_file = results_file.ext(@configurator.extension_testfail) if (results[:counts][:failed] > 0)
@yaml_wrapper.dump(output_file, results)
return { :result_file => output_file, :result => results }
end
private
def get_results_structure
return {
:source => {:path => '', :file => ''},
:successes => [],
:failures => [],
:ignores => [],
:counts => {:total => 0, :passed => 0, :failed => 0, :ignored => 0},
:stdout => [],
}
end
def extract_line_elements(line, filename)
# handle anything preceding filename in line as extra output to be collected
stdout = nil
stdout_regex = /(.+)#{Regexp.escape(filename)}.+/i
if (line =~ stdout_regex)
stdout = $1.clone
line.sub!(/#{Regexp.escape(stdout)}/, '')
end
# collect up test results minus and extra output
elements = (line.strip.split(':'))[1..-1]
return {:test => elements[1], :line => elements[0].to_i, :message => (elements[3..-1].join(':')).strip}, stdout
end
end

View File

@ -1,62 +0,0 @@
require 'constants'
require 'rubygems'
require 'rake' # for ext() method
class GeneratorTestResultsSanityChecker
constructor :configurator, :streaminator
def verify(results, unity_exit_code)
# do no sanity checking if it's disabled
return if (@configurator.sanity_checks == TestResultsSanityChecks::NONE)
ceedling_ignores_count = results[:ignores].size
ceedling_failures_count = results[:failures].size
ceedling_tests_summation = (ceedling_ignores_count + ceedling_failures_count + results[:successes].size)
# Exit code handling is not a sanity check that can always be performed because
# command line simulators may or may not pass through Unity's exit code
if (@configurator.sanity_checks >= TestResultsSanityChecks::THOROUGH)
# many platforms limit exit codes to a maximum of 255
if ((ceedling_failures_count != unity_exit_code) and (unity_exit_code < 255))
sanity_check_warning(results[:source][:file], "Unity's exit code (#{unity_exit_code}) does not match Ceedling's summation of failed test cases (#{ceedling_failures_count}).")
end
if ((ceedling_failures_count < 255) and (unity_exit_code == 255))
sanity_check_warning(results[:source][:file], "Ceedling's summation of failed test cases (#{ceedling_failures_count}) is less than Unity's exit code (255 or more).")
end
end
if (ceedling_ignores_count != results[:counts][:ignored])
sanity_check_warning(results[:source][:file], "Unity's final ignore count (#{results[:counts][:ignored]}) does not match Ceedling's summation of ignored test cases (#{ceedling_ignores_count}).")
end
if (ceedling_failures_count != results[:counts][:failed])
sanity_check_warning(results[:source][:file], "Unity's final fail count (#{results[:counts][:failed]}) does not match Ceedling's summation of failed test cases (#{ceedling_failures_count}).")
end
if (ceedling_tests_summation != results[:counts][:total])
sanity_check_warning(results[:source][:file], "Unity's final test count (#{results[:counts][:total]}) does not match Ceedling's summation of all test cases (#{ceedling_tests_summation}).")
end
end
private
def sanity_check_warning(file, message)
notice = "\n" +
"ERROR: Internal sanity check for test fixture '#{file.ext(@configurator.extension_executable)}' finds that #{message}\n" +
" Possible causes:\n" +
" 1. Your test + source dereferenced a null pointer.\n" +
" 2. Your test + source indexed past the end of a buffer.\n" +
" 3. Your test + source committed a memory access violation.\n" +
" 4. Your test fixture produced an exit code of 0 despite execution ending prematurely.\n" +
" Sanity check failures of test results are usually a symptom of interrupted test execution.\n\n"
@streaminator.stderr_puts( notice )
raise
end
end

View File

@ -1,63 +0,0 @@
class GeneratorTestRunner
constructor :configurator, :file_path_utils, :file_wrapper
def find_test_cases(test_file)
tests = []
tests_and_line_numbers = []
lines = []
# if we don't have preprocessor assistance, do some basic preprocessing of our own
if (not @configurator.project_use_test_preprocessor)
source = @file_wrapper.read(test_file)
# remove line comments
source = source.gsub(/\/\/.*$/, '')
# remove block comments
source = source.gsub(/\/\*.*?\*\//m, '')
# treat preprocessor directives as a logical line
lines = source.split(/(^\s*\#.*$) | (;|\{|\}) /x) # match ;, {, and } as end of lines
# otherwise, read the preprocessed file raw
else
lines = @file_wrapper.read( @file_path_utils.form_preprocessed_file_filepath(test_file) ).split(/;|\{|\}/)
end
# step 1. find test functions in (possibly preprocessed) file
# (note that lines are not broken up at end of lines)
lines.each do |line|
if (line =~ /^\s*void\s+((T|t)est.*)\s*\(\s*(void)?\s*\)/m)
tests << ($1.strip)
end
end
# step 2. associate test functions with line numbers in (non-preprocessed) original file
# (note that this time we must scan file contents broken up by end of lines)
raw_lines = @file_wrapper.read(test_file).split("\n")
raw_index = 0
tests.each do |test|
raw_lines[raw_index..-1].each_with_index do |line, index|
# test function might be declared across lines; look for it by its name followed
# by a few tell-tale signs
if (line =~ /#{test}\s*($|\(|\()/)
raw_index += (index + 1)
tests_and_line_numbers << {:test => test, :line_number => raw_index}
break
end
end
end
return tests_and_line_numbers
end
def generate(module_name, runner_filepath, test_cases, mock_list)
require 'generate_test_runner.rb'
@test_runner_generator ||= UnityTestRunnerGenerator.new( @configurator.get_runner_config )
@test_runner_generator.generate( module_name,
runner_filepath,
test_cases,
mock_list)
end
end

View File

@ -1,31 +0,0 @@
class Loginator
constructor :configurator, :project_file_loader, :project_config_manager, :file_wrapper, :system_wrapper
def setup_log_filepath
config_files = []
config_files << @project_file_loader.main_file
config_files << @project_file_loader.user_file
config_files.concat( @project_config_manager.options_files )
config_files.compact!
config_files.map! { |file| file.ext('') }
log_name = config_files.join( '_' )
@project_log_filepath = File.join( @configurator.project_log_path, log_name.ext('.log') )
end
def log(string, heading=nil)
return if (not @configurator.project_logging)
output = "\n[#{@system_wrapper.time_now}]"
output += " :: #{heading}" if (not heading.nil?)
output += "\n#{string.strip}\n"
@file_wrapper.write(@project_log_filepath, output, 'a')
end
end

View File

@ -1,46 +0,0 @@
# modified version of Rake's provided make-style dependency loader
# customizations:
# (1) handles windows drives in paths -- colons don't confuse task demarcation
# (2) handles spaces in directory paths
module Rake
# Makefile loader to be used with the import file loader.
class MakefileLoader
# Load the makefile dependencies in +fn+.
def load(fn)
open(fn) do |mf|
lines = mf.read
lines.gsub!(/#[^\n]*\n/m, "") # remove comments
lines.gsub!(/\\\n/, ' ') # string together line continuations into single line
lines.split("\n").each do |line|
process_line(line)
end
end
end
private
# Process one logical line of makefile data.
def process_line(line)
# split on presence of task demaractor followed by space (i.e don't get confused by a colon in a win path)
file_tasks, args = line.split(/:\s/)
return if args.nil?
# split at non-escaped space boundary between files (i.e. escaped spaces in paths are left alone)
dependents = args.split(/\b\s+/)
# replace escaped spaces and clean up any extra whitespace
dependents.map! { |path| path.gsub(/\\ /, ' ').strip }
file_tasks.strip.split.each do |file_task|
file file_task => dependents
end
end
end
# Install the handler
Rake.application.add_loader('mf', MakefileLoader.new)
end

View File

@ -1,307 +0,0 @@
file_wrapper:
file_system_wrapper:
stream_wrapper:
rake_wrapper:
yaml_wrapper:
system_wrapper:
cmock_builder:
reportinator:
rake_utils:
compose:
- rake_wrapper
system_utils:
compose:
- system_wrapper
file_path_utils:
compose:
- configurator
- file_wrapper
file_system_utils:
compose: file_wrapper
project_file_loader:
compose:
- yaml_wrapper
- stream_wrapper
- system_wrapper
- file_wrapper
project_config_manager:
compose:
- cacheinator
- yaml_wrapper
cacheinator:
compose:
- cacheinator_helper
- file_path_utils
- file_wrapper
- yaml_wrapper
cacheinator_helper:
compose:
- file_wrapper
- yaml_wrapper
tool_executor:
compose:
- configurator
- tool_executor_helper
- streaminator
- system_wrapper
tool_executor_helper:
compose:
- streaminator
- system_utils
- system_wrapper
configurator:
compose:
- configurator_setup
- configurator_plugins
- configurator_builder
- cmock_builder
- yaml_wrapper
- system_wrapper
configurator_setup:
compose:
- configurator_builder
- configurator_validator
- configurator_plugins
- stream_wrapper
configurator_plugins:
compose:
- stream_wrapper
- file_wrapper
- system_wrapper
configurator_validator:
compose:
- file_wrapper
- stream_wrapper
- system_wrapper
configurator_builder:
compose:
- file_system_utils
- file_wrapper
- system_wrapper
loginator:
compose:
- configurator
- project_file_loader
- project_config_manager
- file_wrapper
- system_wrapper
streaminator:
compose:
- streaminator_helper
- verbosinator
- loginator
- stream_wrapper
streaminator_helper:
setupinator:
plugin_builder:
plugin_manager:
compose:
- configurator
- plugin_manager_helper
- streaminator
- reportinator
- system_wrapper
plugin_manager_helper:
plugin_reportinator:
compose:
- plugin_reportinator_helper
- plugin_manager
- reportinator
plugin_reportinator_helper:
compose:
- configurator
- streaminator
- yaml_wrapper
- file_wrapper
verbosinator:
compose: configurator
file_finder:
compose:
- configurator
- file_finder_helper
- cacheinator
- file_path_utils
- file_wrapper
- yaml_wrapper
file_finder_helper:
compose: streaminator
test_includes_extractor:
compose:
- configurator
- yaml_wrapper
- file_wrapper
task_invoker:
compose:
- dependinator
- rake_utils
- rake_wrapper
flaginator:
compose:
- configurator
generator:
compose:
- configurator
- generator_helper
- preprocessinator
- cmock_builder
- generator_test_runner
- generator_test_results
- flaginator
- test_includes_extractor
- tool_executor
- file_finder
- file_path_utils
- streaminator
- plugin_manager
- file_wrapper
generator_helper:
compose:
- streaminator
generator_test_results:
compose:
- configurator
- generator_test_results_sanity_checker
- yaml_wrapper
generator_test_results_sanity_checker:
compose:
- configurator
- streaminator
generator_test_runner:
compose:
- configurator
- file_path_utils
- file_wrapper
dependinator:
compose:
- configurator
- project_config_manager
- test_includes_extractor
- file_path_utils
- rake_wrapper
- file_wrapper
preprocessinator:
compose:
- preprocessinator_helper
- preprocessinator_includes_handler
- preprocessinator_file_handler
- task_invoker
- file_path_utils
- yaml_wrapper
preprocessinator_helper:
compose:
- configurator
- test_includes_extractor
- task_invoker
- file_finder
- file_path_utils
preprocessinator_includes_handler:
compose:
- configurator
- tool_executor
- task_invoker
- file_path_utils
- yaml_wrapper
- file_wrapper
preprocessinator_file_handler:
compose:
- preprocessinator_extractor
- configurator
- tool_executor
- file_path_utils
- file_wrapper
preprocessinator_extractor:
test_invoker:
compose:
- configurator
- test_invoker_helper
- plugin_manager
- streaminator
- preprocessinator
- task_invoker
- dependinator
- project_config_manager
- build_invoker_utils
- file_path_utils
- file_wrapper
test_invoker_helper:
compose:
- configurator
- task_invoker
- test_includes_extractor
- file_finder
- file_path_utils
- file_wrapper
release_invoker:
compose:
- configurator
- release_invoker_helper
- build_invoker_utils
- dependinator
- task_invoker
- file_path_utils
- file_wrapper
release_invoker_helper:
compose:
- configurator
- dependinator
- task_invoker
build_invoker_utils:
compose:
- configurator
- streaminator
erb_wrapper:

View File

@ -1,19 +0,0 @@
def par_map(n, things, &block)
queue = Queue.new
things.each { |thing| queue << thing }
threads = (1..n).collect do
Thread.new do
begin
while true
yield queue.pop(true)
end
rescue ThreadError
end
end
end
threads.each { |t| t.join }
end

View File

@ -1,80 +0,0 @@
class String
# reformat a multiline string to have given number of whitespace columns;
# helpful for formatting heredocs
def left_margin(margin=0)
non_whitespace_column = 0
new_lines = []
# find first line with non-whitespace and count left columns of whitespace
self.each_line do |line|
if (line =~ /^\s*\S/)
non_whitespace_column = $&.length - 1
break
end
end
# iterate through each line, chopping off leftmost whitespace columns and add back the desired whitespace margin
self.each_line do |line|
columns = []
margin.times{columns << ' '}
# handle special case of line being narrower than width to be lopped off
if (non_whitespace_column < line.length)
new_lines << "#{columns.join}#{line[non_whitespace_column..-1]}"
else
new_lines << "\n"
end
end
return new_lines.join
end
end
class Plugin
attr_reader :name, :environment
attr_accessor :plugin_objects
def initialize(system_objects, name)
@environment = []
@ceedling = system_objects
@name = name
self.setup
end
def setup; end
# mock generation
def pre_mock_generate(arg_hash); end
def post_mock_generate(arg_hash); end
# test runner generation
def pre_runner_generate(arg_hash); end
def post_runner_generate(arg_hash); end
# compilation (test or source)
def pre_compile_execute(arg_hash); end
def post_compile_execute(arg_hash); end
# linking (test or source)
def pre_link_execute(arg_hash); end
def post_link_execute(arg_hash); end
# test fixture execution
def pre_test_fixture_execute(arg_hash); end
def post_test_fixture_execute(arg_hash); end
# test task
def pre_test; end
def post_test; end
# release task
def pre_release; end
def post_release; end
# whole shebang (any use of Ceedling)
def pre_build; end
def post_build; end
def summary; end
end

View File

@ -1,53 +0,0 @@
require 'plugin'
class PluginBuilder
attr_accessor :plugin_objects
def construct_plugin(plugin_name, object_map_yaml, system_objects)
# @streaminator.stdout_puts("Constructing plugin #{plugin_name}...", Verbosity::OBNOXIOUS)
object_map = {}
@plugin_objects = {}
@system_objects = system_objects
if object_map_yaml
@object_map = YAML.load(object_map_yaml)
@object_map.each_key do |obj|
construct_object(obj)
end
else
raise "Invalid object map for plugin #{plugin_name}!"
end
return @plugin_objects
end
private
def camelize(underscored_name)
return underscored_name.gsub(/(_|^)([a-z0-9])/) {$2.upcase}
end
def construct_object(obj)
if @plugin_objects[obj].nil?
if @object_map[obj] && @object_map[obj]['compose']
@object_map[obj]['compose'].each do |dep|
construct_object(dep)
end
end
build_object(obj)
end
end
def build_object(new_object)
if @plugin_objects[new_object.to_sym].nil?
# @streaminator.stdout_puts("Building plugin object #{new_object}", Verbosity::OBNOXIOUS)
require new_object
class_name = camelize(new_object)
new_instance = eval("#{class_name}.new(@system_objects, class_name.to_s)")
new_instance.plugin_objects = @plugin_objects
@plugin_objects[new_object.to_sym] = new_instance
end
end
end

View File

@ -1,107 +0,0 @@
require 'constants'
require 'set'
class PluginManager
constructor :configurator, :plugin_manager_helper, :streaminator, :reportinator, :system_wrapper
def setup
@build_fail_registry = []
@plugin_objects = [] # so we can preserve order
end
def load_plugin_scripts(script_plugins, system_objects)
environment = []
script_plugins.each do |plugin|
# protect against instantiating object multiple times due to processing config multiple times (option files, etc)
next if (@plugin_manager_helper.include?(@plugin_objects, plugin))
begin
@system_wrapper.require_file( "#{plugin}.rb" )
object = @plugin_manager_helper.instantiate_plugin_script( camelize(plugin), system_objects, plugin )
@plugin_objects << object
environment += object.environment
# add plugins to hash of all system objects
system_objects[plugin.downcase.to_sym] = object
rescue
puts "Exception raised while trying to load plugin: #{plugin}"
raise
end
end
yield( { :environment => environment } ) if (environment.size > 0)
end
def plugins_failed?
return (@build_fail_registry.size > 0)
end
def print_plugin_failures
if (@build_fail_registry.size > 0)
report = @reportinator.generate_banner('BUILD FAILURE SUMMARY')
@build_fail_registry.each do |failure|
report += "#{' - ' if (@build_fail_registry.size > 1)}#{failure}\n"
end
report += "\n"
@streaminator.stderr_puts(report, Verbosity::ERRORS)
end
end
def register_build_failure(message)
@build_fail_registry << message if (message and not message.empty?)
end
#### execute all plugin methods ####
def pre_mock_generate(arg_hash); execute_plugins(:pre_mock_generate, arg_hash); end
def post_mock_generate(arg_hash); execute_plugins(:post_mock_generate, arg_hash); end
def pre_runner_generate(arg_hash); execute_plugins(:pre_runner_generate, arg_hash); end
def post_runner_generate(arg_hash); execute_plugins(:post_runner_generate, arg_hash); end
def pre_compile_execute(arg_hash); execute_plugins(:pre_compile_execute, arg_hash); end
def post_compile_execute(arg_hash); execute_plugins(:post_compile_execute, arg_hash); end
def pre_link_execute(arg_hash); execute_plugins(:pre_link_execute, arg_hash); end
def post_link_execute(arg_hash); execute_plugins(:post_link_execute, arg_hash); end
def pre_test_fixture_execute(arg_hash); execute_plugins(:pre_test_fixture_execute, arg_hash); end
def post_test_fixture_execute(arg_hash)
# special arbitration: raw test results are printed or taken over by plugins handling the job
@streaminator.stdout_puts(arg_hash[:shell_result][:output]) if (@configurator.plugins_display_raw_test_results)
execute_plugins(:post_test_fixture_execute, arg_hash)
end
def pre_test; execute_plugins(:pre_test); end
def post_test; execute_plugins(:post_test); end
def pre_release; execute_plugins(:pre_release); end
def post_release; execute_plugins(:post_release); end
def pre_build; execute_plugins(:pre_build); end
def post_build; execute_plugins(:post_build); end
def summary; execute_plugins(:summary); end
private ####################################
def camelize(underscored_name)
return underscored_name.gsub(/(_|^)([a-z0-9])/) {$2.upcase}
end
def execute_plugins(method, *args)
@plugin_objects.each do |plugin|
begin
plugin.send(method, *args)
rescue
puts "Exception raised in plugin: #{plugin.name}, in method #{method}"
raise
end
end
end
end

View File

@ -1,19 +0,0 @@
class PluginManagerHelper
def include?(plugins, name)
include = false
plugins.each do |plugin|
if (plugin.name == name)
include = true
break
end
end
return include
end
def instantiate_plugin_script(plugin, system_objects, name)
return eval("#{plugin}.new(system_objects, name)")
end
end

View File

@ -1,75 +0,0 @@
require 'constants'
require 'defaults'
class PluginReportinator
constructor :plugin_reportinator_helper, :plugin_manager, :reportinator
def setup
@test_results_template = nil
end
def set_system_objects(system_objects)
@plugin_reportinator_helper.ceedling = system_objects
end
def fetch_results(results_path, test, options={:boom => false})
return @plugin_reportinator_helper.fetch_results( File.join(results_path, test), options )
end
def generate_banner(message)
return @reportinator.generate_banner(message)
end
def assemble_test_results(results_list, options={:boom => false})
aggregated_results = get_results_structure
results_list.each do |result_path|
results = @plugin_reportinator_helper.fetch_results( result_path, options )
@plugin_reportinator_helper.process_results(aggregated_results, results)
end
return aggregated_results
end
def register_test_results_template(template)
@test_results_template = template if (@test_results_template.nil?)
end
def run_test_results_report(hash, verbosity=Verbosity::NORMAL, &block)
run_report( $stdout,
((@test_results_template.nil?) ? DEFAULT_TESTS_RESULTS_REPORT_TEMPLATE : @test_results_template),
hash,
verbosity,
&block )
end
def run_report(stream, template, hash=nil, verbosity=Verbosity::NORMAL)
failure = nil
failure = yield() if block_given?
@plugin_manager.register_build_failure( failure )
@plugin_reportinator_helper.run_report( stream, template, hash, verbosity )
end
private ###############################
def get_results_structure
return {
:successes => [],
:failures => [],
:ignores => [],
:stdout => [],
:counts => {:total => 0, :passed => 0, :failed => 0, :ignored => 0, :stdout => 0}
}
end
end

View File

@ -1,52 +0,0 @@
require 'constants'
require 'erb'
require 'rubygems'
require 'rake' # for ext()
class PluginReportinatorHelper
attr_writer :ceedling
constructor :configurator, :streaminator, :yaml_wrapper, :file_wrapper
def fetch_results(results_path, options)
pass_path = File.join(results_path.ext( @configurator.extension_testpass ))
fail_path = File.join(results_path.ext( @configurator.extension_testfail ))
if (@file_wrapper.exist?(fail_path))
return @yaml_wrapper.load(fail_path)
elsif (@file_wrapper.exist?(pass_path))
return @yaml_wrapper.load(pass_path)
else
if (options[:boom])
@streaminator.stderr_puts("Could find no test results for '#{File.basename(results_path).ext(@configurator.extension_source)}'", Verbosity::ERRORS)
raise
end
end
return {}
end
def process_results(aggregate_results, results)
return if (results.empty?)
aggregate_results[:successes] << { :source => results[:source].clone, :collection => results[:successes].clone } if (results[:successes].size > 0)
aggregate_results[:failures] << { :source => results[:source].clone, :collection => results[:failures].clone } if (results[:failures].size > 0)
aggregate_results[:ignores] << { :source => results[:source].clone, :collection => results[:ignores].clone } if (results[:ignores].size > 0)
aggregate_results[:stdout] << { :source => results[:source].clone, :collection => results[:stdout].clone } if (results[:stdout].size > 0)
aggregate_results[:counts][:total] += results[:counts][:total]
aggregate_results[:counts][:passed] += results[:counts][:passed]
aggregate_results[:counts][:failed] += results[:counts][:failed]
aggregate_results[:counts][:ignored] += results[:counts][:ignored]
aggregate_results[:counts][:stdout] += results[:stdout].size
end
def run_report(stream, template, hash, verbosity)
output = ERB.new(template, 0, "%<>")
@streaminator.stream_puts(stream, output.result(binding()), verbosity)
end
end

View File

@ -1,43 +0,0 @@
class Preprocessinator
attr_reader :preprocess_file_proc
constructor :preprocessinator_helper, :preprocessinator_includes_handler, :preprocessinator_file_handler, :task_invoker, :file_path_utils, :yaml_wrapper
def setup
# fashion ourselves callbacks @preprocessinator_helper can use
@preprocess_includes_proc = Proc.new { |filepath| self.preprocess_shallow_includes(filepath) }
@preprocess_file_proc = Proc.new { |filepath| self.preprocess_file(filepath) }
end
def preprocess_test_and_invoke_test_mocks(test)
@preprocessinator_helper.preprocess_includes(test, @preprocess_includes_proc)
mocks_list = @preprocessinator_helper.assemble_mocks_list(test)
@preprocessinator_helper.preprocess_mockable_headers(mocks_list, @preprocess_file_proc)
@task_invoker.invoke_test_mocks(mocks_list)
@preprocessinator_helper.preprocess_test_file(test, @preprocess_file_proc)
return mocks_list
end
def preprocess_shallow_includes(filepath)
dependencies_rule = @preprocessinator_includes_handler.form_shallow_dependencies_rule(filepath)
includes = @preprocessinator_includes_handler.extract_shallow_includes(dependencies_rule)
@preprocessinator_includes_handler.write_shallow_includes_list(
@file_path_utils.form_preprocessed_includes_list_filepath(filepath), includes)
end
def preprocess_file(filepath)
@preprocessinator_includes_handler.invoke_shallow_includes_list(filepath)
@preprocessinator_file_handler.preprocess_file( filepath, @yaml_wrapper.load(@file_path_utils.form_preprocessed_includes_list_filepath(filepath)) )
end
end

View File

@ -1,30 +0,0 @@
class PreprocessinatorExtractor
def extract_base_file_from_preprocessed_expansion(filepath)
# preprocessing by way of toolchain preprocessor expands macros, eliminates
# comments, strips out #ifdef code, etc. however, it also expands in place
# each #include'd file. so, we must extract only the lines of the file
# that belong to the file originally preprocessed
# iterate through all lines and alternate between extract and ignore modes
# all lines between a '#'line containing file name of our filepath and the
# next '#'line should be extracted
base_name = File.basename(filepath)
not_pragma = /^#(?!pragma\b)/ # preprocessor directive that's not a #pragma
pattern = /^#.*(\s|\/|\\|\")#{Regexp.escape(base_name)}/
found_file = false # have we found the file we care about?
lines = []
File.readlines(filepath).each do |line|
if found_file and not line.match(not_pragma)
lines << line
else
found_file = false
end
found_file = true if line.match(pattern)
end
return lines
end
end

View File

@ -1,21 +0,0 @@
class PreprocessinatorFileHandler
constructor :preprocessinator_extractor, :configurator, :tool_executor, :file_path_utils, :file_wrapper
def preprocess_file(filepath, includes)
preprocessed_filepath = @file_path_utils.form_preprocessed_file_filepath(filepath)
command = @tool_executor.build_command_line(@configurator.tools_test_file_preprocessor, filepath, preprocessed_filepath)
@tool_executor.exec(command[:line], command[:options])
contents = @preprocessinator_extractor.extract_base_file_from_preprocessed_expansion(preprocessed_filepath)
includes.each{|include| contents.unshift("#include \"#{include}\"")}
@file_wrapper.write(preprocessed_filepath, contents.join("\n"))
end
end

View File

@ -1,46 +0,0 @@
class PreprocessinatorHelper
constructor :configurator, :test_includes_extractor, :task_invoker, :file_finder, :file_path_utils
def preprocess_includes(test, preprocess_includes_proc)
if (@configurator.project_use_test_preprocessor)
preprocessed_includes_list = @file_path_utils.form_preprocessed_includes_list_filepath(test)
preprocess_includes_proc.call( @file_finder.find_test_from_file_path(preprocessed_includes_list) )
@test_includes_extractor.parse_includes_list(preprocessed_includes_list)
else
@test_includes_extractor.parse_test_file(test)
end
end
def assemble_mocks_list(test)
return @file_path_utils.form_mocks_source_filelist( @test_includes_extractor.lookup_raw_mock_list(test) )
end
def preprocess_mockable_headers(mock_list, preprocess_file_proc)
if (@configurator.project_use_test_preprocessor)
preprocess_files_smartly(
@file_path_utils.form_preprocessed_mockable_headers_filelist(mock_list),
preprocess_file_proc ) { |file| @file_finder.find_header_file(file) }
end
end
def preprocess_test_file(test, preprocess_file_proc)
return if (!@configurator.project_use_test_preprocessor)
preprocess_file_proc.call(test)
end
private ############################
def preprocess_files_smartly(file_list, preprocess_file_proc)
if (@configurator.project_use_deep_dependencies)
@task_invoker.invoke_test_preprocessed_files(file_list)
else
file_list.each { |file| preprocess_file_proc.call( yield(file) ) }
end
end
end

View File

@ -1,55 +0,0 @@
class PreprocessinatorIncludesHandler
constructor :configurator, :tool_executor, :task_invoker, :file_path_utils, :yaml_wrapper, :file_wrapper
# shallow includes: only those headers a source file explicitly includes
def invoke_shallow_includes_list(filepath)
@task_invoker.invoke_test_shallow_include_lists( [@file_path_utils.form_preprocessed_includes_list_filepath(filepath)] )
end
# ask the preprocessor for a make-style dependency rule of only the headers the source file immediately includes
def form_shallow_dependencies_rule(filepath)
# change filename (prefix of '_') to prevent preprocessor from finding include files in temp directory containing file it's scanning
temp_filepath = @file_path_utils.form_temp_path(filepath, '_')
# read the file and replace all include statements with a decorated version
# (decorating the names creates file names that don't exist, thus preventing the preprocessor
# from snaking out and discovering the entire include path that winds through the code)
contents = @file_wrapper.read(filepath)
contents.gsub!( /#include\s+\"\s*(\S+)\s*\"/, "#include \"\\1\"\n#include \"@@@@\\1\"" )
@file_wrapper.write( temp_filepath, contents )
# extract the make-style dependency rule telling the preprocessor to
# ignore the fact that it can't find the included files
command = @tool_executor.build_command_line(@configurator.tools_test_includes_preprocessor, temp_filepath)
shell_result = @tool_executor.exec(command[:line], command[:options])
return shell_result[:output]
end
# headers only; ignore any crazy .c includes
def extract_shallow_includes(make_rule)
list = []
header_extension = @configurator.extension_header
headers = make_rule.scan(/(\S+#{'\\'+header_extension})/).flatten # escape slashes before dot file extension
headers.uniq!
headers.map! { |header| header.sub(/(@@@@)|(.+\/)/, '') }
headers.sort!
headers.each_with_index do |header, index|
break if (headers.size == (index-1))
list << header if (header == headers[index + 1])
end
return list
end
def write_shallow_includes_list(filepath, list)
@yaml_wrapper.dump(filepath, list)
end
end

View File

@ -1,38 +0,0 @@
require 'constants'
class ProjectConfigManager
attr_reader :options_files, :release_config_changed, :test_config_changed
attr_accessor :config_hash
constructor :cacheinator, :yaml_wrapper
def setup
@options_files = []
@release_config_changed = false
@test_config_changed = false
end
def merge_options(config_hash, option_filepath)
@options_files << File.basename( option_filepath )
config_hash.deep_merge( @yaml_wrapper.load( option_filepath ) )
return config_hash
end
def process_release_config_change
# has project configuration changed since last release build
@release_config_changed = @cacheinator.diff_cached_release_config?( @config_hash )
end
def process_test_config_change
# has project configuration changed since last test build
@test_config_changed = @cacheinator.diff_cached_test_config?( @config_hash )
end
end

View File

@ -1,64 +0,0 @@
require 'constants'
class ProjectFileLoader
attr_reader :main_file, :user_file
constructor :yaml_wrapper, :stream_wrapper, :system_wrapper, :file_wrapper
def setup
@main_file = nil
@user_file = nil
@main_project_filepath = ''
@user_project_filepath = ''
end
def find_project_files
# first go hunting for optional user project file by looking for environment variable and then default location on disk
user_filepath = @system_wrapper.env_get('CEEDLING_USER_PROJECT_FILE')
if ( not user_filepath.nil? and @file_wrapper.exist?(user_filepath) )
@user_project_filepath = user_filepath
elsif (@file_wrapper.exist?(DEFAULT_CEEDLING_USER_PROJECT_FILE))
@user_project_filepath = DEFAULT_CEEDLING_USER_PROJECT_FILE
end
# next check for main project file by looking for environment variable and then default location on disk;
# blow up if we don't find this guy -- like, he's so totally important
main_filepath = @system_wrapper.env_get('CEEDLING_MAIN_PROJECT_FILE')
if ( not main_filepath.nil? and @file_wrapper.exist?(main_filepath) )
@main_project_filepath = main_filepath
elsif (@file_wrapper.exist?(DEFAULT_CEEDLING_MAIN_PROJECT_FILE))
@main_project_filepath = DEFAULT_CEEDLING_MAIN_PROJECT_FILE
else
# no verbosity checking since this is lowest level reporting anyhow &
# verbosity checking depends on configurator which in turns needs this class (circular dependency)
@stream_wrapper.stderr_puts('Found no Ceedling project file (*.yml)')
raise
end
@main_file = File.basename( @main_project_filepath )
@user_file = File.basename( @user_project_filepath ) if ( not @user_project_filepath.empty? )
end
def load_project_config
config_hash = {}
# if there's no user project file, then just provide hash from project file
if (@user_project_filepath.empty?)
config_hash = @yaml_wrapper.load(@main_project_filepath)
# if there is a user project file, load it too and merge it on top of the project file,
# superseding anything that's common between them
else
config_hash = (@yaml_wrapper.load(@main_project_filepath)).merge(@yaml_wrapper.load(@user_project_filepath))
end
return config_hash
end
end

View File

@ -1,17 +0,0 @@
class RakeUtils
constructor :rake_wrapper
def task_invoked?(task_regex)
task_invoked = false
@rake_wrapper.task_list.each do |task|
if ((task.already_invoked) and (task.to_s =~ task_regex))
task_invoked = true
break
end
end
return task_invoked
end
end

View File

@ -1,33 +0,0 @@
require 'rubygems'
require 'rake'
require 'makefile' # our replacement for rake's make-style dependency loader
include Rake::DSL if defined?(Rake::DSL)
class Rake::Task
attr_reader :already_invoked
end
class RakeWrapper
def initialize
@makefile_loader = Rake::MakefileLoader.new # use our custom replacement noted above
end
def [](task)
return Rake::Task[task]
end
def task_list
return Rake::Task.tasks
end
def create_file_task(file_task, dependencies)
file(file_task => dependencies)
end
def load_dependencies(dependencies_path)
@makefile_loader.load(dependencies_path)
end
end

Some files were not shown because too many files have changed in this diff Show More