Explorar el Código

change desc_str_table to array of pointer of uint8_t* to be compatible with IAR (lack of support for VLA initialization)
IAR device os none works with ea4357

hathach hace 12 años
padre
commit
b586fe632a

+ 2975 - 0
demos/device/device_os_none/device_os_none.ewp

@@ -0,0 +1,2975 @@
+<?xml version="1.0" encoding="iso-8859-1"?>
+
+<project>
+  <fileVersion>2</fileVersion>
+  <configuration>
+    <name>Board EA4357</name>
+    <toolchain>
+      <name>ARM</name>
+    </toolchain>
+    <debug>1</debug>
+    <settings>
+      <name>General</name>
+      <archiveVersion>3</archiveVersion>
+      <data>
+        <version>21</version>
+        <wantNonLocal>1</wantNonLocal>
+        <debug>1</debug>
+        <option>
+          <name>ExePath</name>
+          <state>Board EA4357\Exe</state>
+        </option>
+        <option>
+          <name>ObjPath</name>
+          <state>Board EA4357\Obj</state>
+        </option>
+        <option>
+          <name>ListPath</name>
+          <state>Board EA4357\List</state>
+        </option>
+        <option>
+          <name>Variant</name>
+          <version>20</version>
+          <state>39</state>
+        </option>
+        <option>
+          <name>GEndianMode</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>Input variant</name>
+          <version>3</version>
+          <state>0</state>
+        </option>
+        <option>
+          <name>Input description</name>
+          <state>Automatic choice of formatter.</state>
+        </option>
+        <option>
+          <name>Output variant</name>
+          <version>2</version>
+          <state>0</state>
+        </option>
+        <option>
+          <name>Output description</name>
+          <state>Automatic choice of formatter.</state>
+        </option>
+        <option>
+          <name>GOutputBinary</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>FPU</name>
+          <version>2</version>
+          <state>5</state>
+        </option>
+        <option>
+          <name>OGCoreOrChip</name>
+          <state>1</state>
+        </option>
+        <option>
+          <name>GRuntimeLibSelect</name>
+          <version>0</version>
+          <state>1</state>
+        </option>
+        <option>
+          <name>GRuntimeLibSelectSlave</name>
+          <version>0</version>
+          <state>1</state>
+        </option>
+        <option>
+          <name>RTDescription</name>
+          <state>Use the normal configuration of the C/C++ runtime library. No locale interface, C locale, no file descriptor support, no multibytes in printf and scanf, and no hex floats in strtod.</state>
+        </option>
+        <option>
+          <name>OGProductVersion</name>
+          <state>6.50.5.4846</state>
+        </option>
+        <option>
+          <name>OGLastSavedByProductVersion</name>
+          <state>6.50.5.4846</state>
+        </option>
+        <option>
+          <name>GeneralEnableMisra</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>GeneralMisraVerbose</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>OGChipSelectEditMenu</name>
+          <state>LPC4357_M4	NXP LPC4357_M4</state>
+        </option>
+        <option>
+          <name>GenLowLevelInterface</name>
+          <state>1</state>
+        </option>
+        <option>
+          <name>GEndianModeBE</name>
+          <state>1</state>
+        </option>
+        <option>
+          <name>OGBufferedTerminalOutput</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>GenStdoutInterface</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>GeneralMisraRules98</name>
+          <version>0</version>
+          <state>1000111110110101101110011100111111101110011011000101110111101101100111111111111100110011111001110111001111111111111111111111111</state>
+        </option>
+        <option>
+          <name>GeneralMisraVer</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>GeneralMisraRules04</name>
+          <version>0</version>
+          <state>111101010010111111111000110011111101111111111111110110010111101111010101111111111111111111111111101111111011110001111011111011111111111111111</state>
+        </option>
+        <option>
+          <name>RTConfigPath2</name>
+          <state>$TOOLKIT_DIR$\INC\c\DLib_Config_Normal.h</state>
+        </option>
+        <option>
+          <name>GFPUCoreSlave</name>
+          <version>20</version>
+          <state>39</state>
+        </option>
+        <option>
+          <name>GBECoreSlave</name>
+          <version>20</version>
+          <state>39</state>
+        </option>
+        <option>
+          <name>OGUseCmsis</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>OGUseCmsisDspLib</name>
+          <state>0</state>
+        </option>
+      </data>
+    </settings>
+    <settings>
+      <name>ICCARM</name>
+      <archiveVersion>2</archiveVersion>
+      <data>
+        <version>28</version>
+        <wantNonLocal>1</wantNonLocal>
+        <debug>1</debug>
+        <option>
+          <name>CCDefines</name>
+          <state>CORE_M4</state>
+          <state>TUSB_CFG_MCU=MCU_LPC43XX</state>
+          <state>BOARD=BOARD_EA4357</state>
+          <state>TUSB_CFG_OS=TUSB_OS_NONE</state>
+        </option>
+        <option>
+          <name>CCPreprocFile</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>CCPreprocComments</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>CCPreprocLine</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>CCListCFile</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>CCListCMnemonics</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>CCListCMessages</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>CCListAssFile</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>CCListAssSource</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>CCEnableRemarks</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>CCDiagSuppress</name>
+          <state></state>
+        </option>
+        <option>
+          <name>CCDiagRemark</name>
+          <state></state>
+        </option>
+        <option>
+          <name>CCDiagWarning</name>
+          <state></state>
+        </option>
+        <option>
+          <name>CCDiagError</name>
+          <state></state>
+        </option>
+        <option>
+          <name>CCObjPrefix</name>
+          <state>1</state>
+        </option>
+        <option>
+          <name>CCAllowList</name>
+          <version>1</version>
+          <state>0000000</state>
+        </option>
+        <option>
+          <name>CCDebugInfo</name>
+          <state>1</state>
+        </option>
+        <option>
+          <name>IEndianMode</name>
+          <state>1</state>
+        </option>
+        <option>
+          <name>IProcessor</name>
+          <state>1</state>
+        </option>
+        <option>
+          <name>IExtraOptionsCheck</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>IExtraOptions</name>
+          <state></state>
+        </option>
+        <option>
+          <name>CCLangConformance</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>CCSignedPlainChar</name>
+          <state>1</state>
+        </option>
+        <option>
+          <name>CCRequirePrototypes</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>CCMultibyteSupport</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>CCDiagWarnAreErr</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>CCCompilerRuntimeInfo</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>IFpuProcessor</name>
+          <state>1</state>
+        </option>
+        <option>
+          <name>OutputFile</name>
+          <state>$FILE_BNAME$.o</state>
+        </option>
+        <option>
+          <name>CCLibConfigHeader</name>
+          <state>1</state>
+        </option>
+        <option>
+          <name>PreInclude</name>
+          <state></state>
+        </option>
+        <option>
+          <name>CompilerMisraOverride</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>CCIncludePath2</name>
+          <state>$PROJ_DIR$\..\src</state>
+          <state>$PROJ_DIR$\..\..\bsp\lpc43xx\CMSIS_LPC43xx_DriverLib\inc</state>
+          <state>$PROJ_DIR$\..\..\bsp</state>
+          <state>$PROJ_DIR$\..\..\..\tinyusb</state>
+        </option>
+        <option>
+          <name>CCStdIncCheck</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>CCCodeSection</name>
+          <state>.text</state>
+        </option>
+        <option>
+          <name>IInterwork2</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>IProcessorMode2</name>
+          <state>1</state>
+        </option>
+        <option>
+          <name>CCOptLevel</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>CCOptStrategy</name>
+          <version>0</version>
+          <state>0</state>
+        </option>
+        <option>
+          <name>CCOptLevelSlave</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>CompilerMisraRules98</name>
+          <version>0</version>
+          <state>1000111110110101101110011100111111101110011011000101110111101101100111111111111100110011111001110111001111111111111111111111111</state>
+        </option>
+        <option>
+          <name>CompilerMisraRules04</name>
+          <version>0</version>
+          <state>111101110010111111111000110111111111111111111111111110010111101111010101111111111111111111111111101111111011111001111011111011111111111111111</state>
+        </option>
+        <option>
+          <name>CCPosIndRopi</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>CCPosIndRwpi</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>CCPosIndNoDynInit</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>IccLang</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>IccCDialect</name>
+          <state>1</state>
+        </option>
+        <option>
+          <name>IccAllowVLA</name>
+          <state>1</state>
+        </option>
+        <option>
+          <name>IccCppDialect</name>
+          <state>1</state>
+        </option>
+        <option>
+          <name>IccExceptions</name>
+          <state>1</state>
+        </option>
+        <option>
+          <name>IccRTTI</name>
+          <state>1</state>
+        </option>
+        <option>
+          <name>IccStaticDestr</name>
+          <state>1</state>
+        </option>
+        <option>
+          <name>IccCppInlineSemantics</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>IccCmsis</name>
+          <state>1</state>
+        </option>
+        <option>
+          <name>IccFloatSemantics</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>CCOptimizationNoSizeConstraints</name>
+          <state>0</state>
+        </option>
+      </data>
+    </settings>
+    <settings>
+      <name>AARM</name>
+      <archiveVersion>2</archiveVersion>
+      <data>
+        <version>8</version>
+        <wantNonLocal>1</wantNonLocal>
+        <debug>1</debug>
+        <option>
+          <name>AObjPrefix</name>
+          <state>1</state>
+        </option>
+        <option>
+          <name>AEndian</name>
+          <state>1</state>
+        </option>
+        <option>
+          <name>ACaseSensitivity</name>
+          <state>1</state>
+        </option>
+        <option>
+          <name>MacroChars</name>
+          <version>0</version>
+          <state>0</state>
+        </option>
+        <option>
+          <name>AWarnEnable</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>AWarnWhat</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>AWarnOne</name>
+          <state></state>
+        </option>
+        <option>
+          <name>AWarnRange1</name>
+          <state></state>
+        </option>
+        <option>
+          <name>AWarnRange2</name>
+          <state></state>
+        </option>
+        <option>
+          <name>ADebug</name>
+          <state>1</state>
+        </option>
+        <option>
+          <name>AltRegisterNames</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>ADefines</name>
+          <state></state>
+        </option>
+        <option>
+          <name>AList</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>AListHeader</name>
+          <state>1</state>
+        </option>
+        <option>
+          <name>AListing</name>
+          <state>1</state>
+        </option>
+        <option>
+          <name>Includes</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>MacDefs</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>MacExps</name>
+          <state>1</state>
+        </option>
+        <option>
+          <name>MacExec</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>OnlyAssed</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>MultiLine</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>PageLengthCheck</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>PageLength</name>
+          <state>80</state>
+        </option>
+        <option>
+          <name>TabSpacing</name>
+          <state>8</state>
+        </option>
+        <option>
+          <name>AXRef</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>AXRefDefines</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>AXRefInternal</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>AXRefDual</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>AProcessor</name>
+          <state>1</state>
+        </option>
+        <option>
+          <name>AFpuProcessor</name>
+          <state>1</state>
+        </option>
+        <option>
+          <name>AOutputFile</name>
+          <state>$FILE_BNAME$.o</state>
+        </option>
+        <option>
+          <name>AMultibyteSupport</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>ALimitErrorsCheck</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>ALimitErrorsEdit</name>
+          <state>100</state>
+        </option>
+        <option>
+          <name>AIgnoreStdInclude</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>AUserIncludes</name>
+          <state></state>
+        </option>
+        <option>
+          <name>AExtraOptionsCheckV2</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>AExtraOptionsV2</name>
+          <state></state>
+        </option>
+      </data>
+    </settings>
+    <settings>
+      <name>OBJCOPY</name>
+      <archiveVersion>0</archiveVersion>
+      <data>
+        <version>1</version>
+        <wantNonLocal>1</wantNonLocal>
+        <debug>1</debug>
+        <option>
+          <name>OOCOutputFormat</name>
+          <version>2</version>
+          <state>0</state>
+        </option>
+        <option>
+          <name>OCOutputOverride</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>OOCOutputFile</name>
+          <state>device_os_none.srec</state>
+        </option>
+        <option>
+          <name>OOCCommandLineProducer</name>
+          <state>1</state>
+        </option>
+        <option>
+          <name>OOCObjCopyEnable</name>
+          <state>0</state>
+        </option>
+      </data>
+    </settings>
+    <settings>
+      <name>CUSTOM</name>
+      <archiveVersion>3</archiveVersion>
+      <data>
+        <extensions></extensions>
+        <cmdline></cmdline>
+      </data>
+    </settings>
+    <settings>
+      <name>BICOMP</name>
+      <archiveVersion>0</archiveVersion>
+      <data/>
+    </settings>
+    <settings>
+      <name>BUILDACTION</name>
+      <archiveVersion>1</archiveVersion>
+      <data>
+        <prebuild></prebuild>
+        <postbuild></postbuild>
+      </data>
+    </settings>
+    <settings>
+      <name>ILINK</name>
+      <archiveVersion>0</archiveVersion>
+      <data>
+        <version>15</version>
+        <wantNonLocal>1</wantNonLocal>
+        <debug>1</debug>
+        <option>
+          <name>IlinkLibIOConfig</name>
+          <state>1</state>
+        </option>
+        <option>
+          <name>XLinkMisraHandler</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>IlinkInputFileSlave</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>IlinkOutputFile</name>
+          <state>device_os_none.out</state>
+        </option>
+        <option>
+          <name>IlinkDebugInfoEnable</name>
+          <state>1</state>
+        </option>
+        <option>
+          <name>IlinkKeepSymbols</name>
+          <state></state>
+        </option>
+        <option>
+          <name>IlinkRawBinaryFile</name>
+          <state></state>
+        </option>
+        <option>
+          <name>IlinkRawBinarySymbol</name>
+          <state></state>
+        </option>
+        <option>
+          <name>IlinkRawBinarySegment</name>
+          <state></state>
+        </option>
+        <option>
+          <name>IlinkRawBinaryAlign</name>
+          <state></state>
+        </option>
+        <option>
+          <name>IlinkDefines</name>
+          <state></state>
+        </option>
+        <option>
+          <name>IlinkConfigDefines</name>
+          <state></state>
+        </option>
+        <option>
+          <name>IlinkMapFile</name>
+          <state>1</state>
+        </option>
+        <option>
+          <name>IlinkLogFile</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>IlinkLogInitialization</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>IlinkLogModule</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>IlinkLogSection</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>IlinkLogVeneer</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>IlinkIcfOverride</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>IlinkIcfFile</name>
+          <state>$TOOLKIT_DIR$\config\linker\NXP\LPC4357_M4.icf</state>
+        </option>
+        <option>
+          <name>IlinkIcfFileSlave</name>
+          <state></state>
+        </option>
+        <option>
+          <name>IlinkEnableRemarks</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>IlinkSuppressDiags</name>
+          <state></state>
+        </option>
+        <option>
+          <name>IlinkTreatAsRem</name>
+          <state></state>
+        </option>
+        <option>
+          <name>IlinkTreatAsWarn</name>
+          <state></state>
+        </option>
+        <option>
+          <name>IlinkTreatAsErr</name>
+          <state></state>
+        </option>
+        <option>
+          <name>IlinkWarningsAreErrors</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>IlinkUseExtraOptions</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>IlinkExtraOptions</name>
+          <state></state>
+        </option>
+        <option>
+          <name>IlinkLowLevelInterfaceSlave</name>
+          <state>1</state>
+        </option>
+        <option>
+          <name>IlinkAutoLibEnable</name>
+          <state>1</state>
+        </option>
+        <option>
+          <name>IlinkAdditionalLibs</name>
+          <state></state>
+        </option>
+        <option>
+          <name>IlinkOverrideProgramEntryLabel</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>IlinkProgramEntryLabelSelect</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>IlinkProgramEntryLabel</name>
+          <state>__iar_program_start</state>
+        </option>
+        <option>
+          <name>DoFill</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>FillerByte</name>
+          <state>0xFF</state>
+        </option>
+        <option>
+          <name>FillerStart</name>
+          <state>0x0</state>
+        </option>
+        <option>
+          <name>FillerEnd</name>
+          <state>0x0</state>
+        </option>
+        <option>
+          <name>CrcSize</name>
+          <version>0</version>
+          <state>1</state>
+        </option>
+        <option>
+          <name>CrcAlign</name>
+          <state>1</state>
+        </option>
+        <option>
+          <name>CrcPoly</name>
+          <state>0x11021</state>
+        </option>
+        <option>
+          <name>CrcCompl</name>
+          <version>0</version>
+          <state>0</state>
+        </option>
+        <option>
+          <name>CrcBitOrder</name>
+          <version>0</version>
+          <state>0</state>
+        </option>
+        <option>
+          <name>CrcInitialValue</name>
+          <state>0x0</state>
+        </option>
+        <option>
+          <name>DoCrc</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>IlinkBE8Slave</name>
+          <state>1</state>
+        </option>
+        <option>
+          <name>IlinkBufferedTerminalOutput</name>
+          <state>1</state>
+        </option>
+        <option>
+          <name>IlinkStdoutInterfaceSlave</name>
+          <state>1</state>
+        </option>
+        <option>
+          <name>CrcFullSize</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>IlinkIElfToolPostProcess</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>IlinkLogAutoLibSelect</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>IlinkLogRedirSymbols</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>IlinkLogUnusedFragments</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>IlinkCrcReverseByteOrder</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>IlinkCrcUseAsInput</name>
+          <state>1</state>
+        </option>
+        <option>
+          <name>IlinkOptInline</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>IlinkOptExceptionsAllow</name>
+          <state>1</state>
+        </option>
+        <option>
+          <name>IlinkOptExceptionsForce</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>IlinkCmsis</name>
+          <state>1</state>
+        </option>
+        <option>
+          <name>IlinkOptMergeDuplSections</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>IlinkOptUseVfe</name>
+          <state>1</state>
+        </option>
+        <option>
+          <name>IlinkOptForceVfe</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>IlinkStackAnalysisEnable</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>IlinkStackControlFile</name>
+          <state></state>
+        </option>
+        <option>
+          <name>IlinkStackCallGraphFile</name>
+          <state></state>
+        </option>
+        <option>
+          <name>CrcAlgorithm</name>
+          <version>0</version>
+          <state>1</state>
+        </option>
+        <option>
+          <name>CrcUnitSize</name>
+          <version>0</version>
+          <state>0</state>
+        </option>
+      </data>
+    </settings>
+    <settings>
+      <name>IARCHIVE</name>
+      <archiveVersion>0</archiveVersion>
+      <data>
+        <version>0</version>
+        <wantNonLocal>1</wantNonLocal>
+        <debug>1</debug>
+        <option>
+          <name>IarchiveInputs</name>
+          <state></state>
+        </option>
+        <option>
+          <name>IarchiveOverride</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>IarchiveOutput</name>
+          <state>###Unitialized###</state>
+        </option>
+      </data>
+    </settings>
+    <settings>
+      <name>BILINK</name>
+      <archiveVersion>0</archiveVersion>
+      <data/>
+    </settings>
+  </configuration>
+  <configuration>
+    <name>Board LPCXpresso1769</name>
+    <toolchain>
+      <name>ARM</name>
+    </toolchain>
+    <debug>1</debug>
+    <settings>
+      <name>General</name>
+      <archiveVersion>3</archiveVersion>
+      <data>
+        <version>21</version>
+        <wantNonLocal>1</wantNonLocal>
+        <debug>1</debug>
+        <option>
+          <name>ExePath</name>
+          <state>Board LPCXpresso1769\Exe</state>
+        </option>
+        <option>
+          <name>ObjPath</name>
+          <state>Board LPCXpresso1769\Obj</state>
+        </option>
+        <option>
+          <name>ListPath</name>
+          <state>Board LPCXpresso1769\List</state>
+        </option>
+        <option>
+          <name>Variant</name>
+          <version>20</version>
+          <state>38</state>
+        </option>
+        <option>
+          <name>GEndianMode</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>Input variant</name>
+          <version>3</version>
+          <state>0</state>
+        </option>
+        <option>
+          <name>Input description</name>
+          <state>Automatic choice of formatter.</state>
+        </option>
+        <option>
+          <name>Output variant</name>
+          <version>2</version>
+          <state>0</state>
+        </option>
+        <option>
+          <name>Output description</name>
+          <state>Automatic choice of formatter.</state>
+        </option>
+        <option>
+          <name>GOutputBinary</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>FPU</name>
+          <version>2</version>
+          <state>0</state>
+        </option>
+        <option>
+          <name>OGCoreOrChip</name>
+          <state>1</state>
+        </option>
+        <option>
+          <name>GRuntimeLibSelect</name>
+          <version>0</version>
+          <state>1</state>
+        </option>
+        <option>
+          <name>GRuntimeLibSelectSlave</name>
+          <version>0</version>
+          <state>1</state>
+        </option>
+        <option>
+          <name>RTDescription</name>
+          <state>Use the normal configuration of the C/C++ runtime library. No locale interface, C locale, no file descriptor support, no multibytes in printf and scanf, and no hex floats in strtod.</state>
+        </option>
+        <option>
+          <name>OGProductVersion</name>
+          <state>6.50.5.4846</state>
+        </option>
+        <option>
+          <name>OGLastSavedByProductVersion</name>
+          <state>6.50.5.4846</state>
+        </option>
+        <option>
+          <name>GeneralEnableMisra</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>GeneralMisraVerbose</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>OGChipSelectEditMenu</name>
+          <state>LPC1769	NXP LPC1769</state>
+        </option>
+        <option>
+          <name>GenLowLevelInterface</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>GEndianModeBE</name>
+          <state>1</state>
+        </option>
+        <option>
+          <name>OGBufferedTerminalOutput</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>GenStdoutInterface</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>GeneralMisraRules98</name>
+          <version>0</version>
+          <state>1000111110110101101110011100111111101110011011000101110111101101100111111111111100110011111001110111001111111111111111111111111</state>
+        </option>
+        <option>
+          <name>GeneralMisraVer</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>GeneralMisraRules04</name>
+          <version>0</version>
+          <state>111101010010111111111000110011111101111111111111110110010111101111010101111111111111111111111111101111111011110001111011111011111111111111111</state>
+        </option>
+        <option>
+          <name>RTConfigPath2</name>
+          <state>$TOOLKIT_DIR$\INC\c\DLib_Config_Normal.h</state>
+        </option>
+        <option>
+          <name>GFPUCoreSlave</name>
+          <version>20</version>
+          <state>38</state>
+        </option>
+        <option>
+          <name>GBECoreSlave</name>
+          <version>20</version>
+          <state>38</state>
+        </option>
+        <option>
+          <name>OGUseCmsis</name>
+          <state>1</state>
+        </option>
+        <option>
+          <name>OGUseCmsisDspLib</name>
+          <state>0</state>
+        </option>
+      </data>
+    </settings>
+    <settings>
+      <name>ICCARM</name>
+      <archiveVersion>2</archiveVersion>
+      <data>
+        <version>28</version>
+        <wantNonLocal>1</wantNonLocal>
+        <debug>1</debug>
+        <option>
+          <name>CCDefines</name>
+          <state>TUSB_CFG_MCU=MCU_LPC175X_6X</state>
+          <state>BOARD=BOARD_LPCXPRESSO1769</state>
+          <state>TUSB_CFG_OS=TUSB_OS_NONE</state>
+        </option>
+        <option>
+          <name>CCPreprocFile</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>CCPreprocComments</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>CCPreprocLine</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>CCListCFile</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>CCListCMnemonics</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>CCListCMessages</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>CCListAssFile</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>CCListAssSource</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>CCEnableRemarks</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>CCDiagSuppress</name>
+          <state></state>
+        </option>
+        <option>
+          <name>CCDiagRemark</name>
+          <state></state>
+        </option>
+        <option>
+          <name>CCDiagWarning</name>
+          <state></state>
+        </option>
+        <option>
+          <name>CCDiagError</name>
+          <state></state>
+        </option>
+        <option>
+          <name>CCObjPrefix</name>
+          <state>1</state>
+        </option>
+        <option>
+          <name>CCAllowList</name>
+          <version>1</version>
+          <state>0000000</state>
+        </option>
+        <option>
+          <name>CCDebugInfo</name>
+          <state>1</state>
+        </option>
+        <option>
+          <name>IEndianMode</name>
+          <state>1</state>
+        </option>
+        <option>
+          <name>IProcessor</name>
+          <state>1</state>
+        </option>
+        <option>
+          <name>IExtraOptionsCheck</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>IExtraOptions</name>
+          <state></state>
+        </option>
+        <option>
+          <name>CCLangConformance</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>CCSignedPlainChar</name>
+          <state>1</state>
+        </option>
+        <option>
+          <name>CCRequirePrototypes</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>CCMultibyteSupport</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>CCDiagWarnAreErr</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>CCCompilerRuntimeInfo</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>IFpuProcessor</name>
+          <state>1</state>
+        </option>
+        <option>
+          <name>OutputFile</name>
+          <state>$FILE_BNAME$.o</state>
+        </option>
+        <option>
+          <name>CCLibConfigHeader</name>
+          <state>1</state>
+        </option>
+        <option>
+          <name>PreInclude</name>
+          <state></state>
+        </option>
+        <option>
+          <name>CompilerMisraOverride</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>CCIncludePath2</name>
+          <state>$PROJ_DIR$\..\src</state>
+          <state>$PROJ_DIR$\..\..\bsp\lpc175x_6x\CMSISv2p00_LPC17xx\inc</state>
+          <state>$PROJ_DIR$\..\..\bsp\lpc175x_6x\LPC17xx_DriverLib\include</state>
+          <state>$PROJ_DIR$\..\..\bsp</state>
+          <state>$PROJ_DIR$\..\..\..\tinyusb</state>
+        </option>
+        <option>
+          <name>CCStdIncCheck</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>CCCodeSection</name>
+          <state>.text</state>
+        </option>
+        <option>
+          <name>IInterwork2</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>IProcessorMode2</name>
+          <state>1</state>
+        </option>
+        <option>
+          <name>CCOptLevel</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>CCOptStrategy</name>
+          <version>0</version>
+          <state>0</state>
+        </option>
+        <option>
+          <name>CCOptLevelSlave</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>CompilerMisraRules98</name>
+          <version>0</version>
+          <state>1000111110110101101110011100111111101110011011000101110111101101100111111111111100110011111001110111001111111111111111111111111</state>
+        </option>
+        <option>
+          <name>CompilerMisraRules04</name>
+          <version>0</version>
+          <state>111101110010111111111000110111111111111111111111111110010111101111010101111111111111111111111111101111111011111001111011111011111111111111111</state>
+        </option>
+        <option>
+          <name>CCPosIndRopi</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>CCPosIndRwpi</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>CCPosIndNoDynInit</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>IccLang</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>IccCDialect</name>
+          <state>1</state>
+        </option>
+        <option>
+          <name>IccAllowVLA</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>IccCppDialect</name>
+          <state>1</state>
+        </option>
+        <option>
+          <name>IccExceptions</name>
+          <state>1</state>
+        </option>
+        <option>
+          <name>IccRTTI</name>
+          <state>1</state>
+        </option>
+        <option>
+          <name>IccStaticDestr</name>
+          <state>1</state>
+        </option>
+        <option>
+          <name>IccCppInlineSemantics</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>IccCmsis</name>
+          <state>1</state>
+        </option>
+        <option>
+          <name>IccFloatSemantics</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>CCOptimizationNoSizeConstraints</name>
+          <state>0</state>
+        </option>
+      </data>
+    </settings>
+    <settings>
+      <name>AARM</name>
+      <archiveVersion>2</archiveVersion>
+      <data>
+        <version>8</version>
+        <wantNonLocal>1</wantNonLocal>
+        <debug>1</debug>
+        <option>
+          <name>AObjPrefix</name>
+          <state>1</state>
+        </option>
+        <option>
+          <name>AEndian</name>
+          <state>1</state>
+        </option>
+        <option>
+          <name>ACaseSensitivity</name>
+          <state>1</state>
+        </option>
+        <option>
+          <name>MacroChars</name>
+          <version>0</version>
+          <state>0</state>
+        </option>
+        <option>
+          <name>AWarnEnable</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>AWarnWhat</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>AWarnOne</name>
+          <state></state>
+        </option>
+        <option>
+          <name>AWarnRange1</name>
+          <state></state>
+        </option>
+        <option>
+          <name>AWarnRange2</name>
+          <state></state>
+        </option>
+        <option>
+          <name>ADebug</name>
+          <state>1</state>
+        </option>
+        <option>
+          <name>AltRegisterNames</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>ADefines</name>
+          <state></state>
+        </option>
+        <option>
+          <name>AList</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>AListHeader</name>
+          <state>1</state>
+        </option>
+        <option>
+          <name>AListing</name>
+          <state>1</state>
+        </option>
+        <option>
+          <name>Includes</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>MacDefs</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>MacExps</name>
+          <state>1</state>
+        </option>
+        <option>
+          <name>MacExec</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>OnlyAssed</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>MultiLine</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>PageLengthCheck</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>PageLength</name>
+          <state>80</state>
+        </option>
+        <option>
+          <name>TabSpacing</name>
+          <state>8</state>
+        </option>
+        <option>
+          <name>AXRef</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>AXRefDefines</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>AXRefInternal</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>AXRefDual</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>AProcessor</name>
+          <state>1</state>
+        </option>
+        <option>
+          <name>AFpuProcessor</name>
+          <state>1</state>
+        </option>
+        <option>
+          <name>AOutputFile</name>
+          <state>$FILE_BNAME$.o</state>
+        </option>
+        <option>
+          <name>AMultibyteSupport</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>ALimitErrorsCheck</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>ALimitErrorsEdit</name>
+          <state>100</state>
+        </option>
+        <option>
+          <name>AIgnoreStdInclude</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>AUserIncludes</name>
+          <state></state>
+        </option>
+        <option>
+          <name>AExtraOptionsCheckV2</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>AExtraOptionsV2</name>
+          <state></state>
+        </option>
+      </data>
+    </settings>
+    <settings>
+      <name>OBJCOPY</name>
+      <archiveVersion>0</archiveVersion>
+      <data>
+        <version>1</version>
+        <wantNonLocal>1</wantNonLocal>
+        <debug>1</debug>
+        <option>
+          <name>OOCOutputFormat</name>
+          <version>2</version>
+          <state>0</state>
+        </option>
+        <option>
+          <name>OCOutputOverride</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>OOCOutputFile</name>
+          <state>device_os_none.srec</state>
+        </option>
+        <option>
+          <name>OOCCommandLineProducer</name>
+          <state>1</state>
+        </option>
+        <option>
+          <name>OOCObjCopyEnable</name>
+          <state>0</state>
+        </option>
+      </data>
+    </settings>
+    <settings>
+      <name>CUSTOM</name>
+      <archiveVersion>3</archiveVersion>
+      <data>
+        <extensions></extensions>
+        <cmdline></cmdline>
+      </data>
+    </settings>
+    <settings>
+      <name>BICOMP</name>
+      <archiveVersion>0</archiveVersion>
+      <data/>
+    </settings>
+    <settings>
+      <name>BUILDACTION</name>
+      <archiveVersion>1</archiveVersion>
+      <data>
+        <prebuild></prebuild>
+        <postbuild></postbuild>
+      </data>
+    </settings>
+    <settings>
+      <name>ILINK</name>
+      <archiveVersion>0</archiveVersion>
+      <data>
+        <version>15</version>
+        <wantNonLocal>1</wantNonLocal>
+        <debug>1</debug>
+        <option>
+          <name>IlinkLibIOConfig</name>
+          <state>1</state>
+        </option>
+        <option>
+          <name>XLinkMisraHandler</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>IlinkInputFileSlave</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>IlinkOutputFile</name>
+          <state>device_os_none.out</state>
+        </option>
+        <option>
+          <name>IlinkDebugInfoEnable</name>
+          <state>1</state>
+        </option>
+        <option>
+          <name>IlinkKeepSymbols</name>
+          <state></state>
+        </option>
+        <option>
+          <name>IlinkRawBinaryFile</name>
+          <state></state>
+        </option>
+        <option>
+          <name>IlinkRawBinarySymbol</name>
+          <state></state>
+        </option>
+        <option>
+          <name>IlinkRawBinarySegment</name>
+          <state></state>
+        </option>
+        <option>
+          <name>IlinkRawBinaryAlign</name>
+          <state></state>
+        </option>
+        <option>
+          <name>IlinkDefines</name>
+          <state></state>
+        </option>
+        <option>
+          <name>IlinkConfigDefines</name>
+          <state></state>
+        </option>
+        <option>
+          <name>IlinkMapFile</name>
+          <state>1</state>
+        </option>
+        <option>
+          <name>IlinkLogFile</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>IlinkLogInitialization</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>IlinkLogModule</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>IlinkLogSection</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>IlinkLogVeneer</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>IlinkIcfOverride</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>IlinkIcfFile</name>
+          <state>$TOOLKIT_DIR$\config\linker\NXP\LPC1769.icf</state>
+        </option>
+        <option>
+          <name>IlinkIcfFileSlave</name>
+          <state></state>
+        </option>
+        <option>
+          <name>IlinkEnableRemarks</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>IlinkSuppressDiags</name>
+          <state></state>
+        </option>
+        <option>
+          <name>IlinkTreatAsRem</name>
+          <state></state>
+        </option>
+        <option>
+          <name>IlinkTreatAsWarn</name>
+          <state></state>
+        </option>
+        <option>
+          <name>IlinkTreatAsErr</name>
+          <state></state>
+        </option>
+        <option>
+          <name>IlinkWarningsAreErrors</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>IlinkUseExtraOptions</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>IlinkExtraOptions</name>
+          <state></state>
+        </option>
+        <option>
+          <name>IlinkLowLevelInterfaceSlave</name>
+          <state>1</state>
+        </option>
+        <option>
+          <name>IlinkAutoLibEnable</name>
+          <state>1</state>
+        </option>
+        <option>
+          <name>IlinkAdditionalLibs</name>
+          <state></state>
+        </option>
+        <option>
+          <name>IlinkOverrideProgramEntryLabel</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>IlinkProgramEntryLabelSelect</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>IlinkProgramEntryLabel</name>
+          <state>__iar_program_start</state>
+        </option>
+        <option>
+          <name>DoFill</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>FillerByte</name>
+          <state>0xFF</state>
+        </option>
+        <option>
+          <name>FillerStart</name>
+          <state>0x0</state>
+        </option>
+        <option>
+          <name>FillerEnd</name>
+          <state>0x0</state>
+        </option>
+        <option>
+          <name>CrcSize</name>
+          <version>0</version>
+          <state>1</state>
+        </option>
+        <option>
+          <name>CrcAlign</name>
+          <state>1</state>
+        </option>
+        <option>
+          <name>CrcPoly</name>
+          <state>0x11021</state>
+        </option>
+        <option>
+          <name>CrcCompl</name>
+          <version>0</version>
+          <state>0</state>
+        </option>
+        <option>
+          <name>CrcBitOrder</name>
+          <version>0</version>
+          <state>0</state>
+        </option>
+        <option>
+          <name>CrcInitialValue</name>
+          <state>0x0</state>
+        </option>
+        <option>
+          <name>DoCrc</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>IlinkBE8Slave</name>
+          <state>1</state>
+        </option>
+        <option>
+          <name>IlinkBufferedTerminalOutput</name>
+          <state>1</state>
+        </option>
+        <option>
+          <name>IlinkStdoutInterfaceSlave</name>
+          <state>1</state>
+        </option>
+        <option>
+          <name>CrcFullSize</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>IlinkIElfToolPostProcess</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>IlinkLogAutoLibSelect</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>IlinkLogRedirSymbols</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>IlinkLogUnusedFragments</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>IlinkCrcReverseByteOrder</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>IlinkCrcUseAsInput</name>
+          <state>1</state>
+        </option>
+        <option>
+          <name>IlinkOptInline</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>IlinkOptExceptionsAllow</name>
+          <state>1</state>
+        </option>
+        <option>
+          <name>IlinkOptExceptionsForce</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>IlinkCmsis</name>
+          <state>1</state>
+        </option>
+        <option>
+          <name>IlinkOptMergeDuplSections</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>IlinkOptUseVfe</name>
+          <state>1</state>
+        </option>
+        <option>
+          <name>IlinkOptForceVfe</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>IlinkStackAnalysisEnable</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>IlinkStackControlFile</name>
+          <state></state>
+        </option>
+        <option>
+          <name>IlinkStackCallGraphFile</name>
+          <state></state>
+        </option>
+        <option>
+          <name>CrcAlgorithm</name>
+          <version>0</version>
+          <state>1</state>
+        </option>
+        <option>
+          <name>CrcUnitSize</name>
+          <version>0</version>
+          <state>0</state>
+        </option>
+      </data>
+    </settings>
+    <settings>
+      <name>IARCHIVE</name>
+      <archiveVersion>0</archiveVersion>
+      <data>
+        <version>0</version>
+        <wantNonLocal>1</wantNonLocal>
+        <debug>1</debug>
+        <option>
+          <name>IarchiveInputs</name>
+          <state></state>
+        </option>
+        <option>
+          <name>IarchiveOverride</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>IarchiveOutput</name>
+          <state>###Unitialized###</state>
+        </option>
+      </data>
+    </settings>
+    <settings>
+      <name>BILINK</name>
+      <archiveVersion>0</archiveVersion>
+      <data/>
+    </settings>
+  </configuration>
+  <configuration>
+    <name>Board NGX4330</name>
+    <toolchain>
+      <name>ARM</name>
+    </toolchain>
+    <debug>1</debug>
+    <settings>
+      <name>General</name>
+      <archiveVersion>3</archiveVersion>
+      <data>
+        <version>21</version>
+        <wantNonLocal>1</wantNonLocal>
+        <debug>1</debug>
+        <option>
+          <name>ExePath</name>
+          <state>Board NGX4330\Exe</state>
+        </option>
+        <option>
+          <name>ObjPath</name>
+          <state>Board NGX4330\Obj</state>
+        </option>
+        <option>
+          <name>ListPath</name>
+          <state>Board NGX4330\List</state>
+        </option>
+        <option>
+          <name>Variant</name>
+          <version>20</version>
+          <state>39</state>
+        </option>
+        <option>
+          <name>GEndianMode</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>Input variant</name>
+          <version>3</version>
+          <state>0</state>
+        </option>
+        <option>
+          <name>Input description</name>
+          <state>Automatic choice of formatter.</state>
+        </option>
+        <option>
+          <name>Output variant</name>
+          <version>2</version>
+          <state>0</state>
+        </option>
+        <option>
+          <name>Output description</name>
+          <state>Automatic choice of formatter.</state>
+        </option>
+        <option>
+          <name>GOutputBinary</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>FPU</name>
+          <version>2</version>
+          <state>5</state>
+        </option>
+        <option>
+          <name>OGCoreOrChip</name>
+          <state>1</state>
+        </option>
+        <option>
+          <name>GRuntimeLibSelect</name>
+          <version>0</version>
+          <state>1</state>
+        </option>
+        <option>
+          <name>GRuntimeLibSelectSlave</name>
+          <version>0</version>
+          <state>1</state>
+        </option>
+        <option>
+          <name>RTDescription</name>
+          <state>Use the normal configuration of the C/C++ runtime library. No locale interface, C locale, no file descriptor support, no multibytes in printf and scanf, and no hex floats in strtod.</state>
+        </option>
+        <option>
+          <name>OGProductVersion</name>
+          <state>6.50.5.4846</state>
+        </option>
+        <option>
+          <name>OGLastSavedByProductVersion</name>
+          <state>6.50.5.4846</state>
+        </option>
+        <option>
+          <name>GeneralEnableMisra</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>GeneralMisraVerbose</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>OGChipSelectEditMenu</name>
+          <state>LPC4330_M4	NXP LPC4330_M4</state>
+        </option>
+        <option>
+          <name>GenLowLevelInterface</name>
+          <state>1</state>
+        </option>
+        <option>
+          <name>GEndianModeBE</name>
+          <state>1</state>
+        </option>
+        <option>
+          <name>OGBufferedTerminalOutput</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>GenStdoutInterface</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>GeneralMisraRules98</name>
+          <version>0</version>
+          <state>1000111110110101101110011100111111101110011011000101110111101101100111111111111100110011111001110111001111111111111111111111111</state>
+        </option>
+        <option>
+          <name>GeneralMisraVer</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>GeneralMisraRules04</name>
+          <version>0</version>
+          <state>111101010010111111111000110011111101111111111111110110010111101111010101111111111111111111111111101111111011110001111011111011111111111111111</state>
+        </option>
+        <option>
+          <name>RTConfigPath2</name>
+          <state>$TOOLKIT_DIR$\INC\c\DLib_Config_Normal.h</state>
+        </option>
+        <option>
+          <name>GFPUCoreSlave</name>
+          <version>20</version>
+          <state>39</state>
+        </option>
+        <option>
+          <name>GBECoreSlave</name>
+          <version>20</version>
+          <state>39</state>
+        </option>
+        <option>
+          <name>OGUseCmsis</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>OGUseCmsisDspLib</name>
+          <state>0</state>
+        </option>
+      </data>
+    </settings>
+    <settings>
+      <name>ICCARM</name>
+      <archiveVersion>2</archiveVersion>
+      <data>
+        <version>28</version>
+        <wantNonLocal>1</wantNonLocal>
+        <debug>1</debug>
+        <option>
+          <name>CCDefines</name>
+          <state>CORE_M4</state>
+          <state>TUSB_CFG_MCU=MCU_LPC43XX</state>
+          <state>BOARD=BOARD_NGX4330</state>
+          <state>TUSB_CFG_OS=TUSB_OS_NONE</state>
+        </option>
+        <option>
+          <name>CCPreprocFile</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>CCPreprocComments</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>CCPreprocLine</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>CCListCFile</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>CCListCMnemonics</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>CCListCMessages</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>CCListAssFile</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>CCListAssSource</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>CCEnableRemarks</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>CCDiagSuppress</name>
+          <state></state>
+        </option>
+        <option>
+          <name>CCDiagRemark</name>
+          <state></state>
+        </option>
+        <option>
+          <name>CCDiagWarning</name>
+          <state></state>
+        </option>
+        <option>
+          <name>CCDiagError</name>
+          <state></state>
+        </option>
+        <option>
+          <name>CCObjPrefix</name>
+          <state>1</state>
+        </option>
+        <option>
+          <name>CCAllowList</name>
+          <version>1</version>
+          <state>0000000</state>
+        </option>
+        <option>
+          <name>CCDebugInfo</name>
+          <state>1</state>
+        </option>
+        <option>
+          <name>IEndianMode</name>
+          <state>1</state>
+        </option>
+        <option>
+          <name>IProcessor</name>
+          <state>1</state>
+        </option>
+        <option>
+          <name>IExtraOptionsCheck</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>IExtraOptions</name>
+          <state></state>
+        </option>
+        <option>
+          <name>CCLangConformance</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>CCSignedPlainChar</name>
+          <state>1</state>
+        </option>
+        <option>
+          <name>CCRequirePrototypes</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>CCMultibyteSupport</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>CCDiagWarnAreErr</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>CCCompilerRuntimeInfo</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>IFpuProcessor</name>
+          <state>1</state>
+        </option>
+        <option>
+          <name>OutputFile</name>
+          <state>$FILE_BNAME$.o</state>
+        </option>
+        <option>
+          <name>CCLibConfigHeader</name>
+          <state>1</state>
+        </option>
+        <option>
+          <name>PreInclude</name>
+          <state></state>
+        </option>
+        <option>
+          <name>CompilerMisraOverride</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>CCIncludePath2</name>
+          <state>$PROJ_DIR$\..\src</state>
+          <state>$PROJ_DIR$\..\..\bsp\lpc43xx\CMSIS_LPC43xx_DriverLib\inc</state>
+          <state>$PROJ_DIR$\..\..\bsp</state>
+          <state>$PROJ_DIR$\..\..\..\tinyusb</state>
+        </option>
+        <option>
+          <name>CCStdIncCheck</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>CCCodeSection</name>
+          <state>.text</state>
+        </option>
+        <option>
+          <name>IInterwork2</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>IProcessorMode2</name>
+          <state>1</state>
+        </option>
+        <option>
+          <name>CCOptLevel</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>CCOptStrategy</name>
+          <version>0</version>
+          <state>0</state>
+        </option>
+        <option>
+          <name>CCOptLevelSlave</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>CompilerMisraRules98</name>
+          <version>0</version>
+          <state>1000111110110101101110011100111111101110011011000101110111101101100111111111111100110011111001110111001111111111111111111111111</state>
+        </option>
+        <option>
+          <name>CompilerMisraRules04</name>
+          <version>0</version>
+          <state>111101110010111111111000110111111111111111111111111110010111101111010101111111111111111111111111101111111011111001111011111011111111111111111</state>
+        </option>
+        <option>
+          <name>CCPosIndRopi</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>CCPosIndRwpi</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>CCPosIndNoDynInit</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>IccLang</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>IccCDialect</name>
+          <state>1</state>
+        </option>
+        <option>
+          <name>IccAllowVLA</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>IccCppDialect</name>
+          <state>1</state>
+        </option>
+        <option>
+          <name>IccExceptions</name>
+          <state>1</state>
+        </option>
+        <option>
+          <name>IccRTTI</name>
+          <state>1</state>
+        </option>
+        <option>
+          <name>IccStaticDestr</name>
+          <state>1</state>
+        </option>
+        <option>
+          <name>IccCppInlineSemantics</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>IccCmsis</name>
+          <state>1</state>
+        </option>
+        <option>
+          <name>IccFloatSemantics</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>CCOptimizationNoSizeConstraints</name>
+          <state>0</state>
+        </option>
+      </data>
+    </settings>
+    <settings>
+      <name>AARM</name>
+      <archiveVersion>2</archiveVersion>
+      <data>
+        <version>8</version>
+        <wantNonLocal>1</wantNonLocal>
+        <debug>1</debug>
+        <option>
+          <name>AObjPrefix</name>
+          <state>1</state>
+        </option>
+        <option>
+          <name>AEndian</name>
+          <state>1</state>
+        </option>
+        <option>
+          <name>ACaseSensitivity</name>
+          <state>1</state>
+        </option>
+        <option>
+          <name>MacroChars</name>
+          <version>0</version>
+          <state>0</state>
+        </option>
+        <option>
+          <name>AWarnEnable</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>AWarnWhat</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>AWarnOne</name>
+          <state></state>
+        </option>
+        <option>
+          <name>AWarnRange1</name>
+          <state></state>
+        </option>
+        <option>
+          <name>AWarnRange2</name>
+          <state></state>
+        </option>
+        <option>
+          <name>ADebug</name>
+          <state>1</state>
+        </option>
+        <option>
+          <name>AltRegisterNames</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>ADefines</name>
+          <state></state>
+        </option>
+        <option>
+          <name>AList</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>AListHeader</name>
+          <state>1</state>
+        </option>
+        <option>
+          <name>AListing</name>
+          <state>1</state>
+        </option>
+        <option>
+          <name>Includes</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>MacDefs</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>MacExps</name>
+          <state>1</state>
+        </option>
+        <option>
+          <name>MacExec</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>OnlyAssed</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>MultiLine</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>PageLengthCheck</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>PageLength</name>
+          <state>80</state>
+        </option>
+        <option>
+          <name>TabSpacing</name>
+          <state>8</state>
+        </option>
+        <option>
+          <name>AXRef</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>AXRefDefines</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>AXRefInternal</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>AXRefDual</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>AProcessor</name>
+          <state>1</state>
+        </option>
+        <option>
+          <name>AFpuProcessor</name>
+          <state>1</state>
+        </option>
+        <option>
+          <name>AOutputFile</name>
+          <state>$FILE_BNAME$.o</state>
+        </option>
+        <option>
+          <name>AMultibyteSupport</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>ALimitErrorsCheck</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>ALimitErrorsEdit</name>
+          <state>100</state>
+        </option>
+        <option>
+          <name>AIgnoreStdInclude</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>AUserIncludes</name>
+          <state></state>
+        </option>
+        <option>
+          <name>AExtraOptionsCheckV2</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>AExtraOptionsV2</name>
+          <state></state>
+        </option>
+      </data>
+    </settings>
+    <settings>
+      <name>OBJCOPY</name>
+      <archiveVersion>0</archiveVersion>
+      <data>
+        <version>1</version>
+        <wantNonLocal>1</wantNonLocal>
+        <debug>1</debug>
+        <option>
+          <name>OOCOutputFormat</name>
+          <version>2</version>
+          <state>0</state>
+        </option>
+        <option>
+          <name>OCOutputOverride</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>OOCOutputFile</name>
+          <state>device_os_none.srec</state>
+        </option>
+        <option>
+          <name>OOCCommandLineProducer</name>
+          <state>1</state>
+        </option>
+        <option>
+          <name>OOCObjCopyEnable</name>
+          <state>0</state>
+        </option>
+      </data>
+    </settings>
+    <settings>
+      <name>CUSTOM</name>
+      <archiveVersion>3</archiveVersion>
+      <data>
+        <extensions></extensions>
+        <cmdline></cmdline>
+      </data>
+    </settings>
+    <settings>
+      <name>BICOMP</name>
+      <archiveVersion>0</archiveVersion>
+      <data/>
+    </settings>
+    <settings>
+      <name>BUILDACTION</name>
+      <archiveVersion>1</archiveVersion>
+      <data>
+        <prebuild></prebuild>
+        <postbuild></postbuild>
+      </data>
+    </settings>
+    <settings>
+      <name>ILINK</name>
+      <archiveVersion>0</archiveVersion>
+      <data>
+        <version>15</version>
+        <wantNonLocal>1</wantNonLocal>
+        <debug>1</debug>
+        <option>
+          <name>IlinkLibIOConfig</name>
+          <state>1</state>
+        </option>
+        <option>
+          <name>XLinkMisraHandler</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>IlinkInputFileSlave</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>IlinkOutputFile</name>
+          <state>device_os_none.out</state>
+        </option>
+        <option>
+          <name>IlinkDebugInfoEnable</name>
+          <state>1</state>
+        </option>
+        <option>
+          <name>IlinkKeepSymbols</name>
+          <state></state>
+        </option>
+        <option>
+          <name>IlinkRawBinaryFile</name>
+          <state></state>
+        </option>
+        <option>
+          <name>IlinkRawBinarySymbol</name>
+          <state></state>
+        </option>
+        <option>
+          <name>IlinkRawBinarySegment</name>
+          <state></state>
+        </option>
+        <option>
+          <name>IlinkRawBinaryAlign</name>
+          <state></state>
+        </option>
+        <option>
+          <name>IlinkDefines</name>
+          <state></state>
+        </option>
+        <option>
+          <name>IlinkConfigDefines</name>
+          <state></state>
+        </option>
+        <option>
+          <name>IlinkMapFile</name>
+          <state>1</state>
+        </option>
+        <option>
+          <name>IlinkLogFile</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>IlinkLogInitialization</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>IlinkLogModule</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>IlinkLogSection</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>IlinkLogVeneer</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>IlinkIcfOverride</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>IlinkIcfFile</name>
+          <state>$TOOLKIT_DIR$\config\linker\NXP\lpc4330_m4.icf</state>
+        </option>
+        <option>
+          <name>IlinkIcfFileSlave</name>
+          <state></state>
+        </option>
+        <option>
+          <name>IlinkEnableRemarks</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>IlinkSuppressDiags</name>
+          <state></state>
+        </option>
+        <option>
+          <name>IlinkTreatAsRem</name>
+          <state></state>
+        </option>
+        <option>
+          <name>IlinkTreatAsWarn</name>
+          <state></state>
+        </option>
+        <option>
+          <name>IlinkTreatAsErr</name>
+          <state></state>
+        </option>
+        <option>
+          <name>IlinkWarningsAreErrors</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>IlinkUseExtraOptions</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>IlinkExtraOptions</name>
+          <state></state>
+        </option>
+        <option>
+          <name>IlinkLowLevelInterfaceSlave</name>
+          <state>1</state>
+        </option>
+        <option>
+          <name>IlinkAutoLibEnable</name>
+          <state>1</state>
+        </option>
+        <option>
+          <name>IlinkAdditionalLibs</name>
+          <state></state>
+        </option>
+        <option>
+          <name>IlinkOverrideProgramEntryLabel</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>IlinkProgramEntryLabelSelect</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>IlinkProgramEntryLabel</name>
+          <state>__iar_program_start</state>
+        </option>
+        <option>
+          <name>DoFill</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>FillerByte</name>
+          <state>0xFF</state>
+        </option>
+        <option>
+          <name>FillerStart</name>
+          <state>0x0</state>
+        </option>
+        <option>
+          <name>FillerEnd</name>
+          <state>0x0</state>
+        </option>
+        <option>
+          <name>CrcSize</name>
+          <version>0</version>
+          <state>1</state>
+        </option>
+        <option>
+          <name>CrcAlign</name>
+          <state>1</state>
+        </option>
+        <option>
+          <name>CrcPoly</name>
+          <state>0x11021</state>
+        </option>
+        <option>
+          <name>CrcCompl</name>
+          <version>0</version>
+          <state>0</state>
+        </option>
+        <option>
+          <name>CrcBitOrder</name>
+          <version>0</version>
+          <state>0</state>
+        </option>
+        <option>
+          <name>CrcInitialValue</name>
+          <state>0x0</state>
+        </option>
+        <option>
+          <name>DoCrc</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>IlinkBE8Slave</name>
+          <state>1</state>
+        </option>
+        <option>
+          <name>IlinkBufferedTerminalOutput</name>
+          <state>1</state>
+        </option>
+        <option>
+          <name>IlinkStdoutInterfaceSlave</name>
+          <state>1</state>
+        </option>
+        <option>
+          <name>CrcFullSize</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>IlinkIElfToolPostProcess</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>IlinkLogAutoLibSelect</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>IlinkLogRedirSymbols</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>IlinkLogUnusedFragments</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>IlinkCrcReverseByteOrder</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>IlinkCrcUseAsInput</name>
+          <state>1</state>
+        </option>
+        <option>
+          <name>IlinkOptInline</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>IlinkOptExceptionsAllow</name>
+          <state>1</state>
+        </option>
+        <option>
+          <name>IlinkOptExceptionsForce</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>IlinkCmsis</name>
+          <state>1</state>
+        </option>
+        <option>
+          <name>IlinkOptMergeDuplSections</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>IlinkOptUseVfe</name>
+          <state>1</state>
+        </option>
+        <option>
+          <name>IlinkOptForceVfe</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>IlinkStackAnalysisEnable</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>IlinkStackControlFile</name>
+          <state></state>
+        </option>
+        <option>
+          <name>IlinkStackCallGraphFile</name>
+          <state></state>
+        </option>
+        <option>
+          <name>CrcAlgorithm</name>
+          <version>0</version>
+          <state>1</state>
+        </option>
+        <option>
+          <name>CrcUnitSize</name>
+          <version>0</version>
+          <state>0</state>
+        </option>
+      </data>
+    </settings>
+    <settings>
+      <name>IARCHIVE</name>
+      <archiveVersion>0</archiveVersion>
+      <data>
+        <version>0</version>
+        <wantNonLocal>1</wantNonLocal>
+        <debug>1</debug>
+        <option>
+          <name>IarchiveInputs</name>
+          <state></state>
+        </option>
+        <option>
+          <name>IarchiveOverride</name>
+          <state>0</state>
+        </option>
+        <option>
+          <name>IarchiveOutput</name>
+          <state>###Unitialized###</state>
+        </option>
+      </data>
+    </settings>
+    <settings>
+      <name>BILINK</name>
+      <archiveVersion>0</archiveVersion>
+      <data/>
+    </settings>
+  </configuration>
+  <group>
+    <name>app</name>
+    <file>
+      <name>$PROJ_DIR$\..\src\cdcd_app.c</name>
+    </file>
+    <file>
+      <name>$PROJ_DIR$\..\src\keyboardd_app.c</name>
+    </file>
+    <file>
+      <name>$PROJ_DIR$\..\src\main.c</name>
+    </file>
+    <file>
+      <name>$PROJ_DIR$\..\src\moused_app.c</name>
+    </file>
+    <file>
+      <name>$PROJ_DIR$\..\src\mscd_app.c</name>
+    </file>
+    <file>
+      <name>$PROJ_DIR$\..\src\mscd_app_ramdisk.c</name>
+    </file>
+    <file>
+      <name>$PROJ_DIR$\..\src\mscd_app_romdisk.c</name>
+    </file>
+    <file>
+      <name>$PROJ_DIR$\..\src\tusb_descriptors.c</name>
+    </file>
+  </group>
+  <group>
+    <name>bsp</name>
+    <group>
+      <name>boards</name>
+      <file>
+        <name>$PROJ_DIR$\..\..\bsp\boards\board.c</name>
+      </file>
+      <file>
+        <name>$PROJ_DIR$\..\..\bsp\boards\embedded_artists\ea4357\board_ea4357.c</name>
+      </file>
+      <file>
+        <name>$PROJ_DIR$\..\..\bsp\boards\microbuilder\board_lpc4357usb.c</name>
+      </file>
+      <file>
+        <name>$PROJ_DIR$\..\..\bsp\boards\lpcxpresso\board_lpcxpresso1769.c</name>
+      </file>
+      <file>
+        <name>$PROJ_DIR$\..\..\bsp\boards\ngx\board_ngx4330.c</name>
+      </file>
+      <file>
+        <name>$PROJ_DIR$\..\..\bsp\boards\embedded_artists\oem_base_board\pca9532.c</name>
+      </file>
+      <file>
+        <name>$PROJ_DIR$\..\..\bsp\boards\printf_retarget.c</name>
+      </file>
+    </group>
+    <group>
+      <name>lpc175x_6x</name>
+      <excluded>
+        <configuration>Board EA4357</configuration>
+        <configuration>Board NGX4330</configuration>
+      </excluded>
+      <file>
+        <name>$PROJ_DIR$\..\..\bsp\lpc175x_6x\CMSISv2p00_LPC17xx\src\core_cm3.c</name>
+      </file>
+      <file>
+        <name>$PROJ_DIR$\..\..\bsp\lpc175x_6x\LPC17xx_DriverLib\source\lpc17xx_clkpwr.c</name>
+      </file>
+      <file>
+        <name>$PROJ_DIR$\..\..\bsp\lpc175x_6x\LPC17xx_DriverLib\source\lpc17xx_gpio.c</name>
+      </file>
+      <file>
+        <name>$PROJ_DIR$\..\..\bsp\lpc175x_6x\LPC17xx_DriverLib\source\lpc17xx_pinsel.c</name>
+      </file>
+      <file>
+        <name>$PROJ_DIR$\..\..\bsp\lpc175x_6x\LPC17xx_DriverLib\source\lpc17xx_uart.c</name>
+      </file>
+      <file>
+        <name>$PROJ_DIR$\..\..\bsp\lpc175x_6x\startup_iar\startup_LPC17xx.s</name>
+      </file>
+      <file>
+        <name>$PROJ_DIR$\..\..\bsp\lpc175x_6x\CMSISv2p00_LPC17xx\src\system_LPC17xx.c</name>
+      </file>
+    </group>
+    <group>
+      <name>lpc43xx</name>
+      <excluded>
+        <configuration>Board LPCXpresso1769</configuration>
+      </excluded>
+      <file>
+        <name>$PROJ_DIR$\..\..\bsp\lpc43xx\CMSIS_LPC43xx_DriverLib\src\lpc43xx_cgu.c</name>
+      </file>
+      <file>
+        <name>$PROJ_DIR$\..\..\bsp\lpc43xx\CMSIS_LPC43xx_DriverLib\src\lpc43xx_gpio.c</name>
+      </file>
+      <file>
+        <name>$PROJ_DIR$\..\..\bsp\lpc43xx\CMSIS_LPC43xx_DriverLib\src\lpc43xx_i2c.c</name>
+      </file>
+      <file>
+        <name>$PROJ_DIR$\..\..\bsp\lpc43xx\CMSIS_LPC43xx_DriverLib\src\lpc43xx_scu.c</name>
+      </file>
+      <file>
+        <name>$PROJ_DIR$\..\..\bsp\lpc43xx\CMSIS_LPC43xx_DriverLib\src\lpc43xx_uart.c</name>
+      </file>
+      <file>
+        <name>$PROJ_DIR$\..\..\bsp\lpc43xx\startup_iar\startup_LPC43xx.s</name>
+      </file>
+      <file>
+        <name>$PROJ_DIR$\..\..\bsp\lpc43xx\CMSIS_LPC43xx_DriverLib\src\system_LPC43xx.c</name>
+      </file>
+    </group>
+  </group>
+  <group>
+    <name>tinyusb</name>
+    <group>
+      <name>class</name>
+      <file>
+        <name>$PROJ_DIR$\..\..\..\tinyusb\class\cdc_device.c</name>
+      </file>
+      <file>
+        <name>$PROJ_DIR$\..\..\..\tinyusb\class\cdc_host.c</name>
+      </file>
+      <file>
+        <name>$PROJ_DIR$\..\..\..\tinyusb\class\hid_device.c</name>
+      </file>
+      <file>
+        <name>$PROJ_DIR$\..\..\..\tinyusb\class\hid_host.c</name>
+      </file>
+      <file>
+        <name>$PROJ_DIR$\..\..\..\tinyusb\class\msc_device.c</name>
+      </file>
+      <file>
+        <name>$PROJ_DIR$\..\..\..\tinyusb\class\msc_host.c</name>
+      </file>
+    </group>
+    <group>
+      <name>common</name>
+      <file>
+        <name>$PROJ_DIR$\..\..\..\tinyusb\common\errors.c</name>
+      </file>
+      <file>
+        <name>$PROJ_DIR$\..\..\..\tinyusb\common\fifo.c</name>
+      </file>
+    </group>
+    <group>
+      <name>device</name>
+      <file>
+        <name>$PROJ_DIR$\..\..\..\tinyusb\device\dcd.c</name>
+      </file>
+      <file>
+        <name>$PROJ_DIR$\..\..\..\tinyusb\device\dcd_lpc175x_6x.c</name>
+      </file>
+      <file>
+        <name>$PROJ_DIR$\..\..\..\tinyusb\device\dcd_lpc43xx.c</name>
+      </file>
+      <file>
+        <name>$PROJ_DIR$\..\..\..\tinyusb\device\dcd_lpc_11uxx_13uxx.c</name>
+      </file>
+      <file>
+        <name>$PROJ_DIR$\..\..\..\tinyusb\device\usbd.c</name>
+      </file>
+    </group>
+    <group>
+      <name>hal</name>
+      <file>
+        <name>$PROJ_DIR$\..\..\..\tinyusb\hal\hal_lpc11uxx.c</name>
+      </file>
+      <file>
+        <name>$PROJ_DIR$\..\..\..\tinyusb\hal\hal_lpc13uxx.c</name>
+      </file>
+      <file>
+        <name>$PROJ_DIR$\..\..\..\tinyusb\hal\hal_lpc175x_6x.c</name>
+      </file>
+      <file>
+        <name>$PROJ_DIR$\..\..\..\tinyusb\hal\hal_lpc43xx.c</name>
+      </file>
+    </group>
+    <group>
+      <name>host</name>
+      <file>
+        <name>$PROJ_DIR$\..\..\..\tinyusb\host\ehci\ehci.c</name>
+      </file>
+      <file>
+        <name>$PROJ_DIR$\..\..\..\tinyusb\host\hcd.c</name>
+      </file>
+      <file>
+        <name>$PROJ_DIR$\..\..\..\tinyusb\host\hub.c</name>
+      </file>
+      <file>
+        <name>$PROJ_DIR$\..\..\..\tinyusb\host\ohci\ohci.c</name>
+      </file>
+      <file>
+        <name>$PROJ_DIR$\..\..\..\tinyusb\host\usbh.c</name>
+      </file>
+    </group>
+    <group>
+      <name>osal</name>
+      <file>
+        <name>$PROJ_DIR$\..\..\..\tinyusb\osal\osal_none.c</name>
+      </file>
+    </group>
+    <file>
+      <name>$PROJ_DIR$\..\..\..\tinyusb\tusb.c</name>
+    </file>
+  </group>
+</project>
+
+

+ 10 - 0
demos/device/device_os_none/device_os_none.eww

@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="iso-8859-1"?>
+
+<workspace>
+  <project>
+    <path>$WS_DIR$\device_os_none.ewp</path>
+  </project>
+  <batchBuild/>
+</workspace>
+
+

+ 18 - 21
demos/device/src/tusb_descriptors.c

@@ -396,43 +396,40 @@ app_descriptor_configuration_t app_tusb_desc_configuration =
 // STRING DESCRIPTORS
 //--------------------------------------------------------------------+
 #define STRING_LEN_UNICODE(n) (2 + (2*(n))) // also includes 2 byte header
+#define ENDIAN_BE16_FROM( high, low) ENDIAN_BE16(high << 8 | low)
 
 ATTR_USB_MIN_ALIGNMENT TUSB_CFG_ATTR_USBRAM
-tusb_descriptor_string_t desc_str_language =
+uint16_t desc_str_language[] =
 {
-    .bLength         = STRING_LEN_UNICODE(1),
-    .bDescriptorType = TUSB_DESC_TYPE_STRING,
-    .unicode_string  = { 0x0409 }
+    ENDIAN_BE16_FROM( STRING_LEN_UNICODE(1), TUSB_DESC_TYPE_STRING ),
+    0x0409
 };
 
 ATTR_USB_MIN_ALIGNMENT TUSB_CFG_ATTR_USBRAM
-tusb_descriptor_string_t desc_str_manufacturer =
+uint16_t desc_str_manufacturer[] =
 {
-    .bLength         = STRING_LEN_UNICODE(11),
-    .bDescriptorType = TUSB_DESC_TYPE_STRING,
-    .unicode_string  = { 't', 'i', 'n', 'y', 'u', 's', 'b', '.', 'o', 'r', 'g' } // len = 11
+    ENDIAN_BE16_FROM( STRING_LEN_UNICODE(11), TUSB_DESC_TYPE_STRING),
+    't', 'i', 'n', 'y', 'u', 's', 'b', '.', 'o', 'r', 'g' // len = 11
 };
 
 ATTR_USB_MIN_ALIGNMENT TUSB_CFG_ATTR_USBRAM
-tusb_descriptor_string_t desc_str_product =
+uint16_t desc_str_product[] =
 {
-    .bLength         = STRING_LEN_UNICODE(14),
-    .bDescriptorType = TUSB_DESC_TYPE_STRING,
-    .unicode_string  = { 't', 'i', 'n', 'y', 'u', 's', 'b', ' ', 'D', 'e', 'v', 'i', 'c', 'e' } // len = 14
+    ENDIAN_BE16_FROM( STRING_LEN_UNICODE(14), TUSB_DESC_TYPE_STRING),
+    't', 'i', 'n', 'y', 'u', 's', 'b', ' ', 'D', 'e', 'v', 'i', 'c', 'e' // len = 14
 };
 
 ATTR_USB_MIN_ALIGNMENT TUSB_CFG_ATTR_USBRAM
-tusb_descriptor_string_t desc_str_serial =
+uint16_t desc_str_serial[] =
 {
-    .bLength         = STRING_LEN_UNICODE(4),
-    .bDescriptorType = TUSB_DESC_TYPE_STRING,
-    .unicode_string  = { '1', '2', '3', '4' } // len = 4
+    ENDIAN_BE16_FROM( STRING_LEN_UNICODE(4), TUSB_DESC_TYPE_STRING),
+    '1', '2', '3', '4' // len = 4
 };
 
-tusb_descriptor_string_t * const desc_str_table [TUSB_CFG_DEVICE_STRING_DESCRIPTOR_COUNT] =
+uint8_t* const desc_str_table [TUSB_CFG_DEVICE_STRING_DESCRIPTOR_COUNT] =
 {
-    &desc_str_language,
-    &desc_str_manufacturer,
-    &desc_str_product,
-    &desc_str_serial
+    (uint8_t*) desc_str_language,
+    (uint8_t*) desc_str_manufacturer,
+    (uint8_t*) desc_str_product,
+    (uint8_t*) desc_str_serial
 };

+ 1 - 1
demos/device/src/tusb_descriptors.h

@@ -179,7 +179,7 @@ typedef ATTR_PACKED_STRUCT(struct)
 //--------------------------------------------------------------------+
 // STRINGS DESCRIPTOR
 //--------------------------------------------------------------------+
-extern tusb_descriptor_string_t * const desc_str_table[TUSB_CFG_DEVICE_STRING_DESCRIPTOR_COUNT];
+extern uint8_t * const desc_str_table[TUSB_CFG_DEVICE_STRING_DESCRIPTOR_COUNT];
 
 //--------------------------------------------------------------------+
 // Export descriptors

+ 291 - 291
tinyusb/common/common.h

@@ -1,291 +1,291 @@
-/**************************************************************************/
-/*!
-    @file     common.h
-    @author   hathach (tinyusb.org)
-
-    @section LICENSE
-
-    Software License Agreement (BSD License)
-
-    Copyright (c) 2013, hathach (tinyusb.org)
-    All rights reserved.
-
-    Redistribution and use in source and binary forms, with or without
-    modification, are permitted provided that the following conditions are met:
-    1. Redistributions of source code must retain the above copyright
-    notice, this list of conditions and the following disclaimer.
-    2. Redistributions in binary form must reproduce the above copyright
-    notice, this list of conditions and the following disclaimer in the
-    documentation and/or other materials provided with the distribution.
-    3. Neither the name of the copyright holders nor the
-    names of its contributors may be used to endorse or promote products
-    derived from this software without specific prior written permission.
-
-    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
-    EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-    WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
-    DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
-    INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
-    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION HOWEVER CAUSED AND
-    ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-    INCLUDING NEGLIGENCE OR OTHERWISE ARISING IN ANY WAY OUT OF THE USE OF THIS
-    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-    This file is part of the tinyusb stack.
-*/
-/**************************************************************************/
-
-/** \defgroup Group_Common Common Files
- * @{
- *
- *  \defgroup Group_CommonH common.h
- *
- *  @{
- */
-
-#ifndef _TUSB_COMMON_H_
-#define _TUSB_COMMON_H_
-
-#ifdef __cplusplus
- extern "C" {
-#endif
-
-//--------------------------------------------------------------------+
-// MACROS
-//--------------------------------------------------------------------+
-#define STRING_(x)  #x                             // stringify without expand
-#define XSTRING_(x) STRING_(x)                     // expand then stringify
-#define STRING_CONCAT_(a, b) a##b                  // concat without expand
-#define XSTRING_CONCAT_(a, b) STRING_CONCAT_(a, b) // expand then concat
-
-//--------------------------------------------------------------------+
-// INCLUDES
-//--------------------------------------------------------------------+
-
-//------------- Standard Header -------------//
-#include "primitive_types.h"
-#include <stddef.h>
-#include <string.h>
-#include <stdio.h>
-
-//------------- TUSB Option Header -------------//
-#include "tusb_option.h"
-
-//------------- General Header -------------//
-#include "compiler/compiler.h"
-#include "assertion.h"
-#include "binary.h"
-#include "errors.h"
-
-//------------- TUSB Header -------------//
-#include "tusb_types.h"
-#include "std_descriptors.h"
-#include "std_request.h"
-
-#include "osal/osal.h"
-
-//--------------------------------------------------------------------+
-// MACROS
-//--------------------------------------------------------------------+
-#define STRING_(x)  #x                             ///< stringify without expand
-#define XSTRING_(x) STRING_(x)                     ///< expand then stringify
-#define STRING_CONCAT_(a, b) a##b                  ///< concat without expand
-#define XSTRING_CONCAT_(a, b) STRING_CONCAT_(a, b) ///< expand then concat
-
-#define MAX_OF(a, b)  ( (a) > (b) ? (a) : (b) )
-#define MIN_OF(a, b)  ( (a) < (b) ? (a) : (b) )
-
-#define U16_HIGH_U8(u16) ((uint8_t) (((u16) >> 8) & 0x00ff))
-#define U16_LOW_U8(u16)  ((uint8_t) ((u16)       & 0x00ff))
-#define U16_TO_U8S_BE(u16)  U16_HIGH_U8(u16), U16_LOW_U8(u16)
-#define U16_TO_U8S_LE(u16)  U16_LOW_U8(u16), U16_HIGH_U8(u16)
-
-#define U32_B1_U8(u32) ((uint8_t) (((u32) >> 24) & 0x000000ff)) // MSB
-#define U32_B2_U8(u32) ((uint8_t) (((u32) >> 16) & 0x000000ff))
-#define U32_B3_U8(u32) ((uint8_t) (((u32) >>  8) & 0x000000ff))
-#define U32_B4_U8(u32) ((uint8_t) ((u32)        & 0x000000ff)) // LSB
-
-#define U32_TO_U8S_BE(u32) U32_B1_U8(u32), U32_B2_U8(u32), U32_B3_U8(u32), U32_B4_U8(u32)
-#define U32_TO_U8S_LE(u32) U32_B4_U8(u32), U32_B3_U8(u32), U32_B2_U8(u32), U32_B1_U8(u32)
-
-//------------- Endian Conversion -------------//
-#define ENDIAN_BE(u32) \
-    (uint32_t) ( (((u32) & 0xFF) << 24) | (((u32) & 0xFF00) << 8) | (((u32) >> 8) & 0xFF00) | (((u32) >> 24) & 0xFF) )
-
-#define ENDIAN_BE16(le16) ((uint16_t) ((U16_LOW_U8(le16) << 8) | U16_HIGH_U8(le16)) )
-
-#ifndef __n2be_16
-#define __n2be_16(u16)  ((uint16_t) ((U16_LOW_U8(u16) << 8) | U16_HIGH_U8(u16)) )
-#define __be2n_16(u16)  __n2be_16(u16)
-#endif
-
-//--------------------------------------------------------------------+
-// INLINE FUNCTION
-//--------------------------------------------------------------------+
-#define memclr_(buffer, size)  memset((buffer), 0, (size))
-
-
-static inline uint8_t const * descriptor_next(uint8_t const p_desc[]) ATTR_ALWAYS_INLINE ATTR_PURE;
-static inline uint8_t const * descriptor_next(uint8_t const p_desc[])
-{
-  return p_desc + p_desc[DESCRIPTOR_OFFSET_LENGTH];
-}
-
-static inline uint8_t descriptor_typeof(uint8_t const p_desc[]) ATTR_ALWAYS_INLINE ATTR_PURE;
-static inline uint8_t descriptor_typeof(uint8_t const p_desc[])
-{
-  return p_desc[DESCRIPTOR_OFFSET_TYPE];
-}
-
-//------------- Conversion -------------//
-/// form an uint32_t from 4 x uint8_t
-static inline uint32_t u32_from_u8(uint8_t b1, uint8_t b2, uint8_t b3, uint8_t b4) ATTR_ALWAYS_INLINE ATTR_CONST;
-static inline uint32_t u32_from_u8(uint8_t b1, uint8_t b2, uint8_t b3, uint8_t b4)
-{
-  return ( ((uint32_t) b1) << 24) + ( ((uint32_t) b2) << 16) + ( ((uint32_t) b3) << 8) + b4;
-}
-
-static inline uint8_t u16_high_u8(uint16_t u16) ATTR_CONST ATTR_ALWAYS_INLINE;
-static inline uint8_t u16_high_u8(uint16_t u16)
-{
-  return (uint8_t) ( ((uint16_t) (u16 >> 8)) & 0x00ff);
-}
-
-static inline uint8_t u16_low_u8(uint16_t u16) ATTR_CONST ATTR_ALWAYS_INLINE;
-static inline uint8_t u16_low_u8(uint16_t u16)
-{
-  return (uint8_t) (u16 & 0x00ff);
-}
-
-static inline uint16_t u16_le2be(uint16_t u16) ATTR_CONST ATTR_ALWAYS_INLINE;
-static inline uint16_t u16_le2be(uint16_t u16)
-{
-  return ((uint16_t)(u16_low_u8(u16) << 8)) | u16_high_u8(u16);
-}
-
-//------------- Min -------------//
-static inline uint8_t min8_of(uint8_t x, uint8_t y) ATTR_ALWAYS_INLINE ATTR_CONST;
-static inline uint8_t min8_of(uint8_t x, uint8_t y)
-{
-  return (x < y) ? x : y;
-}
-
-static inline uint16_t min16_of(uint16_t x, uint16_t y) ATTR_ALWAYS_INLINE ATTR_CONST;
-static inline uint16_t min16_of(uint16_t x, uint16_t y)
-{
-  return (x < y) ? x : y;
-}
-
-static inline uint32_t min32_of(uint32_t x, uint32_t y) ATTR_ALWAYS_INLINE ATTR_CONST;
-static inline uint32_t min32_of(uint32_t x, uint32_t y)
-{
-  return (x < y) ? x : y;
-}
-
-//------------- Max -------------//
-static inline uint32_t max32_of(uint32_t x, uint32_t y) ATTR_ALWAYS_INLINE ATTR_CONST;
-static inline uint32_t max32_of(uint32_t x, uint32_t y)
-{
-  return (x > y) ? x : y;
-}
-
-static inline uint16_t max16_of(uint16_t x, uint16_t y) ATTR_ALWAYS_INLINE ATTR_CONST;
-static inline uint16_t max16_of(uint16_t x, uint16_t y)
-{
-  return (x > y) ? x : y;
-}
-
-//------------- Align -------------//
-static inline uint32_t align32 (uint32_t value) ATTR_ALWAYS_INLINE ATTR_CONST;
-static inline uint32_t align32 (uint32_t value)
-{
-	return (value & 0xFFFFFFE0UL);
-}
-
-static inline uint32_t align16 (uint32_t value) ATTR_ALWAYS_INLINE ATTR_CONST;
-static inline uint32_t align16 (uint32_t value)
-{
-	return (value & 0xFFFFFFF0UL);
-}
-
-static inline uint32_t align_n (uint32_t alignment, uint32_t value) ATTR_ALWAYS_INLINE ATTR_CONST;
-static inline uint32_t align_n (uint32_t alignment, uint32_t value)
-{
-	return value & ((uint32_t) ~(alignment-1));
-}
-
-static inline uint32_t align4k (uint32_t value) ATTR_ALWAYS_INLINE ATTR_CONST;
-static inline uint32_t align4k (uint32_t value)
-{
-	return (value & 0xFFFFF000UL);
-}
-
-static inline uint32_t offset4k(uint32_t value) ATTR_ALWAYS_INLINE ATTR_CONST;
-static inline uint32_t offset4k(uint32_t value)
-{
-	return (value & 0xFFFUL);
-}
-
-//------------- Mathematics -------------//
-static inline uint32_t abs_of(int32_t value) ATTR_ALWAYS_INLINE ATTR_CONST;
-static inline uint32_t abs_of(int32_t value)
-{
-  return (value < 0) ? (-value) : value;
-}
-
-
-/// inclusive range checking
-static inline bool is_in_range(uint32_t lower, uint32_t value, uint32_t upper) ATTR_ALWAYS_INLINE ATTR_CONST;
-static inline bool is_in_range(uint32_t lower, uint32_t value, uint32_t upper)
-{
-  return (lower <= value) && (value <= upper);
-}
-
-/// exclusive range checking
-static inline bool is_in_range_exclusive(uint32_t lower, uint32_t value, uint32_t upper) ATTR_ALWAYS_INLINE ATTR_CONST;
-static inline bool is_in_range_exclusive(uint32_t lower, uint32_t value, uint32_t upper)
-{
-  return (lower < value) && (value < upper);
-}
-
-// TODO use clz
-static inline uint8_t log2_of(uint32_t value) ATTR_ALWAYS_INLINE ATTR_CONST;
-static inline uint8_t log2_of(uint32_t value)
-{
-  uint8_t result = 0; // log2 of a value is its MSB's position
-
-  while (value >>= 1)
-  {
-    result++;
-  }
-  return result;
-}
-
-// return the number of set bits in value
-static inline uint8_t cardinality_of(uint32_t value) ATTR_ALWAYS_INLINE ATTR_CONST;
-static inline uint8_t cardinality_of(uint32_t value)
-{
-  // Brian Kernighan's method goes through as many iterations as there are set bits. So if we have a 32-bit word with only
-  // the high bit set, then it will only go once through the loop
-  // Published in 1988, the C Programming Language 2nd Ed. (by Brian W. Kernighan and Dennis M. Ritchie)
-  // mentions this in exercise 2-9. On April 19, 2006 Don Knuth pointed out to me that this method
-  // "was first published by Peter Wegner in CACM 3 (1960), 322. (Also discovered independently by Derrick Lehmer and
-  // published in 1964 in a book edited by Beckenbach.)"
-  uint8_t count;
-  for (count = 0; value; count++)
-  {
-    value &= value - 1; // clear the least significant bit set
-  }
-
-  return count;
-}
-
-#ifdef __cplusplus
- }
-#endif
-
-#endif /* _TUSB_COMMON_H_ */
-
-/**  @} */
-/**  @} */
+/**************************************************************************/
+/*!
+    @file     common.h
+    @author   hathach (tinyusb.org)
+
+    @section LICENSE
+
+    Software License Agreement (BSD License)
+
+    Copyright (c) 2013, hathach (tinyusb.org)
+    All rights reserved.
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions are met:
+    1. Redistributions of source code must retain the above copyright
+    notice, this list of conditions and the following disclaimer.
+    2. Redistributions in binary form must reproduce the above copyright
+    notice, this list of conditions and the following disclaimer in the
+    documentation and/or other materials provided with the distribution.
+    3. Neither the name of the copyright holders nor the
+    names of its contributors may be used to endorse or promote products
+    derived from this software without specific prior written permission.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
+    EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+    WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
+    DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+    INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION HOWEVER CAUSED AND
+    ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+    INCLUDING NEGLIGENCE OR OTHERWISE ARISING IN ANY WAY OUT OF THE USE OF THIS
+    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+    This file is part of the tinyusb stack.
+*/
+/**************************************************************************/
+
+/** \defgroup Group_Common Common Files
+ * @{
+ *
+ *  \defgroup Group_CommonH common.h
+ *
+ *  @{
+ */
+
+#ifndef _TUSB_COMMON_H_
+#define _TUSB_COMMON_H_
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+//--------------------------------------------------------------------+
+// MACROS
+//--------------------------------------------------------------------+
+#define STRING_(x)  #x                             // stringify without expand
+#define XSTRING_(x) STRING_(x)                     // expand then stringify
+#define STRING_CONCAT_(a, b) a##b                  // concat without expand
+#define XSTRING_CONCAT_(a, b) STRING_CONCAT_(a, b) // expand then concat
+
+//--------------------------------------------------------------------+
+// INCLUDES
+//--------------------------------------------------------------------+
+
+//------------- Standard Header -------------//
+#include "primitive_types.h"
+#include <stddef.h>
+#include <string.h>
+#include <stdio.h>
+
+//------------- TUSB Option Header -------------//
+#include "tusb_option.h"
+
+//------------- General Header -------------//
+#include "compiler/compiler.h"
+#include "assertion.h"
+#include "binary.h"
+#include "errors.h"
+
+//------------- TUSB Header -------------//
+#include "tusb_types.h"
+#include "std_descriptors.h"
+#include "std_request.h"
+
+#include "osal/osal.h"
+
+//--------------------------------------------------------------------+
+// MACROS
+//--------------------------------------------------------------------+
+#define STRING_(x)  #x                             ///< stringify without expand
+#define XSTRING_(x) STRING_(x)                     ///< expand then stringify
+#define STRING_CONCAT_(a, b) a##b                  ///< concat without expand
+#define XSTRING_CONCAT_(a, b) STRING_CONCAT_(a, b) ///< expand then concat
+
+#define MAX_OF(a, b)  ( (a) > (b) ? (a) : (b) )
+#define MIN_OF(a, b)  ( (a) < (b) ? (a) : (b) )
+
+#define U16_HIGH_U8(u16) ((uint8_t) (((u16) >> 8) & 0x00ff))
+#define U16_LOW_U8(u16)  ((uint8_t) ((u16)       & 0x00ff))
+#define U16_TO_U8S_BE(u16)  U16_HIGH_U8(u16), U16_LOW_U8(u16)
+#define U16_TO_U8S_LE(u16)  U16_LOW_U8(u16), U16_HIGH_U8(u16)
+
+#define U32_B1_U8(u32) ((uint8_t) (((u32) >> 24) & 0x000000ff)) // MSB
+#define U32_B2_U8(u32) ((uint8_t) (((u32) >> 16) & 0x000000ff))
+#define U32_B3_U8(u32) ((uint8_t) (((u32) >>  8) & 0x000000ff))
+#define U32_B4_U8(u32) ((uint8_t) ((u32)        & 0x000000ff)) // LSB
+
+#define U32_TO_U8S_BE(u32) U32_B1_U8(u32), U32_B2_U8(u32), U32_B3_U8(u32), U32_B4_U8(u32)
+#define U32_TO_U8S_LE(u32) U32_B4_U8(u32), U32_B3_U8(u32), U32_B2_U8(u32), U32_B1_U8(u32)
+
+//------------- Endian Conversion -------------//
+#define ENDIAN_BE(u32) \
+    (uint32_t) ( (((u32) & 0xFF) << 24) | (((u32) & 0xFF00) << 8) | (((u32) >> 8) & 0xFF00) | (((u32) >> 24) & 0xFF) )
+
+#define ENDIAN_BE16(le16) ((uint16_t) ((U16_LOW_U8(le16) << 8) | U16_HIGH_U8(le16)) )
+
+#ifndef __n2be_16
+#define __n2be_16(u16)  ((uint16_t) ((U16_LOW_U8(u16) << 8) | U16_HIGH_U8(u16)) )
+#define __be2n_16(u16)  __n2be_16(u16)
+#endif
+
+//--------------------------------------------------------------------+
+// INLINE FUNCTION
+//--------------------------------------------------------------------+
+#define memclr_(buffer, size)  memset((buffer), 0, (size))
+
+
+static inline uint8_t const * descriptor_next(uint8_t const p_desc[]) ATTR_ALWAYS_INLINE ATTR_PURE;
+static inline uint8_t const * descriptor_next(uint8_t const p_desc[])
+{
+  return p_desc + p_desc[DESCRIPTOR_OFFSET_LENGTH];
+}
+
+static inline uint8_t descriptor_typeof(uint8_t const p_desc[]) ATTR_ALWAYS_INLINE ATTR_PURE;
+static inline uint8_t descriptor_typeof(uint8_t const p_desc[])
+{
+  return p_desc[DESCRIPTOR_OFFSET_TYPE];
+}
+
+//------------- Conversion -------------//
+/// form an uint32_t from 4 x uint8_t
+static inline uint32_t u32_from_u8(uint8_t b1, uint8_t b2, uint8_t b3, uint8_t b4) ATTR_ALWAYS_INLINE ATTR_CONST;
+static inline uint32_t u32_from_u8(uint8_t b1, uint8_t b2, uint8_t b3, uint8_t b4)
+{
+  return ( ((uint32_t) b1) << 24) + ( ((uint32_t) b2) << 16) + ( ((uint32_t) b3) << 8) + b4;
+}
+
+static inline uint8_t u16_high_u8(uint16_t u16) ATTR_CONST ATTR_ALWAYS_INLINE;
+static inline uint8_t u16_high_u8(uint16_t u16)
+{
+  return (uint8_t) ( ((uint16_t) (u16 >> 8)) & 0x00ff);
+}
+
+static inline uint8_t u16_low_u8(uint16_t u16) ATTR_CONST ATTR_ALWAYS_INLINE;
+static inline uint8_t u16_low_u8(uint16_t u16)
+{
+  return (uint8_t) (u16 & 0x00ff);
+}
+
+static inline uint16_t u16_le2be(uint16_t u16) ATTR_CONST ATTR_ALWAYS_INLINE;
+static inline uint16_t u16_le2be(uint16_t u16)
+{
+  return ((uint16_t)(u16_low_u8(u16) << 8)) | u16_high_u8(u16);
+}
+
+//------------- Min -------------//
+static inline uint8_t min8_of(uint8_t x, uint8_t y) ATTR_ALWAYS_INLINE ATTR_CONST;
+static inline uint8_t min8_of(uint8_t x, uint8_t y)
+{
+  return (x < y) ? x : y;
+}
+
+static inline uint16_t min16_of(uint16_t x, uint16_t y) ATTR_ALWAYS_INLINE ATTR_CONST;
+static inline uint16_t min16_of(uint16_t x, uint16_t y)
+{
+  return (x < y) ? x : y;
+}
+
+static inline uint32_t min32_of(uint32_t x, uint32_t y) ATTR_ALWAYS_INLINE ATTR_CONST;
+static inline uint32_t min32_of(uint32_t x, uint32_t y)
+{
+  return (x < y) ? x : y;
+}
+
+//------------- Max -------------//
+static inline uint32_t max32_of(uint32_t x, uint32_t y) ATTR_ALWAYS_INLINE ATTR_CONST;
+static inline uint32_t max32_of(uint32_t x, uint32_t y)
+{
+  return (x > y) ? x : y;
+}
+
+static inline uint16_t max16_of(uint16_t x, uint16_t y) ATTR_ALWAYS_INLINE ATTR_CONST;
+static inline uint16_t max16_of(uint16_t x, uint16_t y)
+{
+  return (x > y) ? x : y;
+}
+
+//------------- Align -------------//
+static inline uint32_t align32 (uint32_t value) ATTR_ALWAYS_INLINE ATTR_CONST;
+static inline uint32_t align32 (uint32_t value)
+{
+	return (value & 0xFFFFFFE0UL);
+}
+
+static inline uint32_t align16 (uint32_t value) ATTR_ALWAYS_INLINE ATTR_CONST;
+static inline uint32_t align16 (uint32_t value)
+{
+	return (value & 0xFFFFFFF0UL);
+}
+
+static inline uint32_t align_n (uint32_t alignment, uint32_t value) ATTR_ALWAYS_INLINE ATTR_CONST;
+static inline uint32_t align_n (uint32_t alignment, uint32_t value)
+{
+	return value & ((uint32_t) ~(alignment-1));
+}
+
+static inline uint32_t align4k (uint32_t value) ATTR_ALWAYS_INLINE ATTR_CONST;
+static inline uint32_t align4k (uint32_t value)
+{
+	return (value & 0xFFFFF000UL);
+}
+
+static inline uint32_t offset4k(uint32_t value) ATTR_ALWAYS_INLINE ATTR_CONST;
+static inline uint32_t offset4k(uint32_t value)
+{
+	return (value & 0xFFFUL);
+}
+
+//------------- Mathematics -------------//
+static inline uint32_t abs_of(int32_t value) ATTR_ALWAYS_INLINE ATTR_CONST;
+static inline uint32_t abs_of(int32_t value)
+{
+  return (value < 0) ? (-value) : value;
+}
+
+
+/// inclusive range checking
+static inline bool is_in_range(uint32_t lower, uint32_t value, uint32_t upper) ATTR_ALWAYS_INLINE ATTR_CONST;
+static inline bool is_in_range(uint32_t lower, uint32_t value, uint32_t upper)
+{
+  return (lower <= value) && (value <= upper);
+}
+
+/// exclusive range checking
+static inline bool is_in_range_exclusive(uint32_t lower, uint32_t value, uint32_t upper) ATTR_ALWAYS_INLINE ATTR_CONST;
+static inline bool is_in_range_exclusive(uint32_t lower, uint32_t value, uint32_t upper)
+{
+  return (lower < value) && (value < upper);
+}
+
+// TODO use clz
+static inline uint8_t log2_of(uint32_t value) ATTR_ALWAYS_INLINE ATTR_CONST;
+static inline uint8_t log2_of(uint32_t value)
+{
+  uint8_t result = 0; // log2 of a value is its MSB's position
+
+  while (value >>= 1)
+  {
+    result++;
+  }
+  return result;
+}
+
+// return the number of set bits in value
+static inline uint8_t cardinality_of(uint32_t value) ATTR_ALWAYS_INLINE ATTR_CONST;
+static inline uint8_t cardinality_of(uint32_t value)
+{
+  // Brian Kernighan's method goes through as many iterations as there are set bits. So if we have a 32-bit word with only
+  // the high bit set, then it will only go once through the loop
+  // Published in 1988, the C Programming Language 2nd Ed. (by Brian W. Kernighan and Dennis M. Ritchie)
+  // mentions this in exercise 2-9. On April 19, 2006 Don Knuth pointed out to me that this method
+  // "was first published by Peter Wegner in CACM 3 (1960), 322. (Also discovered independently by Derrick Lehmer and
+  // published in 1964 in a book edited by Beckenbach.)"
+  uint8_t count;
+  for (count = 0; value; count++)
+  {
+    value &= value - 1; // clear the least significant bit set
+  }
+
+  return count;
+}
+
+#ifdef __cplusplus
+ }
+#endif
+
+#endif /* _TUSB_COMMON_H_ */
+
+/**  @} */
+/**  @} */

+ 4 - 4
tinyusb/device/dcd_lpc43xx.c

@@ -351,7 +351,7 @@ void dcd_pipe_control_stall(uint8_t coreid)
 }
 
 // control transfer does not need to use qtd find function
-tusb_error_t dcd_pipe_control_xfer(uint8_t coreid, tusb_direction_t dir, void * p_buffer, uint16_t length, bool int_on_complete)
+tusb_error_t dcd_pipe_control_xfer(uint8_t coreid, tusb_direction_t dir, uint8_t * p_buffer, uint16_t length, bool int_on_complete)
 {
   LPC_USB0_Type* const lpc_usb = LPC_USB[coreid];
   dcd_data_t* const p_dcd      = dcd_data_ptr[coreid];
@@ -485,12 +485,12 @@ static tusb_error_t pipe_add_xfer(endpoint_handle_t edpt_hdl, void * buffer, uin
   return TUSB_ERROR_NONE;
 }
 
-tusb_error_t dcd_pipe_queue_xfer(endpoint_handle_t edpt_hdl, void * buffer, uint16_t total_bytes)
+tusb_error_t dcd_pipe_queue_xfer(endpoint_handle_t edpt_hdl, uint8_t * buffer, uint16_t total_bytes)
 {
   return pipe_add_xfer( edpt_hdl, buffer, total_bytes, false);
 }
 
-tusb_error_t  dcd_pipe_xfer(endpoint_handle_t edpt_hdl, void* buffer, uint16_t total_bytes, bool int_on_complete)
+tusb_error_t  dcd_pipe_xfer(endpoint_handle_t edpt_hdl, uint8_t * buffer, uint16_t total_bytes, bool int_on_complete)
 {
   ASSERT_STATUS ( pipe_add_xfer(edpt_hdl, buffer, total_bytes, int_on_complete) );
 
@@ -602,7 +602,7 @@ void dcd_isr(uint8_t coreid)
           .class_code = 0
       };
 
-		  dcd_qtd_t * const p_qtd = &p_dcd->qhd[ (edpt_complete & BIT_(0)) ? 0 : 1 ].qtd_overlay;
+		  dcd_qtd_t volatile * const p_qtd = &p_dcd->qhd[ (edpt_complete & BIT_(0)) ? 0 : 1 ].qtd_overlay;
 		  tusb_event_t event = ( p_qtd->xact_err || p_qtd->halted || p_qtd->buffer_err ) ? TUSB_EVENT_XFER_ERROR : TUSB_EVENT_XFER_COMPLETE;
 
 		  usbd_xfer_isr(edpt_hdl, event, 0); // TODO xferred bytes for control xfer is not needed yet !!!!

+ 1 - 1
tinyusb/device/usbd.c

@@ -344,7 +344,7 @@ static tusb_error_t get_descriptor(uint8_t coreid, tusb_control_request_t const
     if ( ! (desc_index < TUSB_CFG_DEVICE_STRING_DESCRIPTOR_COUNT) ) return TUSB_ERROR_DCD_CONTROL_REQUEST_NOT_SUPPORT;
 
     (*pp_buffer) = (uint8_t *) desc_str_table[desc_index];
-    (*p_length)  = desc_str_table[desc_index]->bLength;
+    (*p_length)  = **pp_buffer;
   }else
   {
     return TUSB_ERROR_DCD_CONTROL_REQUEST_NOT_SUPPORT;

+ 633 - 633
tinyusb/host/usbh.c

@@ -1,633 +1,633 @@
-/**************************************************************************/
-/*!
-    @file     usbd_host.c
-    @author   hathach (tinyusb.org)
-
-    @section LICENSE
-
-    Software License Agreement (BSD License)
-
-    Copyright (c) 2013, hathach (tinyusb.org)
-    All rights reserved.
-
-    Redistribution and use in source and binary forms, with or without
-    modification, are permitted provided that the following conditions are met:
-    1. Redistributions of source code must retain the above copyright
-    notice, this list of conditions and the following disclaimer.
-    2. Redistributions in binary form must reproduce the above copyright
-    notice, this list of conditions and the following disclaimer in the
-    documentation and/or other materials provided with the distribution.
-    3. Neither the name of the copyright holders nor the
-    names of its contributors may be used to endorse or promote products
-    derived from this software without specific prior written permission.
-
-    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
-    EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-    WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
-    DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
-    INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
-    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION HOWEVER CAUSED AND
-    ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-    INCLUDING NEGLIGENCE OR OTHERWISE ARISING IN ANY WAY OUT OF THE USE OF THIS
-    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-    This file is part of the tinyusb stack.
-*/
-/**************************************************************************/
-
-#include "common/common.h"
-
-#if MODE_HOST_SUPPORTED
-
-#define _TINY_USB_SOURCE_FILE_
-
-//--------------------------------------------------------------------+
-// INCLUDE
-//--------------------------------------------------------------------+
-#include "tusb.h"
-#include "hub.h"
-#include "usbh_hcd.h"
-
-//--------------------------------------------------------------------+
-// MACRO CONSTANT TYPEDEF
-//--------------------------------------------------------------------+
-#define ENUM_QUEUE_DEPTH  5
-
-// TODO fix/compress number of class driver
-static host_class_driver_t const usbh_class_drivers[TUSB_CLASS_MAPPED_INDEX_END] =
-{
-#if HOST_CLASS_HID
-    [TUSB_CLASS_HID] = {
-        .init         = hidh_init,
-        .open_subtask = hidh_open_subtask,
-        .isr          = hidh_isr,
-        .close        = hidh_close
-    },
-#endif
-
-#if TUSB_CFG_HOST_CDC
-    [TUSB_CLASS_CDC] = {
-        .init         = cdch_init,
-        .open_subtask = cdch_open_subtask,
-        .isr          = cdch_isr,
-        .close        = cdch_close
-    },
-#endif
-
-#if TUSB_CFG_HOST_MSC
-    [TUSB_CLASS_MSC] = {
-        .init         = msch_init,
-        .open_subtask = msch_open_subtask,
-        .isr          = msch_isr,
-        .close        = msch_close
-    },
-#endif
-
-#if TUSB_CFG_HOST_HUB
-    [TUSB_CLASS_HUB] = {
-        .init         = hub_init,
-        .open_subtask = hub_open_subtask,
-        .isr          = hub_isr,
-        .close        = hub_close
-    },
-#endif
-
-#if TUSB_CFG_HOST_CUSTOM_CLASS
-    [TUSB_CLASS_MAPPED_INDEX_END-1] = {
-        .init         = cush_init,
-        .open_subtask = cush_open_subtask,
-        .isr          = cush_isr,
-        .close        = cush_close
-    }
-#endif
-};
-
-//--------------------------------------------------------------------+
-// INTERNAL OBJECT & FUNCTION DECLARATION
-//--------------------------------------------------------------------+
-TUSB_CFG_ATTR_USBRAM usbh_device_info_t usbh_devices[TUSB_CFG_HOST_DEVICE_MAX+1]; // including zero-address
-
-//------------- Enumeration Task Data -------------//
-OSAL_TASK_DEF(usbh_enumeration_task, 200, TUSB_CFG_OS_TASK_PRIO);
-OSAL_QUEUE_DEF(enum_queue_def, ENUM_QUEUE_DEPTH, uint32_t);
-
-static osal_queue_handle_t enum_queue_hdl;
-TUSB_CFG_ATTR_USBRAM ATTR_ALIGNED(4) STATIC_VAR uint8_t enum_data_buffer[TUSB_CFG_HOST_ENUM_BUFFER_SIZE];
-
-//------------- Reporter Task Data -------------//
-
-//------------- Helper Function Prototypes -------------//
-static inline uint8_t get_new_address(void) ATTR_ALWAYS_INLINE;
-static inline uint8_t get_configure_number_for_device(tusb_descriptor_device_t* dev_desc) ATTR_ALWAYS_INLINE;
-
-//--------------------------------------------------------------------+
-// PUBLIC API (Parameter Verification is required)
-//--------------------------------------------------------------------+
-tusb_device_state_t tusbh_device_get_state (uint8_t const dev_addr)
-{
-  ASSERT_INT_WITHIN(1, TUSB_CFG_HOST_DEVICE_MAX, dev_addr, TUSB_DEVICE_STATE_INVALID_PARAMETER);
-  return (tusb_device_state_t) usbh_devices[dev_addr].state;
-}
-
-uint32_t tusbh_device_get_mounted_class_flag(uint8_t dev_addr)
-{
-  return tusbh_device_is_configured(dev_addr) ? usbh_devices[dev_addr].flag_supported_class : 0;
-}
-
-//--------------------------------------------------------------------+
-// CLASS-USBD API (don't require to verify parameters)
-//--------------------------------------------------------------------+
-tusb_error_t usbh_init(void)
-{
-  memclr_(usbh_devices, sizeof(usbh_device_info_t)*(TUSB_CFG_HOST_DEVICE_MAX+1));
-
-  ASSERT_STATUS( hcd_init() );
-
-  //------------- Enumeration & Reporter Task init -------------//
-  enum_queue_hdl = osal_queue_create( OSAL_QUEUE_REF(enum_queue_def) );
-  ASSERT_PTR(enum_queue_hdl, TUSB_ERROR_OSAL_QUEUE_FAILED);
-  ASSERT_STATUS( osal_task_create( OSAL_TASK_REF(usbh_enumeration_task) ));
-
-  //------------- Semaphore, Mutex for Control Pipe -------------//
-  for(uint8_t i=0; i<TUSB_CFG_HOST_DEVICE_MAX+1; i++) // including address zero
-  {
-    usbh_device_info_t * const p_device = &usbh_devices[i];
-
-    p_device->control.sem_hdl = osal_semaphore_create( OSAL_SEM_REF(p_device->control.semaphore) );
-    ASSERT_PTR(p_device->control.sem_hdl, TUSB_ERROR_OSAL_SEMAPHORE_FAILED);
-
-    p_device->control.mutex_hdl = osal_mutex_create ( OSAL_MUTEX_REF(p_device->control.mutex) );
-    ASSERT_PTR(p_device->control.mutex_hdl, TUSB_ERROR_OSAL_MUTEX_FAILED);
-  }
-
-  //------------- class init -------------//
-  for (uint8_t class_index = 1; class_index < TUSB_CLASS_MAPPED_INDEX_END; class_index++)
-  {
-    if (usbh_class_drivers[class_index].init)
-    {
-      usbh_class_drivers[class_index].init();
-    }
-  }
-
-  return TUSB_ERROR_NONE;
-}
-
-//------------- USBH control transfer -------------//
-// function called within a task, requesting os blocking services, subtask input parameter must be static/global variables or constant
-tusb_error_t usbh_control_xfer_subtask(uint8_t dev_addr, uint8_t bmRequestType, uint8_t bRequest,
-                                       uint16_t wValue, uint16_t wIndex, uint16_t wLength, uint8_t* data)
-{
-  static tusb_error_t error; // FIXME cmsis-rtx use svc for OS API, error value changed after mutex release at the end of function
-
-  OSAL_SUBTASK_BEGIN
-
-  osal_mutex_wait(usbh_devices[dev_addr].control.mutex_hdl, OSAL_TIMEOUT_NORMAL, &error);
-  SUBTASK_ASSERT_STATUS_WITH_HANDLER(error, osal_mutex_release(usbh_devices[dev_addr].control.mutex_hdl));
-
-  usbh_devices[dev_addr].control.request = (tusb_control_request_t) {
-                                                  {.bmRequestType = bmRequestType},
-                                                  .bRequest      = bRequest,
-                                                  .wValue        = wValue,
-                                                  .wIndex        = wIndex,
-                                                  .wLength       = wLength
-                                           };
-
-#ifndef _TEST_
-  usbh_devices[dev_addr].control.pipe_status = 0;
-#else
-  usbh_devices[dev_addr].control.pipe_status = TUSB_EVENT_XFER_COMPLETE; // in Test project, mark as complete immediately
-#endif
-
-  SUBTASK_ASSERT_STATUS_WITH_HANDLER( hcd_pipe_control_xfer(dev_addr, &usbh_devices[dev_addr].control.request, data),
-                                      osal_mutex_release(usbh_devices[dev_addr].control.mutex_hdl) );
-
-  osal_semaphore_wait(usbh_devices[dev_addr].control.sem_hdl, OSAL_TIMEOUT_NORMAL, &error); // careful of local variable without static
-  osal_mutex_release(usbh_devices[dev_addr].control.mutex_hdl);
-
-  // TODO make handler for this function general purpose
-  if (TUSB_ERROR_NONE != error)   SUBTASK_EXIT(error);
-  if (TUSB_EVENT_XFER_STALLED == usbh_devices[dev_addr].control.pipe_status) SUBTASK_EXIT(TUSB_ERROR_USBH_XFER_STALLED);
-  if (TUSB_EVENT_XFER_ERROR   == usbh_devices[dev_addr].control.pipe_status) SUBTASK_EXIT(TUSB_ERROR_USBH_XFER_FAILED);
-
-//  SUBTASK_ASSERT_WITH_HANDLER(TUSB_ERROR_NONE == error &&
-//                              TUSB_EVENT_XFER_COMPLETE == usbh_devices[dev_addr].control.pipe_status,
-//                              tusbh_device_mount_failed_cb(TUSB_ERROR_USBH_MOUNT_DEVICE_NOT_RESPOND, NULL) );
-
-  OSAL_SUBTASK_END
-}
-
-tusb_error_t usbh_pipe_control_open(uint8_t dev_addr, uint8_t max_packet_size) ATTR_ALWAYS_INLINE;
-tusb_error_t usbh_pipe_control_open(uint8_t dev_addr, uint8_t max_packet_size)
-{
-  osal_semaphore_reset( usbh_devices[dev_addr].control.sem_hdl );
-  osal_mutex_reset( usbh_devices[dev_addr].control.mutex_hdl );
-
-  ASSERT_STATUS( hcd_pipe_control_open(dev_addr, max_packet_size) );
-
-  return TUSB_ERROR_NONE;
-}
-
-static inline tusb_error_t usbh_pipe_control_close(uint8_t dev_addr) ATTR_ALWAYS_INLINE;
-static inline tusb_error_t usbh_pipe_control_close(uint8_t dev_addr)
-{
-  ASSERT_STATUS( hcd_pipe_control_close(dev_addr) );
-
-  return TUSB_ERROR_NONE;
-}
-
-tusb_interface_status_t usbh_pipe_status_get(pipe_handle_t pipe_hdl)
-{
-  return TUSB_INTERFACE_STATUS_BUSY;
-}
-
-//--------------------------------------------------------------------+
-// USBH-HCD ISR/Callback API
-//--------------------------------------------------------------------+
-// interrupt caused by a TD (with IOC=1) in pipe of class class_code
-void usbh_xfer_isr(pipe_handle_t pipe_hdl, uint8_t class_code, tusb_event_t event, uint32_t xferred_bytes)
-{
-  uint8_t class_index = std_class_code_to_index(class_code);
-  if (TUSB_XFER_CONTROL == pipe_hdl.xfer_type)
-  {
-    usbh_devices[ pipe_hdl.dev_addr ].control.pipe_status   = event;
-//    usbh_devices[ pipe_hdl.dev_addr ].control.xferred_bytes = xferred_bytes; not yet neccessary
-    osal_semaphore_post( usbh_devices[ pipe_hdl.dev_addr ].control.sem_hdl );
-  }else if (usbh_class_drivers[class_index].isr)
-  {
-    usbh_class_drivers[class_index].isr(pipe_hdl, event, xferred_bytes);
-  }else
-  {
-    ASSERT(false, VOID_RETURN); // something wrong, no one claims the isr's source
-  }
-}
-
-void usbh_hub_port_plugged_isr(uint8_t hub_addr, uint8_t hub_port)
-{
-  osal_queue_send(enum_queue_hdl,
-                  &(usbh_enumerate_t){
-                    .core_id  = usbh_devices[hub_addr].core_id,
-                    .hub_addr = hub_addr,
-                    .hub_port = hub_port}
-                  );
-}
-
-void usbh_hcd_rhport_plugged_isr(uint8_t hostid)
-{
-  osal_queue_send(enum_queue_hdl,
-                  &(usbh_enumerate_t){
-                    .core_id  = hostid,
-                    .hub_addr = 0,
-                    .hub_port = 0}
-                  );
-}
-
-// a device unplugged on hostid, hub_addr, hub_port
-// return true if found and unmounted device, false if cannot find
-static void usbh_device_unplugged(uint8_t hostid, uint8_t hub_addr, uint8_t hub_port)
-{
-  bool is_found = false;
-  //------------- find the all devices (star-network) under port that is unplugged -------------//
-  for (uint8_t dev_addr = 0; dev_addr <= TUSB_CFG_HOST_DEVICE_MAX; dev_addr ++)
-  {
-    if (usbh_devices[dev_addr].core_id  == hostid   &&
-        (hub_addr == 0 || usbh_devices[dev_addr].hub_addr == hub_addr) && // hub_addr == 0 & hub_port == 0 means roothub
-        (hub_port == 0 || usbh_devices[dev_addr].hub_port == hub_port) &&
-        usbh_devices[dev_addr].state    != TUSB_DEVICE_STATE_UNPLUG)
-    {
-      // TODO Hub multiple level
-      for (uint8_t class_index = 1; class_index < TUSB_CLASS_MAPPED_INDEX_END; class_index++)
-      {
-        if ((usbh_devices[dev_addr].flag_supported_class & BIT_(class_index)) &&
-            usbh_class_drivers[class_index].close)
-        {
-          usbh_class_drivers[class_index].close(dev_addr);
-        }
-      }
-
-      // TODO refractor
-      // set to REMOVING to allow HCD to clean up its cached data for this device
-      // HCD must set this device's state to TUSB_DEVICE_STATE_UNPLUG when done
-      usbh_devices[dev_addr].state = TUSB_DEVICE_STATE_REMOVING;
-      usbh_devices[dev_addr].flag_supported_class = 0;
-
-      usbh_pipe_control_close(dev_addr);
-
-
-      is_found = true;
-    }
-  }
-
-  if (is_found) hcd_port_unplug(usbh_devices[0].core_id); // TODO hack
-
-}
-
-void usbh_hcd_rhport_unplugged_isr(uint8_t hostid)
-{
-  osal_queue_send(enum_queue_hdl,
-                  &(usbh_enumerate_t)
-                  {
-                    .core_id = hostid,
-                    .hub_addr = 0,
-                    .hub_port = 0
-                  } );
-}
-
-//--------------------------------------------------------------------+
-// ENUMERATION TASK
-//--------------------------------------------------------------------+
-static tusb_error_t enumeration_body_subtask(void);
-
-// To enable the TASK_ASSERT style (quick return on false condition) in a real RTOS, a task must act as a wrapper
-// and is used mainly to call subtasks. Within a subtask return statement can be called freely, the task with
-// forever loop cannot have any return at all.
-OSAL_TASK_FUNCTION(usbh_enumeration_task) (void* p_task_para)
-{
-  OSAL_TASK_LOOP_BEGIN
-
-  enumeration_body_subtask();
-
-  OSAL_TASK_LOOP_END
-}
-
-tusb_error_t enumeration_body_subtask(void)
-{
-  enum {
-    POWER_STABLE_DELAY = 300,
-    RESET_DELAY = 100 // NXP's EHCI require more than 50ms to work properly although the USB specs say only 50ms
-  };
-
-  tusb_error_t error;
-  usbh_enumerate_t enum_entry;
-
-  // for OSAL_NONE local variable won't retain value after blocking service sem_wait/queue_recv
-  static uint8_t new_addr;
-  static uint8_t configure_selected = 1; // TODO move
-  static uint8_t *p_desc = NULL; // TODO move
-
-  OSAL_SUBTASK_BEGIN
-
-  osal_queue_receive(enum_queue_hdl, &enum_entry, OSAL_TIMEOUT_WAIT_FOREVER, &error);
-  SUBTASK_ASSERT_STATUS(error);
-
-  usbh_devices[0].core_id  = enum_entry.core_id; // TODO refractor integrate to device_pool
-  usbh_devices[0].hub_addr = enum_entry.hub_addr;
-  usbh_devices[0].hub_port = enum_entry.hub_port;
-  usbh_devices[0].state    = TUSB_DEVICE_STATE_UNPLUG;
-
-  //------------- connected/disconnected directly with roothub -------------//
-  if ( usbh_devices[0].hub_addr == 0)
-  {
-    if( hcd_port_connect_status(usbh_devices[0].core_id) )
-    { // connection event
-      osal_task_delay(POWER_STABLE_DELAY); // wait until device is stable. Increase this if the first 8 bytes is failed to get
-
-      if ( !hcd_port_connect_status(usbh_devices[0].core_id) ) SUBTASK_EXIT(TUSB_ERROR_NONE); // exit if device unplugged while delaying
-
-      hcd_port_reset( usbh_devices[0].core_id ); // port must be reset to have correct speed operation
-      osal_task_delay(RESET_DELAY);
-
-      usbh_devices[0].speed = hcd_port_speed_get( usbh_devices[0].core_id );
-    }
-    else
-    { // disconnection event
-      usbh_device_unplugged(usbh_devices[0].core_id, 0, 0);
-      SUBTASK_EXIT(TUSB_ERROR_NONE); // restart task
-    }
-  }
-  #if TUSB_CFG_HOST_HUB
-  //------------- connected/disconnected via hub -------------//
-  else
-  {
-    //------------- Get Port Status -------------//
-    OSAL_SUBTASK_INVOKED_AND_WAIT(
-        usbh_control_xfer_subtask( usbh_devices[0].hub_addr, bm_request_type(TUSB_DIR_DEV_TO_HOST, TUSB_REQUEST_TYPE_CLASS, TUSB_REQUEST_RECIPIENT_OTHER),
-                                   HUB_REQUEST_GET_STATUS, 0, usbh_devices[0].hub_port,
-                                   4, enum_data_buffer ),
-        error
-    );
-//    SUBTASK_ASSERT_STATUS( error );
-    SUBTASK_ASSERT_STATUS_WITH_HANDLER(error, hub_status_pipe_queue( usbh_devices[0].hub_addr) ); // TODO hub refractor
-
-    // Acknowledge Port Connection Change
-    OSAL_SUBTASK_INVOKED_AND_WAIT( hub_port_clear_feature_subtask(usbh_devices[0].hub_addr, usbh_devices[0].hub_port, HUB_FEATURE_PORT_CONNECTION_CHANGE), error );
-
-    if ( ! ((hub_port_status_response_t *) enum_data_buffer)->status_change.connect_status )   SUBTASK_EXIT(TUSB_ERROR_NONE); // only handle connection change
-
-    if ( ! ((hub_port_status_response_t *) enum_data_buffer)->status_current.connect_status )
-    { // Disconnection event
-      usbh_device_unplugged(usbh_devices[0].core_id, usbh_devices[0].hub_addr, usbh_devices[0].hub_port);
-
-      (void) hub_status_pipe_queue( usbh_devices[0].hub_addr ); // done with hub, waiting for next data on status pipe
-      SUBTASK_EXIT(TUSB_ERROR_NONE); // restart task
-    }
-    else
-    { // Connection Event
-      OSAL_SUBTASK_INVOKED_AND_WAIT ( hub_port_reset_subtask(usbh_devices[0].hub_addr, usbh_devices[0].hub_port), error );
-//      SUBTASK_ASSERT_STATUS( error );
-      SUBTASK_ASSERT_STATUS_WITH_HANDLER(error, hub_status_pipe_queue( usbh_devices[0].hub_addr) ); // TODO hub refractor
-
-      usbh_devices[0].speed = hub_port_get_speed();
-
-      // Acknowledge Port Reset Change
-      OSAL_SUBTASK_INVOKED_AND_WAIT( hub_port_clear_feature_subtask(usbh_devices[0].hub_addr, usbh_devices[0].hub_port, HUB_FEATURE_PORT_RESET_CHANGE), error );
-    }
-  }
-  #endif
-
-  SUBTASK_ASSERT_STATUS( usbh_pipe_control_open(0, 8) );
-  usbh_devices[0].state = TUSB_DEVICE_STATE_ADDRESSED;
-
-  //------------- Get first 8 bytes of device descriptor to get Control Endpoint Size -------------//
-  OSAL_SUBTASK_INVOKED_AND_WAIT(
-      usbh_control_xfer_subtask( 0, bm_request_type(TUSB_DIR_DEV_TO_HOST, TUSB_REQUEST_TYPE_STANDARD, TUSB_REQUEST_RECIPIENT_DEVICE),
-                                 TUSB_REQUEST_GET_DESCRIPTOR, (TUSB_DESC_TYPE_DEVICE << 8), 0,
-                                 8, enum_data_buffer ),
-      error
-  );
-
-  //------------- Reset device again before Set Address -------------//
-  if (usbh_devices[0].hub_addr == 0)
-  { // connected directly to roothub
-    SUBTASK_ASSERT_STATUS(error); // TODO some slow device is observed to fail the very fist controller xfer, can try more times
-    hcd_port_reset( usbh_devices[0].core_id ); // reset port after 8 byte descriptor
-    osal_task_delay(RESET_DELAY);
-  }
-  #if TUSB_CFG_HOST_HUB
-  else
-  { // connected via a hub
-    SUBTASK_ASSERT_STATUS_WITH_HANDLER(error, hub_status_pipe_queue( usbh_devices[0].hub_addr) ); // TODO hub refractor
-    OSAL_SUBTASK_INVOKED_AND_WAIT ( hub_port_reset_subtask(usbh_devices[0].hub_addr, usbh_devices[0].hub_port), error );
-
-    if ( TUSB_ERROR_NONE == error )
-    { // Acknowledge Port Reset Change if Reset Successful
-      OSAL_SUBTASK_INVOKED_AND_WAIT( hub_port_clear_feature_subtask(usbh_devices[0].hub_addr, usbh_devices[0].hub_port, HUB_FEATURE_PORT_RESET_CHANGE), error );
-    }
-
-    (void) hub_status_pipe_queue( usbh_devices[0].hub_addr ); // done with hub, waiting for next data on status pipe
-  }
-  #endif
-
-  //------------- Set new address -------------//
-  new_addr = get_new_address();
-  SUBTASK_ASSERT(new_addr <= TUSB_CFG_HOST_DEVICE_MAX); // TODO notify application we reach max devices
-
-  OSAL_SUBTASK_INVOKED_AND_WAIT(
-    usbh_control_xfer_subtask( 0, bm_request_type(TUSB_DIR_HOST_TO_DEV, TUSB_REQUEST_TYPE_STANDARD, TUSB_REQUEST_RECIPIENT_DEVICE),
-                               TUSB_REQUEST_SET_ADDRESS, new_addr, 0,
-                               0, NULL ),
-    error
-  );
-  SUBTASK_ASSERT_STATUS(error);
-
-  //------------- update port info & close control pipe of addr0 -------------//
-  usbh_devices[new_addr].core_id  = usbh_devices[0].core_id;
-  usbh_devices[new_addr].hub_addr = usbh_devices[0].hub_addr;
-  usbh_devices[new_addr].hub_port = usbh_devices[0].hub_port;
-  usbh_devices[new_addr].speed    = usbh_devices[0].speed;
-  usbh_devices[new_addr].state    = TUSB_DEVICE_STATE_ADDRESSED;
-
-  usbh_pipe_control_close(0);
-  usbh_devices[0].state = TUSB_DEVICE_STATE_UNPLUG;
-
-  // open control pipe for new address
-  SUBTASK_ASSERT_STATUS ( usbh_pipe_control_open(new_addr, ((tusb_descriptor_device_t*) enum_data_buffer)->bMaxPacketSize0 ) );
-
-  //------------- Get full device descriptor -------------//
-  OSAL_SUBTASK_INVOKED_AND_WAIT(
-      usbh_control_xfer_subtask( new_addr, bm_request_type(TUSB_DIR_DEV_TO_HOST, TUSB_REQUEST_TYPE_STANDARD, TUSB_REQUEST_RECIPIENT_DEVICE),
-                                 TUSB_REQUEST_GET_DESCRIPTOR, (TUSB_DESC_TYPE_DEVICE << 8), 0,
-                                 18, enum_data_buffer ),
-      error
-  );
-  SUBTASK_ASSERT_STATUS(error);
-
-  // update device info  TODO alignment issue
-  usbh_devices[new_addr].vendor_id       = ((tusb_descriptor_device_t*) enum_data_buffer)->idVendor;
-  usbh_devices[new_addr].product_id      = ((tusb_descriptor_device_t*) enum_data_buffer)->idProduct;
-  usbh_devices[new_addr].configure_count = ((tusb_descriptor_device_t*) enum_data_buffer)->bNumConfigurations;
-
-  configure_selected = get_configure_number_for_device((tusb_descriptor_device_t*) enum_data_buffer);
-  SUBTASK_ASSERT(configure_selected <= usbh_devices[new_addr].configure_count); // TODO notify application when invalid configuration
-
-  //------------- Get 9 bytes of configuration descriptor -------------//
-  OSAL_SUBTASK_INVOKED_AND_WAIT(
-      usbh_control_xfer_subtask( new_addr, bm_request_type(TUSB_DIR_DEV_TO_HOST, TUSB_REQUEST_TYPE_STANDARD, TUSB_REQUEST_RECIPIENT_DEVICE),
-                                 TUSB_REQUEST_GET_DESCRIPTOR, (TUSB_DESC_TYPE_CONFIGURATION << 8) | (configure_selected - 1), 0,
-                                 9, enum_data_buffer ),
-      error
-  );
-  SUBTASK_ASSERT_STATUS(error);
-  SUBTASK_ASSERT_WITH_HANDLER( TUSB_CFG_HOST_ENUM_BUFFER_SIZE >= ((tusb_descriptor_configuration_t*)enum_data_buffer)->wTotalLength,
-                            tusbh_device_mount_failed_cb(TUSB_ERROR_USBH_MOUNT_CONFIG_DESC_TOO_LONG, NULL) );
-
-  //------------- Get full configuration descriptor -------------//
-  OSAL_SUBTASK_INVOKED_AND_WAIT(
-      usbh_control_xfer_subtask( new_addr, bm_request_type(TUSB_DIR_DEV_TO_HOST, TUSB_REQUEST_TYPE_STANDARD, TUSB_REQUEST_RECIPIENT_DEVICE),
-                                 TUSB_REQUEST_GET_DESCRIPTOR, (TUSB_DESC_TYPE_CONFIGURATION << 8) | (configure_selected - 1), 0,
-                                 TUSB_CFG_HOST_ENUM_BUFFER_SIZE, enum_data_buffer ),
-      error
-  );
-  SUBTASK_ASSERT_STATUS(error);
-
-  // update configuration info
-  usbh_devices[new_addr].interface_count = ((tusb_descriptor_configuration_t*) enum_data_buffer)->bNumInterfaces;
-
-  //------------- Set Configure -------------//
-  OSAL_SUBTASK_INVOKED_AND_WAIT(
-    usbh_control_xfer_subtask( new_addr, bm_request_type(TUSB_DIR_HOST_TO_DEV, TUSB_REQUEST_TYPE_STANDARD, TUSB_REQUEST_RECIPIENT_DEVICE),
-                               TUSB_REQUEST_SET_CONFIGURATION, configure_selected, 0,
-                               0, NULL ),
-    error
-  );
-  SUBTASK_ASSERT_STATUS(error);
-
-  usbh_devices[new_addr].state = TUSB_DEVICE_STATE_CONFIGURED;
-
-  //------------- TODO Get String Descriptors -------------//
-
-  //------------- parse configuration & install drivers -------------//
-  p_desc = enum_data_buffer + sizeof(tusb_descriptor_configuration_t);
-
-  // parse each interfaces
-  while( p_desc < enum_data_buffer + ((tusb_descriptor_configuration_t*)enum_data_buffer)->wTotalLength )
-  {
-    // skip until we see interface descriptor
-    if ( TUSB_DESC_TYPE_INTERFACE != p_desc[DESCRIPTOR_OFFSET_TYPE] )
-    {
-      p_desc += p_desc[DESCRIPTOR_OFFSET_LENGTH]; // skip the descriptor, increase by the descriptor's length
-    }else
-    {
-      static uint8_t class_index; // has to be static as it is used to call class's open_subtask
-
-      class_index = std_class_code_to_index( ((tusb_descriptor_interface_t*) p_desc)->bInterfaceClass );
-      SUBTASK_ASSERT( class_index != 0 ); // class_index == 0 means corrupted data, abort enumeration
-
-      if (usbh_class_drivers[class_index].open_subtask &&
-          !(class_index == TUSB_CLASS_HUB && usbh_devices[new_addr].hub_addr != 0))
-      { // supported class, TODO Hub disable multiple level
-        static uint16_t length;
-        length = 0;
-
-        OSAL_SUBTASK_INVOKED_AND_WAIT ( // parameters in task/sub_task must be static storage (static or global)
-            usbh_class_drivers[class_index].open_subtask( new_addr, (tusb_descriptor_interface_t*) p_desc, &length ),
-            error
-        );
-
-        if (error == TUSB_ERROR_NONE)
-        {
-          SUBTASK_ASSERT( length >= sizeof(tusb_descriptor_interface_t) );
-          usbh_devices[new_addr].flag_supported_class |= BIT_(class_index);
-          p_desc += length;
-        }else  // Interface open failed, for example a subclass is not supported
-        {
-          p_desc += p_desc[DESCRIPTOR_OFFSET_LENGTH]; // skip this interface, the rest will be skipped by the above loop
-        }
-      } else // unsupported class (not enable or yet implemented)
-      {
-        p_desc += p_desc[DESCRIPTOR_OFFSET_LENGTH]; // skip this interface, the rest will be skipped by the above loop
-      }
-    }
-  }
-
-  tusbh_device_mount_succeed_cb(new_addr);
-
-  OSAL_SUBTASK_END
-}
-
-//--------------------------------------------------------------------+
-// REPORTER TASK & ITS DATA
-//--------------------------------------------------------------------+
-
-
-
-
-
-//--------------------------------------------------------------------+
-// INTERNAL HELPER
-//--------------------------------------------------------------------+
-static inline uint8_t get_new_address(void)
-{
-  uint8_t addr;
-  for (addr=1; addr <= TUSB_CFG_HOST_DEVICE_MAX; addr++)
-  {
-    if (usbh_devices[addr].state == TUSB_DEVICE_STATE_UNPLUG)
-      break;
-  }
-  return addr;
-}
-
-static inline uint8_t get_configure_number_for_device(tusb_descriptor_device_t* dev_desc)
-{
-  uint8_t config_num = 1;
-
-  // invoke callback to ask user which configuration to select
-  if (tusbh_device_attached_cb)
-  {
-    config_num = min8_of(1, tusbh_device_attached_cb(dev_desc) );
-  }
-
-  return config_num;
-}
-
-#endif
+/**************************************************************************/
+/*!
+    @file     usbd_host.c
+    @author   hathach (tinyusb.org)
+
+    @section LICENSE
+
+    Software License Agreement (BSD License)
+
+    Copyright (c) 2013, hathach (tinyusb.org)
+    All rights reserved.
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions are met:
+    1. Redistributions of source code must retain the above copyright
+    notice, this list of conditions and the following disclaimer.
+    2. Redistributions in binary form must reproduce the above copyright
+    notice, this list of conditions and the following disclaimer in the
+    documentation and/or other materials provided with the distribution.
+    3. Neither the name of the copyright holders nor the
+    names of its contributors may be used to endorse or promote products
+    derived from this software without specific prior written permission.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
+    EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+    WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
+    DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+    INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION HOWEVER CAUSED AND
+    ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+    INCLUDING NEGLIGENCE OR OTHERWISE ARISING IN ANY WAY OUT OF THE USE OF THIS
+    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+    This file is part of the tinyusb stack.
+*/
+/**************************************************************************/
+
+#include "common/common.h"
+
+#if MODE_HOST_SUPPORTED
+
+#define _TINY_USB_SOURCE_FILE_
+
+//--------------------------------------------------------------------+
+// INCLUDE
+//--------------------------------------------------------------------+
+#include "tusb.h"
+#include "hub.h"
+#include "usbh_hcd.h"
+
+//--------------------------------------------------------------------+
+// MACRO CONSTANT TYPEDEF
+//--------------------------------------------------------------------+
+#define ENUM_QUEUE_DEPTH  5
+
+// TODO fix/compress number of class driver
+static host_class_driver_t const usbh_class_drivers[TUSB_CLASS_MAPPED_INDEX_END] =
+{
+#if HOST_CLASS_HID
+    [TUSB_CLASS_HID] = {
+        .init         = hidh_init,
+        .open_subtask = hidh_open_subtask,
+        .isr          = hidh_isr,
+        .close        = hidh_close
+    },
+#endif
+
+#if TUSB_CFG_HOST_CDC
+    [TUSB_CLASS_CDC] = {
+        .init         = cdch_init,
+        .open_subtask = cdch_open_subtask,
+        .isr          = cdch_isr,
+        .close        = cdch_close
+    },
+#endif
+
+#if TUSB_CFG_HOST_MSC
+    [TUSB_CLASS_MSC] = {
+        .init         = msch_init,
+        .open_subtask = msch_open_subtask,
+        .isr          = msch_isr,
+        .close        = msch_close
+    },
+#endif
+
+#if TUSB_CFG_HOST_HUB
+    [TUSB_CLASS_HUB] = {
+        .init         = hub_init,
+        .open_subtask = hub_open_subtask,
+        .isr          = hub_isr,
+        .close        = hub_close
+    },
+#endif
+
+#if TUSB_CFG_HOST_CUSTOM_CLASS
+    [TUSB_CLASS_MAPPED_INDEX_END-1] = {
+        .init         = cush_init,
+        .open_subtask = cush_open_subtask,
+        .isr          = cush_isr,
+        .close        = cush_close
+    }
+#endif
+};
+
+//--------------------------------------------------------------------+
+// INTERNAL OBJECT & FUNCTION DECLARATION
+//--------------------------------------------------------------------+
+TUSB_CFG_ATTR_USBRAM usbh_device_info_t usbh_devices[TUSB_CFG_HOST_DEVICE_MAX+1]; // including zero-address
+
+//------------- Enumeration Task Data -------------//
+OSAL_TASK_DEF(usbh_enumeration_task, 200, TUSB_CFG_OS_TASK_PRIO);
+OSAL_QUEUE_DEF(enum_queue_def, ENUM_QUEUE_DEPTH, uint32_t);
+
+static osal_queue_handle_t enum_queue_hdl;
+TUSB_CFG_ATTR_USBRAM ATTR_ALIGNED(4) STATIC_VAR uint8_t enum_data_buffer[TUSB_CFG_HOST_ENUM_BUFFER_SIZE];
+
+//------------- Reporter Task Data -------------//
+
+//------------- Helper Function Prototypes -------------//
+static inline uint8_t get_new_address(void) ATTR_ALWAYS_INLINE;
+static inline uint8_t get_configure_number_for_device(tusb_descriptor_device_t* dev_desc) ATTR_ALWAYS_INLINE;
+
+//--------------------------------------------------------------------+
+// PUBLIC API (Parameter Verification is required)
+//--------------------------------------------------------------------+
+tusb_device_state_t tusbh_device_get_state (uint8_t const dev_addr)
+{
+  ASSERT_INT_WITHIN(1, TUSB_CFG_HOST_DEVICE_MAX, dev_addr, TUSB_DEVICE_STATE_INVALID_PARAMETER);
+  return (tusb_device_state_t) usbh_devices[dev_addr].state;
+}
+
+uint32_t tusbh_device_get_mounted_class_flag(uint8_t dev_addr)
+{
+  return tusbh_device_is_configured(dev_addr) ? usbh_devices[dev_addr].flag_supported_class : 0;
+}
+
+//--------------------------------------------------------------------+
+// CLASS-USBD API (don't require to verify parameters)
+//--------------------------------------------------------------------+
+tusb_error_t usbh_init(void)
+{
+  memclr_(usbh_devices, sizeof(usbh_device_info_t)*(TUSB_CFG_HOST_DEVICE_MAX+1));
+
+  ASSERT_STATUS( hcd_init() );
+
+  //------------- Enumeration & Reporter Task init -------------//
+  enum_queue_hdl = osal_queue_create( OSAL_QUEUE_REF(enum_queue_def) );
+  ASSERT_PTR(enum_queue_hdl, TUSB_ERROR_OSAL_QUEUE_FAILED);
+  ASSERT_STATUS( osal_task_create( OSAL_TASK_REF(usbh_enumeration_task) ));
+
+  //------------- Semaphore, Mutex for Control Pipe -------------//
+  for(uint8_t i=0; i<TUSB_CFG_HOST_DEVICE_MAX+1; i++) // including address zero
+  {
+    usbh_device_info_t * const p_device = &usbh_devices[i];
+
+    p_device->control.sem_hdl = osal_semaphore_create( OSAL_SEM_REF(p_device->control.semaphore) );
+    ASSERT_PTR(p_device->control.sem_hdl, TUSB_ERROR_OSAL_SEMAPHORE_FAILED);
+
+    p_device->control.mutex_hdl = osal_mutex_create ( OSAL_MUTEX_REF(p_device->control.mutex) );
+    ASSERT_PTR(p_device->control.mutex_hdl, TUSB_ERROR_OSAL_MUTEX_FAILED);
+  }
+
+  //------------- class init -------------//
+  for (uint8_t class_index = 1; class_index < TUSB_CLASS_MAPPED_INDEX_END; class_index++)
+  {
+    if (usbh_class_drivers[class_index].init)
+    {
+      usbh_class_drivers[class_index].init();
+    }
+  }
+
+  return TUSB_ERROR_NONE;
+}
+
+//------------- USBH control transfer -------------//
+// function called within a task, requesting os blocking services, subtask input parameter must be static/global variables or constant
+tusb_error_t usbh_control_xfer_subtask(uint8_t dev_addr, uint8_t bmRequestType, uint8_t bRequest,
+                                       uint16_t wValue, uint16_t wIndex, uint16_t wLength, uint8_t* data)
+{
+  static tusb_error_t error; // FIXME cmsis-rtx use svc for OS API, error value changed after mutex release at the end of function
+
+  OSAL_SUBTASK_BEGIN
+
+  osal_mutex_wait(usbh_devices[dev_addr].control.mutex_hdl, OSAL_TIMEOUT_NORMAL, &error);
+  SUBTASK_ASSERT_STATUS_WITH_HANDLER(error, osal_mutex_release(usbh_devices[dev_addr].control.mutex_hdl));
+
+  usbh_devices[dev_addr].control.request = (tusb_control_request_t) {
+                                                  {.bmRequestType = bmRequestType},
+                                                  .bRequest      = bRequest,
+                                                  .wValue        = wValue,
+                                                  .wIndex        = wIndex,
+                                                  .wLength       = wLength
+                                           };
+
+#ifndef _TEST_
+  usbh_devices[dev_addr].control.pipe_status = 0;
+#else
+  usbh_devices[dev_addr].control.pipe_status = TUSB_EVENT_XFER_COMPLETE; // in Test project, mark as complete immediately
+#endif
+
+  SUBTASK_ASSERT_STATUS_WITH_HANDLER( hcd_pipe_control_xfer(dev_addr, &usbh_devices[dev_addr].control.request, data),
+                                      osal_mutex_release(usbh_devices[dev_addr].control.mutex_hdl) );
+
+  osal_semaphore_wait(usbh_devices[dev_addr].control.sem_hdl, OSAL_TIMEOUT_NORMAL, &error); // careful of local variable without static
+  osal_mutex_release(usbh_devices[dev_addr].control.mutex_hdl);
+
+  // TODO make handler for this function general purpose
+  if (TUSB_ERROR_NONE != error)   SUBTASK_EXIT(error);
+  if (TUSB_EVENT_XFER_STALLED == usbh_devices[dev_addr].control.pipe_status) SUBTASK_EXIT(TUSB_ERROR_USBH_XFER_STALLED);
+  if (TUSB_EVENT_XFER_ERROR   == usbh_devices[dev_addr].control.pipe_status) SUBTASK_EXIT(TUSB_ERROR_USBH_XFER_FAILED);
+
+//  SUBTASK_ASSERT_WITH_HANDLER(TUSB_ERROR_NONE == error &&
+//                              TUSB_EVENT_XFER_COMPLETE == usbh_devices[dev_addr].control.pipe_status,
+//                              tusbh_device_mount_failed_cb(TUSB_ERROR_USBH_MOUNT_DEVICE_NOT_RESPOND, NULL) );
+
+  OSAL_SUBTASK_END
+}
+
+tusb_error_t usbh_pipe_control_open(uint8_t dev_addr, uint8_t max_packet_size) ATTR_ALWAYS_INLINE;
+tusb_error_t usbh_pipe_control_open(uint8_t dev_addr, uint8_t max_packet_size)
+{
+  osal_semaphore_reset( usbh_devices[dev_addr].control.sem_hdl );
+  osal_mutex_reset( usbh_devices[dev_addr].control.mutex_hdl );
+
+  ASSERT_STATUS( hcd_pipe_control_open(dev_addr, max_packet_size) );
+
+  return TUSB_ERROR_NONE;
+}
+
+static inline tusb_error_t usbh_pipe_control_close(uint8_t dev_addr) ATTR_ALWAYS_INLINE;
+static inline tusb_error_t usbh_pipe_control_close(uint8_t dev_addr)
+{
+  ASSERT_STATUS( hcd_pipe_control_close(dev_addr) );
+
+  return TUSB_ERROR_NONE;
+}
+
+tusb_interface_status_t usbh_pipe_status_get(pipe_handle_t pipe_hdl)
+{
+  return TUSB_INTERFACE_STATUS_BUSY;
+}
+
+//--------------------------------------------------------------------+
+// USBH-HCD ISR/Callback API
+//--------------------------------------------------------------------+
+// interrupt caused by a TD (with IOC=1) in pipe of class class_code
+void usbh_xfer_isr(pipe_handle_t pipe_hdl, uint8_t class_code, tusb_event_t event, uint32_t xferred_bytes)
+{
+  uint8_t class_index = std_class_code_to_index(class_code);
+  if (TUSB_XFER_CONTROL == pipe_hdl.xfer_type)
+  {
+    usbh_devices[ pipe_hdl.dev_addr ].control.pipe_status   = event;
+//    usbh_devices[ pipe_hdl.dev_addr ].control.xferred_bytes = xferred_bytes; not yet neccessary
+    osal_semaphore_post( usbh_devices[ pipe_hdl.dev_addr ].control.sem_hdl );
+  }else if (usbh_class_drivers[class_index].isr)
+  {
+    usbh_class_drivers[class_index].isr(pipe_hdl, event, xferred_bytes);
+  }else
+  {
+    ASSERT(false, VOID_RETURN); // something wrong, no one claims the isr's source
+  }
+}
+
+void usbh_hub_port_plugged_isr(uint8_t hub_addr, uint8_t hub_port)
+{
+  osal_queue_send(enum_queue_hdl,
+                  &(usbh_enumerate_t){
+                    .core_id  = usbh_devices[hub_addr].core_id,
+                    .hub_addr = hub_addr,
+                    .hub_port = hub_port}
+                  );
+}
+
+void usbh_hcd_rhport_plugged_isr(uint8_t hostid)
+{
+  osal_queue_send(enum_queue_hdl,
+                  &(usbh_enumerate_t){
+                    .core_id  = hostid,
+                    .hub_addr = 0,
+                    .hub_port = 0}
+                  );
+}
+
+// a device unplugged on hostid, hub_addr, hub_port
+// return true if found and unmounted device, false if cannot find
+static void usbh_device_unplugged(uint8_t hostid, uint8_t hub_addr, uint8_t hub_port)
+{
+  bool is_found = false;
+  //------------- find the all devices (star-network) under port that is unplugged -------------//
+  for (uint8_t dev_addr = 0; dev_addr <= TUSB_CFG_HOST_DEVICE_MAX; dev_addr ++)
+  {
+    if (usbh_devices[dev_addr].core_id  == hostid   &&
+        (hub_addr == 0 || usbh_devices[dev_addr].hub_addr == hub_addr) && // hub_addr == 0 & hub_port == 0 means roothub
+        (hub_port == 0 || usbh_devices[dev_addr].hub_port == hub_port) &&
+        usbh_devices[dev_addr].state    != TUSB_DEVICE_STATE_UNPLUG)
+    {
+      // TODO Hub multiple level
+      for (uint8_t class_index = 1; class_index < TUSB_CLASS_MAPPED_INDEX_END; class_index++)
+      {
+        if ((usbh_devices[dev_addr].flag_supported_class & BIT_(class_index)) &&
+            usbh_class_drivers[class_index].close)
+        {
+          usbh_class_drivers[class_index].close(dev_addr);
+        }
+      }
+
+      // TODO refractor
+      // set to REMOVING to allow HCD to clean up its cached data for this device
+      // HCD must set this device's state to TUSB_DEVICE_STATE_UNPLUG when done
+      usbh_devices[dev_addr].state = TUSB_DEVICE_STATE_REMOVING;
+      usbh_devices[dev_addr].flag_supported_class = 0;
+
+      usbh_pipe_control_close(dev_addr);
+
+
+      is_found = true;
+    }
+  }
+
+  if (is_found) hcd_port_unplug(usbh_devices[0].core_id); // TODO hack
+
+}
+
+void usbh_hcd_rhport_unplugged_isr(uint8_t hostid)
+{
+  osal_queue_send(enum_queue_hdl,
+                  &(usbh_enumerate_t)
+                  {
+                    .core_id = hostid,
+                    .hub_addr = 0,
+                    .hub_port = 0
+                  } );
+}
+
+//--------------------------------------------------------------------+
+// ENUMERATION TASK
+//--------------------------------------------------------------------+
+static tusb_error_t enumeration_body_subtask(void);
+
+// To enable the TASK_ASSERT style (quick return on false condition) in a real RTOS, a task must act as a wrapper
+// and is used mainly to call subtasks. Within a subtask return statement can be called freely, the task with
+// forever loop cannot have any return at all.
+OSAL_TASK_FUNCTION(usbh_enumeration_task) (void* p_task_para)
+{
+  OSAL_TASK_LOOP_BEGIN
+
+  enumeration_body_subtask();
+
+  OSAL_TASK_LOOP_END
+}
+
+tusb_error_t enumeration_body_subtask(void)
+{
+  enum {
+    POWER_STABLE_DELAY = 300,
+    RESET_DELAY = 100 // NXP's EHCI require more than 50ms to work properly although the USB specs say only 50ms
+  };
+
+  tusb_error_t error;
+  usbh_enumerate_t enum_entry;
+
+  // for OSAL_NONE local variable won't retain value after blocking service sem_wait/queue_recv
+  static uint8_t new_addr;
+  static uint8_t configure_selected = 1; // TODO move
+  static uint8_t *p_desc = NULL; // TODO move
+
+  OSAL_SUBTASK_BEGIN
+
+  osal_queue_receive(enum_queue_hdl, &enum_entry, OSAL_TIMEOUT_WAIT_FOREVER, &error);
+  SUBTASK_ASSERT_STATUS(error);
+
+  usbh_devices[0].core_id  = enum_entry.core_id; // TODO refractor integrate to device_pool
+  usbh_devices[0].hub_addr = enum_entry.hub_addr;
+  usbh_devices[0].hub_port = enum_entry.hub_port;
+  usbh_devices[0].state    = TUSB_DEVICE_STATE_UNPLUG;
+
+  //------------- connected/disconnected directly with roothub -------------//
+  if ( usbh_devices[0].hub_addr == 0)
+  {
+    if( hcd_port_connect_status(usbh_devices[0].core_id) )
+    { // connection event
+      osal_task_delay(POWER_STABLE_DELAY); // wait until device is stable. Increase this if the first 8 bytes is failed to get
+
+      if ( !hcd_port_connect_status(usbh_devices[0].core_id) ) SUBTASK_EXIT(TUSB_ERROR_NONE); // exit if device unplugged while delaying
+
+      hcd_port_reset( usbh_devices[0].core_id ); // port must be reset to have correct speed operation
+      osal_task_delay(RESET_DELAY);
+
+      usbh_devices[0].speed = hcd_port_speed_get( usbh_devices[0].core_id );
+    }
+    else
+    { // disconnection event
+      usbh_device_unplugged(usbh_devices[0].core_id, 0, 0);
+      SUBTASK_EXIT(TUSB_ERROR_NONE); // restart task
+    }
+  }
+  #if TUSB_CFG_HOST_HUB
+  //------------- connected/disconnected via hub -------------//
+  else
+  {
+    //------------- Get Port Status -------------//
+    OSAL_SUBTASK_INVOKED_AND_WAIT(
+        usbh_control_xfer_subtask( usbh_devices[0].hub_addr, bm_request_type(TUSB_DIR_DEV_TO_HOST, TUSB_REQUEST_TYPE_CLASS, TUSB_REQUEST_RECIPIENT_OTHER),
+                                   HUB_REQUEST_GET_STATUS, 0, usbh_devices[0].hub_port,
+                                   4, enum_data_buffer ),
+        error
+    );
+//    SUBTASK_ASSERT_STATUS( error );
+    SUBTASK_ASSERT_STATUS_WITH_HANDLER(error, hub_status_pipe_queue( usbh_devices[0].hub_addr) ); // TODO hub refractor
+
+    // Acknowledge Port Connection Change
+    OSAL_SUBTASK_INVOKED_AND_WAIT( hub_port_clear_feature_subtask(usbh_devices[0].hub_addr, usbh_devices[0].hub_port, HUB_FEATURE_PORT_CONNECTION_CHANGE), error );
+
+    if ( ! ((hub_port_status_response_t *) enum_data_buffer)->status_change.connect_status )   SUBTASK_EXIT(TUSB_ERROR_NONE); // only handle connection change
+
+    if ( ! ((hub_port_status_response_t *) enum_data_buffer)->status_current.connect_status )
+    { // Disconnection event
+      usbh_device_unplugged(usbh_devices[0].core_id, usbh_devices[0].hub_addr, usbh_devices[0].hub_port);
+
+      (void) hub_status_pipe_queue( usbh_devices[0].hub_addr ); // done with hub, waiting for next data on status pipe
+      SUBTASK_EXIT(TUSB_ERROR_NONE); // restart task
+    }
+    else
+    { // Connection Event
+      OSAL_SUBTASK_INVOKED_AND_WAIT ( hub_port_reset_subtask(usbh_devices[0].hub_addr, usbh_devices[0].hub_port), error );
+//      SUBTASK_ASSERT_STATUS( error );
+      SUBTASK_ASSERT_STATUS_WITH_HANDLER(error, hub_status_pipe_queue( usbh_devices[0].hub_addr) ); // TODO hub refractor
+
+      usbh_devices[0].speed = hub_port_get_speed();
+
+      // Acknowledge Port Reset Change
+      OSAL_SUBTASK_INVOKED_AND_WAIT( hub_port_clear_feature_subtask(usbh_devices[0].hub_addr, usbh_devices[0].hub_port, HUB_FEATURE_PORT_RESET_CHANGE), error );
+    }
+  }
+  #endif
+
+  SUBTASK_ASSERT_STATUS( usbh_pipe_control_open(0, 8) );
+  usbh_devices[0].state = TUSB_DEVICE_STATE_ADDRESSED;
+
+  //------------- Get first 8 bytes of device descriptor to get Control Endpoint Size -------------//
+  OSAL_SUBTASK_INVOKED_AND_WAIT(
+      usbh_control_xfer_subtask( 0, bm_request_type(TUSB_DIR_DEV_TO_HOST, TUSB_REQUEST_TYPE_STANDARD, TUSB_REQUEST_RECIPIENT_DEVICE),
+                                 TUSB_REQUEST_GET_DESCRIPTOR, (TUSB_DESC_TYPE_DEVICE << 8), 0,
+                                 8, enum_data_buffer ),
+      error
+  );
+
+  //------------- Reset device again before Set Address -------------//
+  if (usbh_devices[0].hub_addr == 0)
+  { // connected directly to roothub
+    SUBTASK_ASSERT_STATUS(error); // TODO some slow device is observed to fail the very fist controller xfer, can try more times
+    hcd_port_reset( usbh_devices[0].core_id ); // reset port after 8 byte descriptor
+    osal_task_delay(RESET_DELAY);
+  }
+  #if TUSB_CFG_HOST_HUB
+  else
+  { // connected via a hub
+    SUBTASK_ASSERT_STATUS_WITH_HANDLER(error, hub_status_pipe_queue( usbh_devices[0].hub_addr) ); // TODO hub refractor
+    OSAL_SUBTASK_INVOKED_AND_WAIT ( hub_port_reset_subtask(usbh_devices[0].hub_addr, usbh_devices[0].hub_port), error );
+
+    if ( TUSB_ERROR_NONE == error )
+    { // Acknowledge Port Reset Change if Reset Successful
+      OSAL_SUBTASK_INVOKED_AND_WAIT( hub_port_clear_feature_subtask(usbh_devices[0].hub_addr, usbh_devices[0].hub_port, HUB_FEATURE_PORT_RESET_CHANGE), error );
+    }
+
+    (void) hub_status_pipe_queue( usbh_devices[0].hub_addr ); // done with hub, waiting for next data on status pipe
+  }
+  #endif
+
+  //------------- Set new address -------------//
+  new_addr = get_new_address();
+  SUBTASK_ASSERT(new_addr <= TUSB_CFG_HOST_DEVICE_MAX); // TODO notify application we reach max devices
+
+  OSAL_SUBTASK_INVOKED_AND_WAIT(
+    usbh_control_xfer_subtask( 0, bm_request_type(TUSB_DIR_HOST_TO_DEV, TUSB_REQUEST_TYPE_STANDARD, TUSB_REQUEST_RECIPIENT_DEVICE),
+                               TUSB_REQUEST_SET_ADDRESS, new_addr, 0,
+                               0, NULL ),
+    error
+  );
+  SUBTASK_ASSERT_STATUS(error);
+
+  //------------- update port info & close control pipe of addr0 -------------//
+  usbh_devices[new_addr].core_id  = usbh_devices[0].core_id;
+  usbh_devices[new_addr].hub_addr = usbh_devices[0].hub_addr;
+  usbh_devices[new_addr].hub_port = usbh_devices[0].hub_port;
+  usbh_devices[new_addr].speed    = usbh_devices[0].speed;
+  usbh_devices[new_addr].state    = TUSB_DEVICE_STATE_ADDRESSED;
+
+  usbh_pipe_control_close(0);
+  usbh_devices[0].state = TUSB_DEVICE_STATE_UNPLUG;
+
+  // open control pipe for new address
+  SUBTASK_ASSERT_STATUS ( usbh_pipe_control_open(new_addr, ((tusb_descriptor_device_t*) enum_data_buffer)->bMaxPacketSize0 ) );
+
+  //------------- Get full device descriptor -------------//
+  OSAL_SUBTASK_INVOKED_AND_WAIT(
+      usbh_control_xfer_subtask( new_addr, bm_request_type(TUSB_DIR_DEV_TO_HOST, TUSB_REQUEST_TYPE_STANDARD, TUSB_REQUEST_RECIPIENT_DEVICE),
+                                 TUSB_REQUEST_GET_DESCRIPTOR, (TUSB_DESC_TYPE_DEVICE << 8), 0,
+                                 18, enum_data_buffer ),
+      error
+  );
+  SUBTASK_ASSERT_STATUS(error);
+
+  // update device info  TODO alignment issue
+  usbh_devices[new_addr].vendor_id       = ((tusb_descriptor_device_t*) enum_data_buffer)->idVendor;
+  usbh_devices[new_addr].product_id      = ((tusb_descriptor_device_t*) enum_data_buffer)->idProduct;
+  usbh_devices[new_addr].configure_count = ((tusb_descriptor_device_t*) enum_data_buffer)->bNumConfigurations;
+
+  configure_selected = get_configure_number_for_device((tusb_descriptor_device_t*) enum_data_buffer);
+  SUBTASK_ASSERT(configure_selected <= usbh_devices[new_addr].configure_count); // TODO notify application when invalid configuration
+
+  //------------- Get 9 bytes of configuration descriptor -------------//
+  OSAL_SUBTASK_INVOKED_AND_WAIT(
+      usbh_control_xfer_subtask( new_addr, bm_request_type(TUSB_DIR_DEV_TO_HOST, TUSB_REQUEST_TYPE_STANDARD, TUSB_REQUEST_RECIPIENT_DEVICE),
+                                 TUSB_REQUEST_GET_DESCRIPTOR, (TUSB_DESC_TYPE_CONFIGURATION << 8) | (configure_selected - 1), 0,
+                                 9, enum_data_buffer ),
+      error
+  );
+  SUBTASK_ASSERT_STATUS(error);
+  SUBTASK_ASSERT_WITH_HANDLER( TUSB_CFG_HOST_ENUM_BUFFER_SIZE >= ((tusb_descriptor_configuration_t*)enum_data_buffer)->wTotalLength,
+                            tusbh_device_mount_failed_cb(TUSB_ERROR_USBH_MOUNT_CONFIG_DESC_TOO_LONG, NULL) );
+
+  //------------- Get full configuration descriptor -------------//
+  OSAL_SUBTASK_INVOKED_AND_WAIT(
+      usbh_control_xfer_subtask( new_addr, bm_request_type(TUSB_DIR_DEV_TO_HOST, TUSB_REQUEST_TYPE_STANDARD, TUSB_REQUEST_RECIPIENT_DEVICE),
+                                 TUSB_REQUEST_GET_DESCRIPTOR, (TUSB_DESC_TYPE_CONFIGURATION << 8) | (configure_selected - 1), 0,
+                                 TUSB_CFG_HOST_ENUM_BUFFER_SIZE, enum_data_buffer ),
+      error
+  );
+  SUBTASK_ASSERT_STATUS(error);
+
+  // update configuration info
+  usbh_devices[new_addr].interface_count = ((tusb_descriptor_configuration_t*) enum_data_buffer)->bNumInterfaces;
+
+  //------------- Set Configure -------------//
+  OSAL_SUBTASK_INVOKED_AND_WAIT(
+    usbh_control_xfer_subtask( new_addr, bm_request_type(TUSB_DIR_HOST_TO_DEV, TUSB_REQUEST_TYPE_STANDARD, TUSB_REQUEST_RECIPIENT_DEVICE),
+                               TUSB_REQUEST_SET_CONFIGURATION, configure_selected, 0,
+                               0, NULL ),
+    error
+  );
+  SUBTASK_ASSERT_STATUS(error);
+
+  usbh_devices[new_addr].state = TUSB_DEVICE_STATE_CONFIGURED;
+
+  //------------- TODO Get String Descriptors -------------//
+
+  //------------- parse configuration & install drivers -------------//
+  p_desc = enum_data_buffer + sizeof(tusb_descriptor_configuration_t);
+
+  // parse each interfaces
+  while( p_desc < enum_data_buffer + ((tusb_descriptor_configuration_t*)enum_data_buffer)->wTotalLength )
+  {
+    // skip until we see interface descriptor
+    if ( TUSB_DESC_TYPE_INTERFACE != p_desc[DESCRIPTOR_OFFSET_TYPE] )
+    {
+      p_desc += p_desc[DESCRIPTOR_OFFSET_LENGTH]; // skip the descriptor, increase by the descriptor's length
+    }else
+    {
+      static uint8_t class_index; // has to be static as it is used to call class's open_subtask
+
+      class_index = std_class_code_to_index( ((tusb_descriptor_interface_t*) p_desc)->bInterfaceClass );
+      SUBTASK_ASSERT( class_index != 0 ); // class_index == 0 means corrupted data, abort enumeration
+
+      if (usbh_class_drivers[class_index].open_subtask &&
+          !(class_index == TUSB_CLASS_HUB && usbh_devices[new_addr].hub_addr != 0))
+      { // supported class, TODO Hub disable multiple level
+        static uint16_t length;
+        length = 0;
+
+        OSAL_SUBTASK_INVOKED_AND_WAIT ( // parameters in task/sub_task must be static storage (static or global)
+            usbh_class_drivers[class_index].open_subtask( new_addr, (tusb_descriptor_interface_t*) p_desc, &length ),
+            error
+        );
+
+        if (error == TUSB_ERROR_NONE)
+        {
+          SUBTASK_ASSERT( length >= sizeof(tusb_descriptor_interface_t) );
+          usbh_devices[new_addr].flag_supported_class |= BIT_(class_index);
+          p_desc += length;
+        }else  // Interface open failed, for example a subclass is not supported
+        {
+          p_desc += p_desc[DESCRIPTOR_OFFSET_LENGTH]; // skip this interface, the rest will be skipped by the above loop
+        }
+      } else // unsupported class (not enable or yet implemented)
+      {
+        p_desc += p_desc[DESCRIPTOR_OFFSET_LENGTH]; // skip this interface, the rest will be skipped by the above loop
+      }
+    }
+  }
+
+  tusbh_device_mount_succeed_cb(new_addr);
+
+  OSAL_SUBTASK_END
+}
+
+//--------------------------------------------------------------------+
+// REPORTER TASK & ITS DATA
+//--------------------------------------------------------------------+
+
+
+
+
+
+//--------------------------------------------------------------------+
+// INTERNAL HELPER
+//--------------------------------------------------------------------+
+static inline uint8_t get_new_address(void)
+{
+  uint8_t addr;
+  for (addr=1; addr <= TUSB_CFG_HOST_DEVICE_MAX; addr++)
+  {
+    if (usbh_devices[addr].state == TUSB_DEVICE_STATE_UNPLUG)
+      break;
+  }
+  return addr;
+}
+
+static inline uint8_t get_configure_number_for_device(tusb_descriptor_device_t* dev_desc)
+{
+  uint8_t config_num = 1;
+
+  // invoke callback to ask user which configuration to select
+  if (tusbh_device_attached_cb)
+  {
+    config_num = min8_of(1, tusbh_device_attached_cb(dev_desc) );
+  }
+
+  return config_num;
+}
+
+#endif